/* ===========================================================================
   EASYDESK — FEUILLE DE MODULE (.dsk-*)

   POURQUOI UNE FEUILLE DE MODULE ET NON UNE FEUILLE PAR ÉCRAN
     La règle du dépôt est « un écran, une feuille » (CLAUDE.md), avec son
     exception écrite : « une classe employée par deux écrans ou plus remonte ».
     Le portage d'EasyDesk au gabarit (2026-09-08) a fait passer seize écrans du
     balisage Bootstrap (.md-card, .row g-3, .progress, .badge bg-*, .alert) à la
     trame .mx-*, et ce qui restait à écrire après ce passage était, à chaque
     fois, LE MÊME PEU : la disposition « liste à gauche, éditeur à droite » que
     six écrans du module emploient, le fil d'échanges du ticket, la colonne de
     durées alignée à droite, la rangée en retard. Seize feuilles d'écran
     auraient été seize copies de ces quatre-vingts lignes, et elles auraient
     divergé comme .apv-* et .cso-* l'ont fait avant elles.

     Le précédent est easypaie.css, puis easyconso.css, puis easysales.css : une
     feuille par module, préfixe propre, ses propres paliers responsive. C'est le
     cinquième cas du dépôt et il est traité comme les quatre autres.

   CE QUI N'EST PAS ICI, ET N'A PAS À Y ÊTRE
     Tout ce que le gabarit porte déjà. La trame de page, les boutons, la carte,
     la bande d'indicateurs, les barres de répartition, les pastilles d'état, la
     grille de champs dense, le bloc d'alerte, le groupe segmenté, la modale, la
     table : ce sont .mx-* et rien d'autre. Une classe .dsk- qui redirait l'une
     d'elles serait une divergence en attente.

   AUCUNE COULEUR LITTÉRALE. Tout passe par les jetons --et-* de
   easytech-theme.css — thème sombre compris, sans une ligne de plus. Aucune
   couleur d'état n'est écrite en `color:` : c'est le rang -ink qui sert d'encre,
   la teinte pleine ne servant que de fond, de bordure ou de marque.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1. ALIGNEMENT DES CELLULES

   .mx-tbl th force text-align:left (0,1,1 en spécificité). Un simple
   .dsk-droite (0,1,0) ne le battrait pas : d'où la portée par .mx-tbl, qui monte
   à 0,2,0. La forme nue reste définie pour les rares emplois hors table.
   --------------------------------------------------------------------------- */
.dsk-droite { text-align: right; }
.dsk-centre { text-align: center; }
.mx-tbl .dsk-droite { text-align: right; }
.mx-tbl .dsk-centre { text-align: center; }

/* ---------------------------------------------------------------------------
   2. UNE DURÉE, UN DÉCOMPTE, UNE ÉCHÉANCE

   Le module ne compte pas des montants mais du TEMPS : « 2 h 30 », « dans 45
   min », « en retard de 3 j ». La chasse fixe leur donne la même largeur de
   chiffre, si bien que deux échéances posées l'une sous l'autre se comparent en
   balayant la colonne au lieu de se lire une à une. Le gabarit pose déjà la mono
   sur .mx-tbl-mono ; ce qui manquait était l'encre du RETARD.

   ELLE N'EST PAS --et-danger. Mesuré : --et-danger rend 4,83:1 sur blanc mais
   4,13:1 sur --et-rang, le fond d'une rangée SURVOLÉE — c'est-à-dire au moment
   précis où l'on pose le curseur dessus pour la lire. L'encre du rang, elle,
   tient sur les trois fonds (surface, rangée survolée, rangée retenue).
   --------------------------------------------------------------------------- */
.dsk-retard { color: var(--et-danger-ink); font-weight: 600; }
.dsk-proche { color: var(--et-avertissement-ink); font-weight: 600; }
.dsk-tenu   { color: var(--et-succes-ink); }

