/* ============================================================================
   TERMINAUX DE POINTAGE — /app/terminaux et /app/terminaux/{sn}
   Passation « design_handoff_terminaux » (Design 25).

   SA FEUILLE, ET RIEN QUE LA SIENNE. Trois familles qui n'existent que sur cet
   écran : la pastille d'état de connexion, la photo de l'appareil (vignette de
   liste et cadre de fiche), et le pavé de raccordement. Ce qui habille la carte
   de vignette elle-même n'est PAS ici : .tbl-vig-img appartient au gabarit de
   liste (easytime-shell.css), puisque toute liste dont les objets portent une
   image s'en servira — une feuille d'écran qui le porterait ferait dépendre le
   deuxième écran de la feuille du premier.

   Aucune couleur en dur : tout passe par les jetons --et-*, c'est par eux que le
   mode sombre existe.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   L'ÉTAT DE CONNEXION, en filet gauche plutôt qu'en pastille.

   La liste en porte un par rangée : un filet se lit en balayage vertical, là où
   une pastille arrête l'œil à chaque ligne. La couleur ne porte pas seule — le
   mot « Hors ligne » est écrit, pour qui ne distingue pas le vert du rouge. */
.term-etat {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 2px 8px;
    font-size: 12px; font-weight: 600;
}
.term-etat.est-en-ligne   { background: var(--et-succes-bg);       border-left: 3px solid var(--et-succes); color: var(--et-succes-ink); }
.term-etat.est-hors-ligne { background: var(--et-danger-badge-bg); border-left: 3px solid var(--et-danger); color: var(--et-danger-ink); }
/* « Erreur » n'est pas « hors ligne » : le terminal RÉPOND, mais mal. Les
   confondre enverrait chercher un câble débranché là où c'est le firmware qui
   refuse une trame. */
.term-etat.est-erreur     { background: var(--et-avertissement-bg); border-left: 3px solid var(--et-avertissement-mark); color: var(--et-avertissement-ink); }

/* ---------------------------------------------------------------------------
   LE DÉPÔT DE PHOTO, dans la vignette de liste.

   Il occupe toute la surface de l'image manquante : la cible de clic est la
   vignette entière, et non un lien de douze pixels sous la carte. */
.term-depot {
    position: absolute; inset: 0;
    display: grid; place-content: center; justify-items: center; gap: 6px;
    margin: 0;
    font-size: 12px; color: var(--et-faint);
    cursor: pointer;
}
.term-depot i { font-size: 20px; color: var(--et-inerte); }
label.term-depot:hover { background: var(--et-surface-2); color: var(--et-form-blue-d); }

/* ---------------------------------------------------------------------------
   LA FICHE : les champs à gauche, la photo à droite.

   176 px, la taille où l'on reconnaît un appareil — au-dessous, une pointeuse
   grise ressemble à toutes les pointeuses grises. La colonne disparaît au palier
   tablette : à cette largeur, la photo mangerait la moitié du formulaire dense,
   dont la colonne de libellés de 158 px ne se comprime pas. */
.term-affectation {
    display: grid; grid-template-columns: minmax(0, 1fr) 176px;
    gap: 18px; align-items: start;
}
/* 1024 px, ET NON 980 : docs/conventions-responsive.md fixe l'échelle des paliers
   à 560 / 640 / 720 / 1024 / 1100, et 980 n'en était pas — c'était une valeur
   propre à cet écran, que rien n'accordait aux autres. Le repli tombe donc au
   palier tablette, où le formulaire dense perd de toute façon sa place : sa
   colonne de libellés de 158 px ne se comprime pas, et la photo mangerait la
   moitié de ce qui reste. */
@media (max-width: 1024px) { .term-affectation { grid-template-columns: minmax(0, 1fr); } }

/* EN CRÉATION IL N'Y A PAS DE PHOTO — mais il y avait quand même sa colonne.
   La photo n'existe qu'APRÈS le terminal : son nom de fichier découle du numéro
   de série, qui n'est pas encore acquis. La fiche ne rend donc pas le bloc… et
   la piste de grille, elle, est DÉCLARÉE : une piste explicite ne disparaît pas
   avec son contenu. Le formulaire de création perdait ainsi 176 px de colonne
   plus 18 px de gouttière, au profit d'un vide que rien n'expliquait — c'est
   l'écran le plus étroit de la fiche qui payait le plus.

   Relevé le 2026-09-09 par tools/apercu-ecran/, et par lui seul : le balisage
   est juste, la feuille est juste, et le défaut n'existe qu'à leur rencontre. */
.term-affectation:not(:has(.term-photo)) { grid-template-columns: minmax(0, 1fr); }