/* ---------------------------------------------------------------------------
   3. RANGÉE EN RETARD — le pendant `danger` de .mx-tbl tr.est-alerte

   Le gabarit n'a que l'ambre (est-terne, est-alerte). EasyDesk a besoin du cran
   au-dessus : une échéance de résolution DÉPASSÉE n'est pas « à surveiller »,
   elle est manquée. Même forme exactement — aplat pâle plus liseré à gauche —
   pour que les deux se lisent comme deux degrés d'une même chose.

   LE LISERÉ N'EST PAS DÉCORATIF : en thème sombre l'aplat rouge pâle descend à
   quelques pour cent du fond, et c'est lui qui reste.
   --------------------------------------------------------------------------- */
.mx-tbl tbody tr.dsk-rang-retard td { background: var(--et-danger-badge-bg); }
.mx-tbl tbody tr.dsk-rang-retard td:first-child { box-shadow: inset 3px 0 0 var(--et-danger); }

/* ---------------------------------------------------------------------------
   4. LA DISPOSITION « LISTE + ÉDITEUR »

   Six écrans du module la portent — Escalade, Contrats, Parc, Interventions,
   Temps, Base de connaissances : on choisit une ligne à gauche, on la modifie à
   droite, sans quitter la liste ni ouvrir de fenêtre. C'était un `.row g-3` avec
   `col-lg-7 / col-lg-5` recopié six fois ; c'est ici une grille, une fois.

   380 px À DROITE, ET NON UNE FRACTION. Le panneau porte la grille de champs
   dense du gabarit — colonne d'intitulés de 158 px alignée à droite — plus le
   champ lui-même : sous 360 px le champ tombe à moins de 180 px et une date n'y
   tient plus. Une colonne en `fr` aurait rétréci sous la pression de la table.

   SOUS 1100 px l'éditeur passe SOUS la liste. Côte à côte, il ne resterait pas
   300 px utiles au tableau — c'est le même palier, et pour la même raison, que
   .ecran-filtre de la coquille.
   --------------------------------------------------------------------------- */
.dsk-duo {
    display: grid; grid-template-columns: minmax(0, 1fr) 380px;
    gap: 16px; align-items: start;
}
.dsk-duo > * { min-width: 0; }

/* La variante de la FICHE : la colonne de contexte est plus large (elle porte le
   client, le SLA, l'affectation) et se colle en haut pendant que le fil défile. */
.dsk-fiche {
    display: grid; grid-template-columns: minmax(0, 1fr) 320px;
    gap: 16px; align-items: start;
}
.dsk-fiche > * { min-width: 0; }
/* `position: sticky` sur le flanc : le fil d'un ticket ancien fait plusieurs
   écrans de haut, et l'affectation ne doit pas s'échapper vers le haut avec lui.
   Le décalage est celui de l'en-tête fixe de la coquille (lot08). */
.dsk-flanc { position: sticky; top: 12px; display: flex; flex-direction: column; gap: 16px; }

@media (max-width: 1100px) {
    .dsk-duo, .dsk-fiche { grid-template-columns: minmax(0, 1fr); }
    /* Empilé, l'ancrage n'a plus de sens : le flanc est un bloc comme un autre. */
    .dsk-flanc { position: static; }
}

/* ---------------------------------------------------------------------------
   5. LE FIL D'ÉCHANGES DU TICKET

   C'est le seul objet vraiment propre au module : une suite de messages dont
   certains sont PUBLICS (le client les lit) et d'autres INTERNES (il ne les lit
   pas). La distinction est la plus lourde de conséquences de tout l'écran — une
   note interne écrite en croyant répondre au client, ou l'inverse, ne se rattrape
   pas — et elle doit donc se voir sans être lue.

   ELLE SE VOIT PAR LA BORDURE, PAS PAR L'APLAT. Un aplat ambre sous du texte
   ordinaire descend à 2,02:1 pour l'ambre et lit « anomalie » là où il n'y en a
   pas ; une note interne est un geste normal. Le message interne porte donc un
   liseré ambre à gauche — un MARQUE, au rang --et-avertissement-mark qui tient
   le seuil graphique de 3:1 — et un jeton qui le nomme. Le message public reste
   sur la surface de la page.
   --------------------------------------------------------------------------- */
.dsk-fil { display: flex; flex-direction: column; gap: 10px; }
.dsk-msg {
    border: 1px solid var(--et-hairline); border-left: 3px solid var(--et-hairline);
    background: var(--et-surface-2); padding: 9px 12px;
}
.dsk-msg.est-interne { border-left-color: var(--et-avertissement-mark); }
.dsk-msg.est-client  { border-left-color: var(--et-form-blue); }
.dsk-msg-tete {
    display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
    font-size: 12px; color: var(--et-muted); margin-bottom: 5px;
}
.dsk-msg-auteur { font-weight: 700; color: var(--et-ink); font-size: 13px; }
.dsk-msg-quand { margin-left: auto; font-family: var(--et-font-mono); }
/* `pre-wrap` : le corps d'un message porte les retours à la ligne de celui qui
   l'a écrit. Les replier ferait d'une liste de manipulations un paragraphe. */
.dsk-msg-corps { white-space: pre-wrap; font-size: 13px; line-height: 1.55; color: var(--et-ink); }

/* Jeton de nature du message. Ce n'est pas une pastille d'état : « interne » ne
   dit pas comment va le ticket, il dit qui peut lire la ligne. */
.dsk-jeton {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 1px 6px; font-size: 11px; font-weight: 600; line-height: 1.5;
    border: 1px solid var(--et-hairline); background: var(--et-surface); color: var(--et-muted);
}
.dsk-jeton.est-interne {
    border-color: var(--et-avertissement-bord); color: var(--et-avertissement-ink);
    background: var(--et-avertissement-bg);
}

/* ---------------------------------------------------------------------------
   6. LA GRILLE DE FICHES DE LECTURE (portail, canaux)

   Deux écrans présentent des objets à PARCOURIR plutôt qu'à comparer ligne à
   ligne : les articles publiés tels que le client les voit, et l'état des canaux
   d'entrée. Une table y répondrait mal — on y cherche un titre, pas une valeur
   dans une colonne.

   `auto-fill` et non `auto-fit` : avec deux articles, `auto-fit` étire deux
   cartes sur toute la largeur et le titre se perd au milieu d'un blanc de
   600 px. `auto-fill` garde la mesure de la carte et laisse le vide à droite,
   ce qui se lit comme « il n'y en a que deux ».
   --------------------------------------------------------------------------- */
.dsk-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); gap: 12px; }
.dsk-tuile {
    display: flex; flex-direction: column; gap: 6px; min-height: 116px;
    border: 1px solid var(--et-hairline); background: var(--et-surface); padding: 12px 14px;
}
/* Une tuile qui MÈNE quelque part le dit au survol. Celle qui ne mène nulle part
   (l'état d'un canal) ne prend pas cette classe : un survol qui réagit sans que
   le clic fasse quoi que ce soit est une promesse non tenue. */
.dsk-tuile.est-ouvrable { cursor: pointer; }
.dsk-tuile.est-ouvrable:hover { border-color: var(--et-form-blue); background: var(--et-rang); }
.dsk-tuile-sur { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--et-faint); }
.dsk-tuile-titre { font-size: 14px; font-weight: 700; color: var(--et-ink); line-height: 1.35; }
.dsk-tuile-txt { font-size: 12px; color: var(--et-muted); line-height: 1.5; }
.dsk-tuile-pied {
    margin-top: auto; padding-top: 8px; display: flex; align-items: baseline; gap: 10px;
    font-size: 12px; color: var(--et-faint); border-top: 1px solid var(--et-hairline);
}
.dsk-tuile-pied .compte { margin-left: auto; font-family: var(--et-font-mono); font-weight: 600; color: var(--et-ink); }