/* LA COLONNE DE GAUCHE PORTE L'ONGLET ENTIER, et non plus son premier groupe.
   Jusqu'au 2026-09-11, .term-affectation n'enveloppait que « Affectation » : le
   groupe « Heure & synchronisation » était son FRÈRE, hors grille, donc large de
   toute la fiche. Deux largeurs de champ dans le même onglet, l'une sous l'autre —
   mesuré sur l'application qui tourne, dans la fenêtre de 1140 px : valeur à
   738 px sous le premier groupe, à 932 px sous le second. Personne n'avait demandé
   ce décrochement ; il était la conséquence non dite d'un enveloppement partiel.
   min-width: 0 sur la colonne, pour la même raison que sur .mx-champ-val : sans
   lui un enfant de grille refuse de se réduire sous la largeur de son contenu. */
.term-colonne { min-width: 0; }

/* La photo s'aligne sur la marge des champs (18 px, § 6 du gabarit) au lieu de
   toucher le bord du cadre. Sous le palier tablette elle passe SOUS le formulaire :
   il lui faut alors la marge des deux côtés. */
.term-photo { margin-right: 18px; }
@media (max-width: 1024px) { .term-photo { margin-left: 18px; } }

.term-photo .cadre {
    position: relative; width: 176px; height: 132px;
    border: 1px solid var(--et-hairline);
    background: var(--et-surface-3);
    overflow: hidden;
}
.term-photo .cadre img { width: 100%; height: 100%; object-fit: cover; display: block; }

.term-photo .vide {
    position: absolute; inset: 0;
    display: grid; place-content: center; justify-items: center; gap: 6px;
    margin: 0;
    font-size: 12px; color: var(--et-faint);
    cursor: pointer;
}
.term-photo .vide i { font-size: 20px; color: var(--et-inerte); }
label.term-photo .vide:hover,
.term-photo label.vide:hover { background: var(--et-surface-2); }

/* Les commandes n'apparaissent qu'au survol et au focus : posées en permanence,
   elles masqueraient le bas de la photo, c'est-à-dire souvent le mur ou la porte
   qui situe l'appareil. Le :focus-within les rend atteignables au clavier, sans
   quoi « Retirer » n'existerait que pour la souris. */
.term-photo .ctl { position: absolute; inset: auto 0 0 0; display: none; gap: 1px; }
.term-photo .cadre:hover .ctl,
.term-photo .cadre:focus-within .ctl { display: flex; }
.term-photo .ctl label,
.term-photo .ctl button {
    flex: 1; padding: 5px 0;
    border: none; background: rgba(20, 27, 38, .72);
    font-family: inherit; font-size: 12px; font-weight: 600; color: var(--et-sur-aplat);
    text-align: center; cursor: pointer;
}
.term-photo .ctl label:hover,
.term-photo .ctl button:hover { background: rgba(20, 27, 38, .88); }


/* L'affectation est un GESTE posé dans une rangée de champ, pas un contrôle de
   saisie : il se détache de la valeur qu'il commente. Le retrait était écrit en
   style en ligne sur le bouton — une géométrie n'a pas plus sa place dans une
   page qu'une couleur. */
.term-affecter { margin-top: 7px; }

/* ---------------------------------------------------------------------------
   LE SUFFIXE D'UNITÉ d'un champ du formulaire dense (« min »).

   Il est DANS le cadre du champ et non à côté : posé à l'extérieur, il se
   décalait de la valeur dès que la colonne se resserrait, et l'on finissait par
   lire un nombre sans son unité.

   Le composant lui-même vit dans le gabarit (.mx-input-suffixe, modele-erp.css
   § 11) : ne restent ici que la largeur — affaire de mise en page — et la
   réserve, que commande la longueur des suffixes de cet écran (« min », « s »). */
.term-suffixe { --mx-suffixe-reserve: 42px; max-width: 200px; }

/* ---------------------------------------------------------------------------
   LE PAVÉ DE RACCORDEMENT, replié par défaut.

   Ces valeurs — adresse, port, protocole — ne se trouvent nulle part ailleurs, et
   c'est ici qu'on les cherche, le terminal en main. Repliées, parce qu'on ne les
   consulte qu'à la pose d'un appareil : dépliées en permanence, elles poussaient
   la liste de trois cents pixels vers le bas tous les autres jours. */
.term-raccordement { margin: 0 14px 14px; border: 1px solid var(--et-hairline); background: var(--et-surface-3); }
.term-raccordement > summary {
    padding: 9px 12px; cursor: pointer;
    font-size: 13px; font-weight: 600; color: var(--et-ink);
}
.term-raccordement > summary:hover { color: var(--et-form-blue-d); }
.term-raccordement-corps {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 14px; padding: 0 12px 12px;
    font-size: 13px; color: var(--et-ink);
}
.term-raccordement-corps .titre { margin-bottom: 5px; font-weight: 600; }
.term-raccordement-corps ul { margin: 0; padding-left: 18px; line-height: 1.7; }
.term-raccordement-corps code { font-family: var(--et-font-mono); font-size: 12px; color: var(--et-form-blue-d); }
/* La note tient sur toute la largeur : coupée en colonne, une phrase de mise en
   garde se lit comme une légende, et l'on ne lit pas les légendes. */
.term-raccordement-note { grid-column: 1 / -1; color: var(--et-muted); line-height: 1.6; }

/* ---------------------------------------------------------------------------
   LA FICHE EN FENÊTRE (recette du 2026-08-18, mise au gabarit le 2026-09-09).

   C'est le cadre normal de la fiche : on corrige un parc en le parcourant, et
   une page ferait perdre à chaque ouverture le tri, le filtre et la position de
   la liste.

   IL NE RESTE ICI QUE LA LARGEUR ET DEUX ACCORDS. Tout ce que ce bloc portait
   auparavant — plafond de hauteur, défilement interne, en-tête collant, rail
   privé de son plancher de 620 px — est ce que .mx-modale-fiche (modele-erp.css
   § 6) fait pour les quatre écrans qui logent un rail d'onglets dans une
   fenêtre. Ces règles étaient donc une CINQUIÈME copie, écrite avant que le
   gabarit ne sache le faire, et elle avait déjà divergé sur un point qui compte :
   le plafond se calculait sur 56 px de retrait quand le voile du gabarit en pose
   96, si bien que le pied de la fiche — « Enregistrer » compris — passait sous
   la ligne de flottaison sur un portable en paysage. */

/* LA LARGEUR EST CELLE DU CRAN LARGE (2026-09-11) — .est-large, posée dans la
   page. Elle a été mise au cran TRÈS LARGE la veille, en constatant que les
   1140 px qu'écrivait cette feuille étaient les 1120 du cran « à vingt pixels que
   personne ne pouvait voir ». C'est juste sur les vingt pixels, et c'est le cran
   qui était le mauvais : le motif inscrit ici — « la photo ne tient pas dans une
   fenêtre de saisie ordinaire » — ne tient pas au calcul. La photo et sa
   gouttière coûtent 194 px, pas 460.

   CE QUE 1140 px PRODUISAIENT, mesuré sur l'application qui tourne : un <select>
   « Actif » de 738 px et un <select> de fuseau de 932 px, pour des listes dont la
   plus longue option écrit 39 caractères. C'est ce qu'un utilisateur a relevé en
   demandant que cette fiche soit resserrée. Un champ n'est pas plus lisible parce
   qu'il est plus large ; passé la longueur de ce qu'on y écrit, il devient un
   trait qui traverse la fenêtre.

   À 880 px, photo comprise, la valeur mesure la même chose dans les deux groupes
   de l'onglet, et rien n'est tronqué (relevé aux quatre largeurs de recette). */

/* Le titre prend la place restante : sans cela, la rangée de tête se distribue
   entre l'intitulé, les pastilles d'état et le carré de fermeture, et un alias
   long pousse les pastilles hors du cadre. */
.term-fenetre .mx-modale-tete-txt { flex: 1; }

/* Le second rang de la tête porte le NUMÉRO DE SÉRIE, une valeur technique : il
   se lit en chasse fixe, comme partout ailleurs dans la fiche. */
.term-fenetre .mx-modale-sous { font-family: var(--et-font-mono); }

/* Le bandeau d'état est posé ENTRE la tête et la bande de faits, donc dans la
   colonne flex de la fenêtre : sans « flex: none » il se comprimerait au profit
   des panneaux, et un message de deux lignes serait rogné. */
.term-fenetre > .mx-blocage { flex: none; }

/* La retenue à la fermeture : le message à gauche, les deux issues à droite.
   Le bouton de sortie est le DERNIER, et il est rouge — l'ordre de lecture met
   sous la main ce qui conserve le travail, non ce qui le jette.

   « flex: none » sur les deux boutons : une cible ne rétrécit pas
   (docs/cibles-tactiles.md), et dans un bandeau qui porte une phrase ce sont
   elles qui paieraient le débordement. */
.term-retenue { align-items: center; }
.term-retenue .mx-btn { flex: none; }

/* ---------------------------------------------------------------------------
   L'ATTENTE. Ni un état vide (.mx-etat-vide, qui dit « il n'y a rien » et
   s'encadre pour le dire), ni une donnée : un temps mort, qui ne demande qu'à
   ne pas coller au bord. Géométrie seule. */
.term-chargement { padding: 48px 24px; text-align: center; }