/* ---------------------------------------------------------------------------
   7. LA NOTE DE SATISFACTION

   Cinq étoiles, en saisie sur la fiche et en lecture au reporting. L'étoile est
   un BOUTON quand on note et un caractère quand on lit — deux formes, un seul
   dessin, pour que la note lue et la note saisie soient reconnaissables l'une
   dans l'autre.

   L'AMBRE EST ICI UNE MARQUE, PAS UNE ENCRE : une étoile est un glyphe plein de
   24 px, au-dessus du pas « grand texte » de la charte, et --et-avertissement y
   tient le seuil. L'étoile vide prend le gris inerte — elle dit « pas encore »,
   pas « mauvais ».
   --------------------------------------------------------------------------- */
.dsk-etoiles { display: inline-flex; align-items: center; gap: 2px; font-size: 24px; line-height: 1; }
.dsk-etoile {
    border: 0; background: none; padding: 0 1px; cursor: pointer; line-height: 1;
    font-size: inherit; color: var(--et-inerte);
}
.dsk-etoile.est-pleine { color: var(--et-avertissement); }
.dsk-etoile:disabled { cursor: default; }
.dsk-etoile:focus-visible { outline: 2px solid var(--et-form-blue); outline-offset: 2px; }
/* La note elle-même, en gros. Elle ne prend PAS de couleur d'état : « 3,8/5 »
   n'est ni un succès ni une alerte tant que la société n'a pas dit quelle est sa
   cible, et la teindre en rouge sous 3 inventerait cette cible. */
.dsk-note { font-family: var(--et-font-mono); font-size: 34px; font-weight: 700; color: var(--et-ink); line-height: 1.1; }
.dsk-note-sur { font-size: 14px; font-weight: 400; color: var(--et-faint); }

/* Le verbatim : ce que le client a ÉCRIT, qui vaut plus que la note qu'il a
   cochée. Il se lit comme une citation, pas comme une cellule. */
.dsk-verbatim { border-left: 3px solid var(--et-hairline); padding: 2px 0 2px 10px; }
.dsk-verbatim-txt { font-size: 13px; line-height: 1.5; color: var(--et-ink); white-space: pre-wrap; }
.dsk-verbatim-sig { margin-top: 3px; font-size: 12px; color: var(--et-faint); }

/* ---------------------------------------------------------------------------
   8. DEUX CARTES CÔTE À CÔTE

   Le tableau de bord et le reporting posent des paires de cartes de même rang.
   `.mx-ind-grille` du gabarit sert les INDICATEURS (une valeur par case), pas
   deux panneaux de contenu.
   --------------------------------------------------------------------------- */
.dsk-paire { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; align-items: start; }
/* Variante 5/7 : la répartition à gauche est courte, la file à droite est la
   raison d'être de l'écran. À parts égales, la file perdrait 200 px pour rien. */
.dsk-paire-57 { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 16px; align-items: start; }
@media (max-width: 1100px) { .dsk-paire-57 { grid-template-columns: minmax(0, 1fr); } }

/* Espacement vertical entre deux blocs de premier niveau. Le gabarit ne le pose
   pas : il ignore combien de blocs un écran empile. */
.dsk-espace { margin-bottom: 16px; }

/* UN INDICATEUR QUI MÈNE À SES LIGNES.
   .mx-ind est écrit pour un <div> : porté par un <a>, il resterait en ligne (son
   padding ne pousserait rien) et prendrait le soulignement et le bleu du lien —
   ce qui, sur une case déjà teintée par est-negatif, se lirait comme deux
   signaux contradictoires. Trois déclarations rendent le <a> à sa case, et le
   survol dit qu'elle mène quelque part sans changer sa teinte d'état. */
a.dsk-ind-lien { display: block; text-decoration: none; color: inherit; }
a.dsk-ind-lien:hover { border-color: var(--et-form-blue); }
a.dsk-ind-lien:hover .mx-ind-lbl { color: var(--et-form-blue-d); }
a.dsk-ind-lien:focus-visible { outline: 2px solid var(--et-form-blue); outline-offset: 1px; }

/* UN INDICATEUR QUI FILTRE LA LISTE SOUS LUI. Même case, mais elle n'emmène nulle
   part : elle retient. C'est un <button>, donc il faut lui reprendre ce que
   l'agent utilisateur pose dessus (fond, bordure, alignement, police) sans quoi
   la teinte d'état de .mx-ind serait recouverte par le gris des boutons.

   L'ÉTAT RETENU SE DIT PAR LE FILET, pas par un aplat : la case porte déjà une
   teinte d'état, et un second fond par-dessus rendrait « dépassés, retenus »
   illisible. Le filet bleu est le même signal que sur .mx-puce.est-actif. */
button.dsk-ind-btn {
    display: block; width: 100%; text-align: left; font: inherit; color: inherit;
    cursor: pointer;
}
button.dsk-ind-btn:hover { border-color: var(--et-form-blue); }
button.dsk-ind-btn.est-retenu {
    border-color: var(--et-form-blue); box-shadow: inset 0 0 0 1px var(--et-form-blue);
}
button.dsk-ind-btn:focus-visible { outline: 2px solid var(--et-form-blue); outline-offset: 1px; }

/* ---------------------------------------------------------------------------
   9. LA BARRE DE FILTRES D'UN ÉCRAN

   Rangée de puces, de listes et d'un champ de recherche, posée au-dessus de la
   liste. Les composants sont ceux du gabarit (.mx-puce, .mx-select, .mx-input) ;
   ce qui manquait était la rangée qui les tient, et le fait qu'elle s'enroule
   proprement sur écran étroit plutôt que de pousser la recherche hors du cadre.
   --------------------------------------------------------------------------- */
.dsk-filtres {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 10px 14px; border-bottom: 1px solid var(--et-hairline);
}
.dsk-filtres + .dsk-filtres { border-top: 0; }
.dsk-filtres-lbl {
    font-size: 12px; font-weight: 700; color: var(--et-muted);
    text-transform: uppercase; letter-spacing: .04em; margin-right: 2px;
}
/* Poussé à droite : la recherche est le dernier élément de la rangée sur tous
   les écrans du module, ce qui en fait un repère plutôt qu'un champ à chercher. */
.dsk-filtres-fin { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dsk-recherche { width: 232px; max-width: 100%; }

/* Compteur porté par une puce de vue : « Non affectés · 7 ». Il ne prend pas la
   forme d'une pastille d'état — c'est un décompte, pas un état. */
.dsk-puce-n {
    margin-left: 5px; padding: 0 4px; min-width: 17px; display: inline-block; text-align: center;
    font-family: var(--et-font-mono); font-size: 11px; font-weight: 600;
    background: var(--et-surface-2); color: var(--et-muted); border: 1px solid var(--et-hairline);
}
.mx-puce.est-actif .dsk-puce-n { background: var(--et-surface); border-color: var(--et-form-blue); color: var(--et-form-blue-d); }

/* ---------------------------------------------------------------------------
   10. PLAN DE CHARGE PAR AGENT

   Rangée de jetons « qui porte combien » au-dessus de l'écran d'affectation.
   C'est une répartition, donc .mx-barre du gabarit pour la jauge ; ce qui est
   ici est seulement la mise en rangée et l'intitulé court.
   --------------------------------------------------------------------------- */
.dsk-charges { display: flex; flex-wrap: wrap; gap: 10px; }
.dsk-charge { flex: 1 1 190px; min-width: 0; background: var(--et-surface-2); padding: 7px 10px; }
.dsk-charge-lbl {
    display: flex; align-items: baseline; gap: 6px; font-size: 12px; color: var(--et-muted);
    margin-bottom: 4px;
}
.dsk-charge-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--et-ink); font-weight: 600; }
.dsk-charge-n { font-family: var(--et-font-mono); font-weight: 700; color: var(--et-ink); }

/* ---------------------------------------------------------------------------
   11. LA RANGÉE D'AFFECTATION EN LIGNE

   Dans la file de tri, chaque rangée porte « file + agent + valider ». Les trois
   contrôles doivent tenir dans une cellule sans la faire enfler, et la cellule
   doit garder une largeur stable d'une rangée à l'autre — sinon la colonne danse
   au fil du contenu des autres colonnes.
   --------------------------------------------------------------------------- */
.dsk-affecter { display: flex; gap: 6px; align-items: center; min-width: 296px; }
.dsk-affecter > .mx-select { flex: 1 1 120px; min-width: 0; }
.dsk-affecter > .mx-input { flex: 1 1 118px; min-width: 0; }

/* ---------------------------------------------------------------------------
   12. LE PLANNING DES INTERVENTIONS

   Les ordres d'intervention groupés par jour : un intertitre de journée, puis
   les créneaux. Ce n'est pas un calendrier (le module n'a pas de vue mois) mais
   une liste ORDONNÉE dans le temps, ce qui est exactement ce qu'un technicien
   consulte le matin.
   --------------------------------------------------------------------------- */
.dsk-jour + .dsk-jour { margin-top: 14px; }
.dsk-jour-tete {
    display: flex; align-items: baseline; gap: 8px;
    padding: 5px 0 5px 2px; border-bottom: 1px solid var(--et-filet-fort);
    font-size: 13px; font-weight: 700; color: var(--et-ink);
}
.dsk-jour-tete .n { margin-left: auto; font-size: 12px; font-weight: 400; color: var(--et-faint); }
/* Le jour qui est AUJOURD'HUI porte le filet bleu de l'en-tête d'écran : c'est
   le même signal « vous êtes ici » et il n'a pas à être appris deux fois. */
.dsk-jour.est-aujourdhui .dsk-jour-tete { border-bottom-color: var(--et-form-strip); }
.dsk-creneau {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 8px 2px; border-bottom: 1px solid var(--et-hairline);
}
.dsk-creneau-h {
    flex: 0 0 96px; font-family: var(--et-font-mono); font-size: 13px; font-weight: 600; color: var(--et-ink);
}
.dsk-creneau-c { flex: 1; min-width: 0; }
.dsk-creneau-actions { flex: none; display: flex; gap: 4px; }

/* ---------------------------------------------------------------------------
   13. PALIERS RESPONSIVE (lot EasyDesk)

   Même doctrine que easypaie.css §17 : le module porte ses propres paliers plutôt
   qu'une feuille de lot, et il les prend dans l'échelle retenue du dépôt
   (560 / 640 / 720 / 1024 / 1100 — docs/conventions-responsive.md). Aucun palier
   inventé, aucune largeur en dur dans une page.

   GÉOMÉTRIE SEULEMENT : pas une couleur ici, et rien qui masque une information.
   Ce qui est secondaire dans une file de tickets est une décision de support, pas
   une décision de feuille de style.
   --------------------------------------------------------------------------- */

/* Sous 1024 px : la règle tactile du dépôt (docs/cibles-tactiles.md) étendue aux
   .dsk-*. Aucune cible interactive du module ne descend sous 44 × 44 px, et une
   cible ne rétrécit jamais. */
@media (max-width: 1024px) {
    .dsk-etoile { min-width: 44px; min-height: 44px; }
    .dsk-creneau-actions .mx-btn { min-height: 44px; min-width: 44px; }
    .dsk-affecter > .mx-select, .dsk-affecter > .mx-input { min-height: 44px; }
    .dsk-tuile.est-ouvrable { min-height: 132px; }
}

/* Sous 720 px : la rangée d'affectation en ligne cesse d'être une rangée. Trois
   contrôles côte à côte dans une cellule de table y font 90 px chacun, ce qui ne
   montre plus ni un nom de file ni un nom d'agent. */
@media (max-width: 720px) {
    .dsk-affecter { flex-wrap: wrap; min-width: 0; }
    .dsk-affecter > .mx-select, .dsk-affecter > .mx-input { flex: 1 1 100%; }
    .dsk-creneau { flex-wrap: wrap; }
    .dsk-creneau-h { flex: 1 1 100%; }
}

/* Sous 560 px : les gouttières rendues. Sur un téléphone, 14 px de marge de
   chaque côté d'une tuile coûtent un cinquième de la largeur utile. */
@media (max-width: 560px) {
    .dsk-grille { grid-template-columns: minmax(0, 1fr); }
    .dsk-tuile { padding: 10px 11px; }
    .dsk-filtres { padding: 9px 11px; }
    .dsk-recherche { width: 100%; }
    .dsk-filtres-fin { margin-left: 0; width: 100%; }
    .dsk-note { font-size: 28px; }
}

/* ---------------------------------------------------------------------------
   14. IMPRESSION D'UNE FICHE TICKET

   La fiche s'imprime — un compte rendu d'incident se classe encore sur papier
   chez la plupart des clients du module. Ce qui était écrit dans un <style> au
   pied de FicheTicket.razor (avec un #dee2e6 en dur) vit ici : une règle
   d'impression n'est pas moins une règle de charte.

   Les TAILLES ne sont pas dans l'échelle de type de la charte, et c'est la règle
   du dépôt : un bloc @media print exprime des tailles PHYSIQUES, pas des tailles
   d'écran.
   --------------------------------------------------------------------------- */
@media print {
    /* `body *` EST DÉLIMITÉ, ET LE @page N'EST PLUS ICI. Cette feuille est liée
       dans le <head> d'App.razor comme les 169 autres, sans condition de route :
       elle est chargée sur les 633 routes, et seuls ses sélecteurs la cantonnent
       à EasyDesk. `body *` n'en cantonnait aucun — il masquait le corps du
       document partout, et seul `.dsk-imprimable`, qui n'existe que sur la fiche
       ticket, reprenait sa visibilité. Même défaut, même jour, dans
       ecran-bulletin.css §171, dont l'en-tête porte la mesure.

       Le @page, lui, ne se délimite pas du tout : il vaut pour le DOCUMENT. Il
       est donc posé par l'écran via `etImpression` (js/easytime-shell.js), le
       mécanisme de l'organigramme — cf. ecran-kilometre.css §756, qui refuse
       d'écrire une @page ici pour cette exacte raison. */
    body:where(:has(.dsk-imprimable)) * { visibility: hidden; }
    .dsk-imprimable, .dsk-imprimable * { visibility: visible; }
    .dsk-imprimable { position: absolute; left: 0; top: 0; width: 100%; }

    /* Ce qui n'a pas de sens sur du papier : les commandes. */
    .dsk-hors-impression { display: none !important; }

    /* Empilé : deux colonnes calculées pour un écran de 1400 px sortent en deux
       colonnes de 90 mm sur une feuille qui en fait 186. */
    .dsk-fiche { display: block; }
    .dsk-flanc { position: static; margin-top: 8mm; }

    /* CES DEUX-LÀ SONT AUSSI DÉLIMITÉES, ET C'EST CE LOT QUI L'EXIGE. `.mx-carte`
       est la carte du GABARIT : ces règles, écrites pour la fiche ticket, valaient
       pour toutes les cartes du produit. Tant que les autres écrans sortaient une
       feuille blanche, cela ne se voyait pas ; maintenant qu'ils impriment, un
       `break-inside: avoid` sur une carte longue la repousserait à la page suivante
       en laissant un grand blanc — sur un journal général, ce serait une feuille par
       carte. Le raisonnement du commentaire d'origine est celui de la FICHE (un titre
       séparé de son contenu), pas celui d'un état comptable.

       La carte perd son ombre (elle sort en gris sale) et garde un filet. Le filet
       est le jeton, pas un gris recopié. Une carte coupée entre deux pages perd le
       lien entre son titre et son contenu ; le fil, lui, peut se couper — il est
       chronologique. */
    .dsk-imprimable .mx-carte { box-shadow: none !important; border: 1px solid var(--et-hairline); }
    .dsk-imprimable .mx-carte { break-inside: avoid; }
    .dsk-fil, .dsk-fil .dsk-msg { break-inside: auto; }
}
