/* ===========================================================================
   MODÈLE DE FICHE — charte EasyTech (bleu marine #1B2A5E / orange #F26C16)
   Préfixe de classes : .fx-*  («fiche»).

   D'OÙ ÇA VIENT
   Maquettes « Fiche terminal », « Fiche terminal v2 » et « Nouveau terminal »
   (export Claude Design, août 2026). La v2 fixe la coquille (bandeau marine,
   carte principale + colonne latérale), la v1 apporte les séparateurs de
   section, la bande d'état et le bloc « actions irréversibles », la troisième
   la modale de création. Ce fichier est la transcription des trois en classes
   réutilisables — même démarche que l'écran de connexion (.cx-* dans app.css),
   qui reproduit sa maquette de la même façon.

   CE QUE C'EST
   Le MODÈLE des fiches détail du back-office : premier écran servi, la fiche
   terminal d'EasyTime (Pages/App/FicheTerminal.razor). Les fiches suivantes
   (employé, article, tiers…) se composent avec ces mêmes classes plutôt qu'en
   réinventant un habillage par page — c'est ce qui a fait diverger trois
   systèmes de jetons concurrents (cf. l'avertissement en tête de
   easytech-theme.css).

   RÈGLES DE REPRISE
   - Ne pas coder une couleur en dur dans une page : tout est en variables
     --fx-* posées sur .fx-page ci-dessous, elles-mêmes alignées sur les jetons
     de marque --et-blue / --et-orange quand ils existent.
   - La structure est toujours la même : .fx-page > .fx-entete + .fx-corps,
     .fx-corps > (.fx-carte principale) + (.fx-cote colonne latérale).
   - Une fiche = une seule carte de saisie, découpée en .fx-section, avec un
     seul pied .fx-carte-pied (Annuler / Enregistrer). Les informations non
     modifiables descendent dans la colonne latérale.

   THÈME SOMBRE
   Pris en charge sous .appgrid[data-theme="dark"] — même sélecteur que la
   coquille (easytime-shell.css) et que les jetons de contenu
   (easytech-theme.css). Le bandeau marine et la carte « capacité » ne changent
   pas : ils portent déjà du texte blanc.
   =========================================================================== */

.fx-page,
.fx-modale {
    /* --- Jetons du modèle (source unique pour les pages qui l'utilisent) ---
       Posés AUSSI sur .fx-modale : une modale se rend dans <ModalCadre>, donc
       hors de l'arbre de .fx-page, et n'héritait d'aucun de ces jetons. */
    --fx-marine: #1B2A5E;
    --fx-orange: var(--et-orange);
    --fx-orange-fonce: var(--et-orange-600);

    /* BASCULE 2026-08-17 (passation « Design 7 ») — ces jetons ne portent plus de
       valeur propre : ils POINTENT ceux de easytech-theme.css. Ils dupliquaient la
       palette à un cran près (#141B26 contre #32363A, #E4EAF3 contre #E5E5E5), et
       c'est exactement le troisième système de jetons concurrent contre lequel
       l'en-tête de easytech-theme.css met en garde. Les noms restent — une
       quarantaine d'écrans les consomment — mais ils cessent de diverger.
       Le bleu de l'ancien modèle (--fx-bleu, #4C7FBF, écrit en dur dans quelques
       règles plus bas) devient lui aussi le bleu SAP. */
    --fx-carte: var(--et-surface);
    --fx-carte-bord: var(--et-hairline);
    --fx-bandeau: var(--et-surface-2);
    --fx-bandeau-bord: var(--et-hairline);
    --fx-filet: var(--et-rang);
    --fx-bleu: var(--et-form-blue);

    --fx-texte: var(--et-ink);
    --fx-texte-2: var(--et-ink);
    --fx-texte-3: var(--et-muted);
    --fx-discret: var(--et-faint);
    --fx-tres-discret: var(--et-inerte);

    --fx-champ-bord: var(--et-form-border);
    /* Le champ était sur fond bleuté ; il redevient BLANC. Sur des surfaces plates
       séparées par des filets, un champ teinté se lit comme une zone désactivée —
       et le fond grisé est justement ce que la passation réserve à la lecture
       seule, qui n'aurait plus rien pour se distinguer. */
    --fx-champ-fond: var(--et-surface);
    --fx-champ-fond-inactif: var(--et-surface-3);

    --fx-err: var(--et-danger);
    --fx-err-bord: var(--et-danger-bord);
    --fx-err-fond: var(--et-danger-badge-bg);
    /* Même arithmétique : --fx-err (= --et-danger) sur --fx-err-fond rend 4,22:1,
       SOUS le seuil AA pour les 12 px d'une pastille ; ce rouge-ci rend 6,95:1. */
    --fx-err-encre: var(--et-danger-ink);
    --fx-attention: var(--et-avertissement);
    --fx-attention-bord: #F7D9BC;
    --fx-attention-fond: var(--et-avertissement-bg);
    /* L'ENCRE N'EST PAS LA COULEUR D'ÉTAT, ET LA MESURE LE DIT. --fx-attention
       (= --et-avertissement, #F59E0B) posé en encre sur --fx-attention-fond rend
       2,02:1 — et ce n'était pas une hypothèse : .fe-entete .fx-etat.est-attente
       l'écrivait DÉJÀ ainsi. Une conversion antérieure avait pris la couleur
       d'état pour l'encre du texte posé dessus. #8A4A0C rend 6,46:1.
       C'est le même cran que --et-avertissement-ink dans la charte, et que
       --fx-ok-encre dans cette feuille. */
    --fx-attention-encre: var(--et-avertissement-ink);
    --fx-ok: var(--et-succes);
    --fx-ok-fond: var(--et-succes-bg);
    /* LA FAMILLE « OK » ÉTAIT LA SEULE DES QUATRE SANS BORDURE NI ENCRE : err et
       attention ont chacune son triple -, -bord, -fond, et .fx-encart.est-succes
       écrivait donc ses deux valeurs manquantes en dur. --fx-ok-encre N'EST PAS
       --fx-ok, et l'écart est mesuré, pas esthétique : --et-succes sur
       --et-succes-bg rend 3,16:1, sous le seuil AA pour du texte de 13 px, quand
       ce vert-ci rend 5,63:1. C'est la même distinction que --et-avertissement-ink
       contre --et-avertissement dans la charte — l'encre POSÉE SUR le fond pâle
       n'est pas la couleur d'état elle-même. */
    --fx-ok-bord: var(--et-succes-bord);
    --fx-ok-encre: var(--et-succes-ink);
    /* LES DEUX RÔLES QUI MANQUAIENT À LA FAMILLE D'ÉTATS. Elle en portait trois
       — ok, attention, err — et les pastilles en emploient CINQ. « maintenance »
       et « neutre » s'écrivaient donc en dur, dans quatre familles de pastilles.
       Aucun jeton à inventer : ce sont l'information et le neutre de la charte,
       et leur contraste passe sans cran supplémentaire (6,14:1 et 4,81:1) — d'où
       l'absence de -encre ici, contrairement à ok, attention et err. */
    --fx-info: var(--et-info);
    --fx-info-fond: var(--et-info-bg);
    --fx-neutre: var(--et-neutre);
    --fx-neutre-fond: var(--et-neutre-bg);

    --fx-rouge: var(--et-danger);
    --fx-rouge-fonce: #990000;

    --fx-mono: var(--et-font-mono);
    /* 2026-08-17 : à plat. « Ni ombre ni arrondi, la structure tient par les filets. » */
    --fx-rayon: 0;
    /* COINS DROITS SUR LES CHAMPS — consigne de charte, confirmée par l'export
       « Fiche terminal » où chaque <input>/<select> porte border-radius: 0.

       Deux jetons et non un seul : le précédent, --fx-rayon-champ, habillait à la
       fois les champs ET .fx-btn, .fx-encart, .fx-bande.est-encadree. Le passer à 0
       aurait carré tous les boutons du modèle au passage, alors que la maquette les
       garde à 10 px. Ce qui se ressemblait par leur valeur ne se ressemblait pas par
       leur intention. */
    --fx-rayon-champ: 0;
    /* Les boutons gardent un arrondi, mais celui de la passation : 4 px, pas 10. */
    --fx-rayon-btn: var(--et-r-btn);
    --fx-ombre: none;

    color: var(--fx-texte);
    font-family: var(--et-font);
}

/* ---------------------------------------------------------------------------
   1. Bandeau d'en-tête (marine, filet orange)
   La maquette le pose pleine largeur ; ici il est arrondi et vit dans la zone
   de contenu de la coquille, qui a déjà ses propres marges.
   --------------------------------------------------------------------------- */
.fx-entete {
    background: var(--fx-marine);
    background-image: radial-gradient(900px 400px at 12% -60%, rgba(255, 255, 255, .09), transparent 62%);
    border-bottom: 3px solid var(--fx-orange);
    border-radius: var(--fx-rayon) var(--fx-rayon) 0 0;
    padding: 18px 22px 20px;
}

/* Sans bande d'état dessous (chargement, fiche introuvable), le bandeau se referme. */
.fx-entete.est-seul { border-radius: var(--fx-rayon); }

.fx-fil { display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--et-sur-marine-faible); }
.fx-fil a { color: var(--et-sur-marine-doux); font-weight: 500; text-decoration: none; }
.fx-fil a:hover { color: var(--et-sur-marine); text-decoration: underline; }
.fx-fil .sep { color: rgba(255, 255, 255, .34); }
.fx-fil .mono { font-family: var(--fx-mono); color: var(--et-sur-marine); }

.fx-entete-bas { display: flex; align-items: flex-end; gap: 16px; margin-top: 14px; flex-wrap: wrap; }
.fx-entete-txt { min-width: 0; flex: 1; }
.fx-entete-ligne { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.fx-titre { margin: 0; font-size: 24px; font-weight: 700; color: var(--et-sur-marine); letter-spacing: -0.025em; }
.fx-sous { margin-top: 5px; font-size: 13px; color: var(--et-sur-marine-faible); }

/* Pastilles d'état posées dans le bandeau : fond translucide, texte clair. */
.fx-etat {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 11px; border-radius: 999px;
    font-size: 12px; font-weight: 600;
    background: var(--et-fond-marine-doux); color: var(--et-sur-marine-doux);
}
.fx-etat .pt { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.fx-etat svg { flex: none; }
.fx-etat.est-ok          { background: var(--et-fond-marine-succes);        color: var(--et-sur-marine-succes); }
.fx-etat.est-attente     { background: var(--et-fond-marine-avertissement); color: var(--et-sur-marine-avertissement); }
.fx-etat.est-bloque      { background: var(--et-fond-marine-danger);        color: var(--et-sur-marine-danger); }
.fx-etat.est-maintenance { background: var(--et-fond-marine);               color: var(--et-sur-marine-info); }
.fx-etat.est-neutre      { background: var(--et-fond-marine-doux); color: var(--et-sur-marine-faible); }

/* Indicateur d'enregistrement, à droite du titre. */
.fx-sauvegarde {
    flex: none; min-height: 20px; display: flex; align-items: center; gap: 7px;
    font-size: 12px; color: var(--et-sur-marine-faible); animation: fxIn .2s ease both;
}
.fx-sauvegarde.est-fait { color: var(--et-sur-marine-succes); }
.fx-sauvegarde .fx-spin { border-color: var(--et-filet-marine); border-top-color: var(--fx-orange); }

/* ---------------------------------------------------------------------------
   2. Bande d'état (dernier battement, dernier pointage, IP…) — maquette v1
   --------------------------------------------------------------------------- */
.fx-bande {
    display: flex; align-items: stretch; flex-wrap: wrap;
    background: var(--fx-carte);
    border: 1px solid var(--fx-carte-bord); border-top: none;
    border-radius: 0 0 var(--fx-rayon) var(--fx-rayon);
    overflow: hidden;
}
.fx-bande-item { flex: 1; min-width: 168px; padding: 11px 20px; border-right: 1px solid var(--fx-filet); }
.fx-bande-item:last-child { border-right: none; }
.fx-bande-lbl { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--fx-discret); }
.fx-bande-lbl .pt { width: 7px; height: 7px; border-radius: 50%; flex: none; background: currentColor; }
.fx-bande-val { margin-top: 3px; font-size: 14px; font-weight: 600; color: var(--fx-texte-2); }
.fx-bande-val.mono { font-family: var(--fx-mono); font-weight: 400; }
.fx-bande-actions { flex: none; display: flex; align-items: center; gap: 8px; padding: 12px 18px; }
/* Variante autonome : la bande d'état se suspend normalement sous l'en-tête de
   page ; encadrée, elle porte des valeurs calculées dans le corps d'une carte
   ou d'une modale. */
.fx-bande.est-encadree {
    background: var(--fx-bandeau); border: 1px solid var(--fx-carte-bord);
    border-radius: var(--fx-rayon-btn);
}
.fx-bande.est-encadree .fx-bande-item { min-width: 124px; padding: 9px 14px; }

/* ---------------------------------------------------------------------------
   3. Corps : carte principale + colonne latérale
   --------------------------------------------------------------------------- */
.fx-corps {
    display: grid; grid-template-columns: minmax(0, 1fr) 316px; gap: 22px;
    align-items: start; margin-top: 22px;
}
@media (max-width: 1100px) { .fx-corps { grid-template-columns: minmax(0, 1fr); } }

.fx-carte {
    background: var(--fx-carte);
    border: 1px solid var(--fx-carte-bord);
    border-radius: var(--fx-rayon);
    box-shadow: var(--fx-ombre);
    overflow: hidden;
    animation: fxUp .4s ease both;
}
.fx-carte-tete {
    display: flex; align-items: center; gap: 10px;
    padding: 14px 22px;
    background: var(--fx-bandeau); border-bottom: 1px solid var(--fx-bandeau-bord);
}
.fx-carte-tete .ico {
    width: 26px; height: 26px; border-radius: 0; flex: none;
    background: var(--fx-marine); color: var(--et-sur-marine);
    display: grid; place-items: center; font-size: 13px;
}
.fx-carte-titre { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }
.fx-carte-note { margin-left: auto; font-size: 12px; color: var(--fx-discret); }
.fx-carte-corps { padding: 22px; }
.fx-carte-pied {
    display: flex; align-items: center; gap: 10px;
    padding: 16px 22px;
    background: var(--fx-bandeau); border-top: 1px solid var(--fx-bandeau-bord);
    flex-wrap: wrap;
}
.fx-carte-pied .fx-pied-txt { flex: 1; min-width: 180px; font-size: 13px; color: var(--fx-discret); }

/* Séparateur de section à l'intérieur d'une carte (maquette v1). */
.fx-section {
    display: flex; align-items: center; gap: 9px;
    padding-bottom: 10px; border-bottom: 2px solid var(--fx-bandeau-bord);
}
.fx-section + * { margin-top: 16px; }
.fx-section:not(:first-child) { margin-top: 32px; }
.fx-section .barre { width: 3px; height: 15px; background: var(--et-form-blue); flex: none; }
/* Graisse 700 et ardoise (2026-08-17) : l'intitulé de groupe est le seul repère
   de structure d'une fiche sans filets de rangée — en 500 il se lisait comme un
   libellé de champ un peu plus haut que les autres. */
.fx-section .txt {
    font-family: var(--fx-mono); font-size: 12px; font-weight: 700;
    letter-spacing: .16em; text-transform: uppercase; color: var(--et-table-head-encre);
}
/* La note explique le groupe ; elle reste en bas de casse et en gris atténué —
   sans capitales, pour qu'on ne la prenne pas pour un second intitulé. */
.fx-section .note { font-size: 12px; text-transform: none; letter-spacing: 0; color: var(--et-faint); }

/* ---------------------------------------------------------------------------
   4. Champs
   --------------------------------------------------------------------------- */
.fx-grille { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 18px; }
.fx-grille .large { grid-column: 1 / -1; }
/* LES COLONNAGES PLUS FINS ONT ÉTÉ RETIRÉS le 2026-09-09 : `.a-trois`,
   `.a-quatre` et `.demi` n'étaient écrits dans AUCUN attribut `class` du dépôt —
   relevé jeton par jeton sur toutes les vues, hors copies `_A_SUPPRIMER_` et
   `.bak-`. Seule la grille nue est employée, par deux modales. Leur palier à
   860 px partait avec elles : convertir le seuil d'une règle que rien ne rend
   aurait fait taire la garde sans rien corriger. */
@media (max-width: 640px) {
    .fx-grille { grid-template-columns: minmax(0, 1fr); }
}

/* 11,5 px / 500 / gris de libellé (2026-08-17) : la passation demande que le
   LIBELLÉ recule et que la VALEUR ressorte. En 13 px gras il pesait plus que la
   donnée qu'il annonce, et une fiche de quarante champs se lisait comme quarante
   titres. */
.fx-label {
    display: flex; align-items: baseline; gap: 5px;
    font-size: 12px; font-weight: 500; line-height: 1.35;
    color: var(--et-muted); margin: 0 0 4px;
}
.fx-label .req { color: var(--fx-rouge); }
.fx-champ { position: relative; }

/* 34 px et 13 px (2026-08-17), au lieu de 42 / 14,5. Une fiche salarié porte une
   quarantaine de champs : à 42 px, l'onglet « Contrat et affectation » demandait
   deux écrans de défilement pour douze valeurs. La densité n'est pas un tassement,
   c'est ce qui permet de voir un dossier d'un seul regard. */
.fx-input, .fx-select {
    width: 100%; height: 34px; padding: 0 11px;
    border: 1px solid var(--fx-champ-bord); border-radius: var(--fx-rayon-champ);
    font-size: 13px; font-family: inherit;
    color: var(--fx-texte); background: var(--fx-champ-fond);
    outline: none; transition: border-color .12s ease;
}
.fx-select { padding-right: 36px; appearance: none; cursor: pointer; }
.fx-input.mono { font-family: var(--fx-mono); letter-spacing: .04em; }
.fx-input::placeholder { color: var(--et-faint); }
/* Focus BLEU et sans halo : « focus bordure #0A6ED1 ». L'anneau orange de 3 px
   était le plus voyant des orange parasites — il apparaissait sur le champ en
   cours de saisie, c'est-à-dire en permanence pendant qu'on remplit une fiche. */
.fx-input:focus, .fx-select:focus {
    border-color: var(--et-form-blue); box-shadow: none;
}
/* Lecture seule : fond #FAFAFA, filet pâle, texte gris — grisé mais LISIBLE. */
.fx-input:disabled, .fx-select:disabled {
    background: var(--fx-champ-fond-inactif); border-color: var(--et-hairline);
    color: var(--et-muted); cursor: default;
}
.fx-input.est-faux, .fx-select.est-faux { border-color: var(--et-danger); }
/* Suffixe d'unité (« sec. », « min ») et chevron du select : purement décoratifs. */
.fx-suffixe, .fx-chevron {
    position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
    pointer-events: none; color: var(--fx-tres-discret); display: grid;
}
.fx-suffixe { font-size: 13px; }
.fx-input.a-suffixe { padding-right: 46px; }

/* Une seule ligne sous un champ à la fois : aide, erreur OU compteur. Empiler les
   trois pousse le champ suivant et fait sauter la fiche à la frappe. */
.fx-aide { margin-top: 4px; font-size: 12px; line-height: 1.4; color: var(--fx-discret); }
.fx-aide.est-attention { color: var(--fx-attention); }
.fx-aide-ligne { display: flex; justify-content: space-between; gap: 12px; margin-top: 7px; font-size: 13px; color: var(--fx-discret); }
.fx-compteur { font-family: var(--fx-mono); flex: none; }
.fx-erreur { display: flex; align-items: center; gap: 6px; margin-top: 4px; font-size: 12px; color: var(--fx-err); }
.fx-erreur svg { flex: none; }

/* Interrupteur (case à cocher présentée en ligne). */
.fx-bascule { display: flex; align-items: flex-start; gap: 10px; }
/* LES 17 px SONT PARTIS D'ICI (2026-09-10), ET CE N'ÉTAIT PAS QUE DE LA REDONDANCE.
   app.css les pose sur toute case native, donc les répéter ne servait à rien — mais
   ils NUISAIENT : à (0,1,1), ce sélecteur égalait la marche tactile de
   lot02-cibles-tactiles.css, et fiche.css est lié APRÈS lui (App.razor:102 contre
   :55). L'égalité tranchait donc en faveur d'ici, et les quarante et quelques écrans
   du modèle .fx-* n'auraient pas eu leurs 24 px sous 1024 px. Un décalage que rien
   n'aurait signalé, sur le modèle le plus employé du dépôt. */
.fx-bascule input { margin-top: 1px; cursor: pointer; }
.fx-bascule label { margin: 0; font-size: 14px; font-weight: 600; color: var(--fx-texte-2); cursor: pointer; }

/* ---------------------------------------------------------------------------
   5. Bandeaux d'avis (non enregistré, erreur, information)
   --------------------------------------------------------------------------- */
.fx-avis {
    display: flex; align-items: center; gap: 11px;
    padding: 12px 22px; font-size: 13px; line-height: 1.5;
    animation: fxIn .2s ease both;
}
.fx-avis svg { flex: none; }
.fx-avis .txt { flex: 1; min-width: 0; }
.fx-avis.est-attention { background: var(--fx-attention-fond); border-bottom: 1px solid var(--fx-attention-bord); color: var(--fx-attention); }
.fx-avis.est-erreur    { background: var(--fx-err-fond);       border-bottom: 1px solid var(--fx-err-bord);       color: var(--fx-err); }
.fx-avis.est-ok        { background: var(--fx-ok-fond);        border-bottom: 1px solid var(--fx-ok-bord);        color: var(--fx-ok-encre); }
/* Variante encadrée, à poser dans le corps d'une carte plutôt qu'en bandeau. */
.fx-encart {
    display: flex; gap: 10px; padding: 11px 13px; border-radius: var(--fx-rayon-btn);
    font-size: 13px; line-height: 1.5; animation: fxIn .2s ease both;
}
.fx-encart.est-erreur    { background: var(--fx-err-fond);       border: 1px solid var(--fx-err-bord);       color: var(--fx-err); }
.fx-encart.est-attention { background: var(--fx-attention-fond); border: 1px solid var(--fx-attention-bord); color: var(--fx-attention); }
/* L'accusé d'enregistrement. Il manquait à la famille : les écrans qui en avaient
   besoin le posaient en style en ligne, chacun avec sa nuance de vert. */
.fx-encart.est-succes    { background: var(--fx-ok-fond);        border: 1px solid var(--fx-ok-bord);        color: var(--fx-ok-encre); }
/* Quatrième variante : le CONSTAT — ce que la validation va faire, ce qu'un verrou
   interdit. Ni erreur ni avertissement : rien à corriger, quelque chose à savoir. Sans
   elle, un encart neutre rendait sans fond ni bordure et se lisait comme du texte perdu,
   ce qui poussait les écrans à réemployer est-attention pour de l'information — un ambre
   qui ne signale plus rien à force de tout signaler. Elle vit ICI et non dans la feuille
   d'un écran : elle appartient à la famille .fx-*, et deux écrans la posent déjà. */
.fx-encart.est-neutre    { background: var(--fx-bandeau);        border: 1px solid var(--fx-carte-bord);     color: var(--fx-texte-3); }

/* ---------------------------------------------------------------------------
   6. Boutons
   --------------------------------------------------------------------------- */
/* 2026-08-17 : 32 px, comme les boutons de barre d'outils de la passation. Le
   translateY(1px) au clic disparaît — « rien d'autre ne bouge » — et l'arrondi
   descend de 10 à 4 px via --fx-rayon-btn. */
.fx-btn {
    flex: none; height: 32px; padding: 0 14px;
    display: inline-flex; align-items: center; justify-content: center; gap: 9px;
    border-radius: var(--fx-rayon-btn);
    font-size: 14px; font-weight: 600; font-family: inherit;
    cursor: pointer; border: 1px solid transparent;
    transition: background .13s ease, border-color .13s ease;
    white-space: nowrap;
}
.fx-btn:disabled { cursor: not-allowed; opacity: 1; }
.fx-btn-neutre { background: var(--fx-carte); color: var(--et-muted); border-color: var(--fx-carte-bord); }
.fx-btn-neutre:hover:enabled { background: var(--et-tint); border-color: var(--et-info-bord); }
.fx-btn-neutre:disabled { color: var(--fx-tres-discret); }
/* LE bouton d'engagement — un par écran. */
.fx-btn-cta { background: var(--fx-orange); color: var(--et-sur-aplat); padding: 0 18px; border-color: var(--fx-orange); }
.fx-btn-cta:hover:enabled { background: var(--fx-orange-fonce); border-color: var(--fx-orange-fonce); }
.fx-btn-cta:disabled { background: var(--et-action-off); border-color: var(--et-action-off); cursor: not-allowed; }
/* Bouton transparent de barre d'outils : bleu sur rien, fond bleu pâle au survol.
   C'est lui, et non le neutre, qui porte les actions secondaires d'un en-tête de
   fiche — « Inviter au portail », « Historique paie ». */
.fx-btn-plat { background: transparent; color: var(--et-form-blue-encre); border-color: transparent; }
.fx-btn-plat:hover:enabled { background: var(--et-tint); color: var(--et-form-blue-d); }
.fx-btn-danger { background: var(--fx-rouge); color: var(--et-sur-aplat); }
.fx-btn-danger:hover:enabled { background: var(--fx-rouge-fonce); }
.fx-btn-danger-doux { background: var(--fx-carte); color: var(--fx-err); border-color: var(--et-danger-bord); }
.fx-btn-danger-doux:hover:enabled { background: var(--et-danger-badge-bg); border-color: var(--et-danger-bord); }
.fx-btn-petit { height: 28px; padding: 0 11px; font-size: 13px; border-radius: var(--fx-rayon-btn); }
.fx-btn-bloc { width: 100%; }

/* PUCE DE VALEUR USUELLE — le raccourci posé à côté d'un champ numérique, qui
   règle la valeur d'un clic (« 7 j », « 14 j », « 28 j »).
   Elle n'est pas un bouton d'action : elle ne déclenche rien, elle SAISIT. D'où
   sa discrétion — plus petite qu'un .fx-btn, en encre secondaire — et le fait
   qu'elle ne consomme aucune des couleurs d'action. Sans ce cran de taille,
   trois puces à côté d'un champ pèseraient plus lourd à l'œil que le bouton
   d'engagement du pied de fiche. */
.fx-puce {
    flex: none; height: 24px; padding: 0 9px;
    display: inline-flex; align-items: center;
    background: var(--fx-carte); border: 1px solid var(--fx-carte-bord);
    border-radius: var(--fx-rayon-btn);
    font-family: var(--et-font-mono); font-size: 12px; color: var(--et-muted);
    cursor: pointer; white-space: nowrap;
    transition: background .13s ease, border-color .13s ease, color .13s ease;
}
.fx-puce:hover:enabled { background: var(--et-tint); border-color: var(--et-form-blue); color: var(--et-form-blue-d); }
.fx-puce:disabled { cursor: not-allowed; color: var(--fx-tres-discret); }

.fx-spin {
    width: 15px; height: 15px; flex: none; display: inline-block;
    border: 2.5px solid rgba(255, 255, 255, .45); border-top-color: var(--et-sur-aplat);
    border-radius: 50%; animation: fxSpin .7s linear infinite;
}
.fx-spin.est-sombre { border: 2px solid var(--et-hairline); border-top-color: var(--fx-orange); width: 12px; height: 12px; }

/* ---------------------------------------------------------------------------
   7. Colonne latérale : capacité (carte marine), listes de définitions, actions
   --------------------------------------------------------------------------- */
.fx-cote { display: flex; flex-direction: column; gap: 16px; animation: fxUp .5s ease both; }

.fx-carte-marine {
    background: var(--fx-marine); border-radius: var(--fx-rayon); padding: 18px 20px; color: var(--et-sur-marine);
}
.fx-surtitre {
    font-family: var(--fx-mono); font-size: 12px; letter-spacing: .16em;
    text-transform: uppercase; color: var(--et-sur-marine-faible);
}
.fx-jauges { display: flex; flex-direction: column; gap: 14px; margin-top: 14px; }
.fx-jauge-tete { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.fx-jauge-lbl { font-size: 13px; color: var(--et-sur-marine-doux); }
.fx-jauge-val { font-family: var(--fx-mono); font-size: 12px; color: var(--et-sur-marine); }
.fx-jauge-piste { margin-top: 6px; height: 4px; background: var(--et-fond-marine); border-radius: 999px; overflow: hidden; }
.fx-jauge-barre { height: 100%; border-radius: 999px; background: var(--et-marine-succes); }
.fx-jauge-barre.est-chargee { background: var(--fx-orange); }

.fx-carte-simple {
    background: var(--fx-carte); border: 1px solid var(--fx-carte-bord);
    border-radius: var(--fx-rayon); overflow: hidden;
}
.fx-carte-simple > .tete {
    padding: 12px 18px; background: var(--fx-bandeau);
    border-bottom: 1px solid var(--fx-bandeau-bord);
    font-size: 13px; font-weight: 600;
}
.fx-carte-simple > .corps { padding: 6px 18px 14px; }
.fx-carte-simple > .corps.serre { padding: 14px 18px; }

.fx-def { display: flex; align-items: baseline; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--fx-filet); }
.fx-def:last-child { border-bottom: none; }
.fx-def-lbl { flex: none; font-size: 13px; color: var(--fx-discret); }
.fx-def-val {
    margin-left: auto; min-width: 0; font-family: var(--fx-mono); font-size: 12px; color: var(--fx-texte-2);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fx-note { padding-top: 12px; font-size: 12px; line-height: 1.5; color: var(--fx-tres-discret); }

/* Actions irréversibles (maquette v1). */
.fx-carte-danger {
    background: var(--fx-carte); border: 1px solid var(--et-danger-bord);
    border-radius: var(--fx-rayon); overflow: hidden; animation: fxUp .5s ease both;
}
.fx-carte-danger > .tete {
    display: flex; align-items: center; gap: 9px;
    padding: 11px 18px; background: var(--et-danger-badge-bg); border-bottom: 1px solid var(--et-danger-bord);
    font-size: 14px; font-weight: 600; color: var(--fx-err);
}
.fx-danger-ligne { display: flex; align-items: center; gap: 16px; padding: 16px 22px; }
.fx-danger-ligne + .fx-danger-ligne { border-top: 1px solid var(--et-danger-bord); }
.fx-danger-txt { flex: 1; min-width: 0; }
.fx-danger-titre { font-size: 14px; font-weight: 600; color: var(--fx-texte-2); }
.fx-danger-detail { margin-top: 3px; font-size: 13px; line-height: 1.5; color: var(--fx-discret); }

/* ---------------------------------------------------------------------------
   8. Modales du modèle (création, confirmation) — à poser dans <ModalCadre>
      avec StyleContenu="border:none;border-radius:0;overflow:hidden" pour
      neutraliser l'habillage Bootstrap de .modal-content.
   --------------------------------------------------------------------------- */
.fx-modale { font-family: 'IBM Plex Sans', system-ui, -apple-system, "Segoe UI", sans-serif; color: var(--fx-texte); }
.fx-modale-tete {
    display: flex; align-items: center; gap: 11px;
    padding: 16px 22px; background: var(--fx-bandeau); border-bottom: 3px solid var(--fx-orange);
}
.fx-modale-tete .ico {
    width: 30px; height: 30px; border-radius: 0; flex: none;
    background: var(--et-tint); color: var(--fx-marine); display: grid; place-items: center;
}
.fx-modale-tete h2 { margin: 0; flex: 1; min-width: 0; font-size: 18px; font-weight: 600; letter-spacing: -0.01em; }
.fx-modale-fermer {
    flex: none; width: 32px; height: 32px; display: grid; place-items: center;
    background: transparent; border: none; border-radius: 0; color: var(--fx-discret); cursor: pointer;
}
.fx-modale-fermer:hover { background: var(--fx-bandeau-bord); color: var(--fx-texte); }
/* Croix armée : la fermeture a été retenue une fois (saisie non enregistrée), le clic
   suivant fermera. Elle le DIT — sinon le bouton paraît inerte à qui n'a pas vu
   l'avertissement, et l'on cherche une sortie qui a l'air de ne pas exister. */
.fx-modale-fermer.est-alerte { background: var(--fx-attention-fond); color: var(--fx-attention); }
.fx-modale-fermer.est-alerte:hover { background: var(--fx-attention-bord); color: var(--fx-attention); }
.fx-modale-corps { padding: 20px 22px 16px; }
.fx-modale-corps .fx-label:not(:first-child) { margin-top: 14px; }
.fx-modale-pied {
    display: flex; align-items: center; justify-content: flex-end; gap: 9px;
    padding: 14px 22px; background: var(--fx-bandeau); border-top: 1px solid var(--fx-bandeau-bord);
}
.fx-succes { padding: 34px 26px 30px; text-align: center; animation: fxIn .3s ease both; }
.fx-succes-rond {
    width: 60px; height: 60px; border-radius: 50%; background: var(--fx-ok-fond);
    display: grid; place-items: center; margin: 0 auto 18px; color: var(--fx-ok);
}
.fx-succes-titre { font-size: 18px; font-weight: 700; letter-spacing: -0.02em; }
.fx-succes-txt { margin-top: 8px; font-size: 14px; line-height: 1.55; color: var(--et-muted); }

/* ---------------------------------------------------------------------------
   9. États de page (chargement, introuvable) + animations
   --------------------------------------------------------------------------- */
.fx-vide {
    background: var(--fx-carte); border: 1px solid var(--fx-carte-bord); border-radius: var(--fx-rayon);
    padding: 56px 24px; text-align: center; color: var(--fx-discret); font-size: 14px;
}

@keyframes fxUp   { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes fxIn   { from { opacity: 0; } to { opacity: 1; } }
@keyframes fxSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .fx-carte, .fx-cote, .fx-avis, .fx-encart, .fx-succes, .fx-sauvegarde { animation: none; }
}

/* ---------------------------------------------------------------------------
   10. Thème sombre — seuls les jetons changent, aucune règle n'est dupliquée.
   --------------------------------------------------------------------------- */
.appgrid[data-theme="dark"] .fx-page,
.appgrid[data-theme="dark"] .fx-modale {
    --fx-carte: var(--et-surface);
    --fx-carte-bord: #26324a;
    --fx-bandeau: var(--et-surface-2);
    --fx-bandeau-bord: #26324a;
    --fx-filet: #1c2740;

    --fx-texte: #e5edf5;
    --fx-texte-2: #c3cede;
    --fx-texte-3: #94a3b8;
    --fx-discret: #8a97ac;
    --fx-tres-discret: #7c8AA0;

    --fx-champ-bord: #2b3855;
    --fx-champ-fond: #0d1524;
    --fx-champ-fond-inactif: #131d31;

    --fx-err: #f4a49c;
    --fx-err-bord: rgba(248, 113, 113, .38);
    --fx-err-fond: rgba(248, 113, 113, .12);
    --fx-err-encre: var(--et-danger-ink);
    --fx-attention: #f0c078;
    --fx-attention-bord: rgba(244, 154, 71, .38);
    --fx-attention-fond: rgba(244, 154, 71, .12);
    /* En sombre les deux encres rejoignent leur couleur d'état : sur un fond
       obscurci, c'est la teinte vive qui redevient la plus lisible — même
       raisonnement que --fx-ok-encre. --fx-info et --fx-neutre n'ont pas de ligne
       ici : --et-info et --et-neutre basculent déjà d'eux-mêmes. */
    --fx-attention-encre: #f0c078;
    --fx-ok: #6ee7a0;
    --fx-ok-fond: rgba(74, 222, 128, .12);
    /* Le pendant sombre manquait AUSSI, et c'est là que ça se voyait : les deux
       règles ci-dessous gardaient #12734A en encre quel que soit le thème, soit
       2,96:1 sur --et-surface sombre — le seul des quatre encarts à ne pas
       basculer. En sombre l'encre rejoint --fx-ok (11,27:1) : sur un fond
       obscurci, le vert vif redevient le plus lisible des deux. */
    --fx-ok-bord: rgba(74, 222, 128, .38);
    --fx-ok-encre: var(--et-succes-ink);
}
.appgrid[data-theme="dark"] .fx-btn-neutre { color: var(--fx-texte-2); }
.appgrid[data-theme="dark"] .fx-btn-neutre:hover:enabled { background: #1b2740; border-color: #33415f; }
.appgrid[data-theme="dark"] .fx-carte-danger { border-color: rgba(248, 113, 113, .3); }
.appgrid[data-theme="dark"] .fx-carte-danger > .tete { background: rgba(248, 113, 113, .1); border-bottom-color: rgba(248, 113, 113, .24); }
.appgrid[data-theme="dark"] .fx-danger-ligne + .fx-danger-ligne { border-top-color: rgba(248, 113, 113, .24); }
.appgrid[data-theme="dark"] .fx-btn-danger-doux { border-color: rgba(248, 113, 113, .3); }
.appgrid[data-theme="dark"] .fx-btn-danger-doux:hover:enabled { background: rgba(248, 113, 113, .12); }
.appgrid[data-theme="dark"] .fx-modale-tete .ico { background: var(--et-info-bg); color: var(--et-info); }
.appgrid[data-theme="dark"] .fx-succes-txt { color: var(--fx-discret); }

/* ===========================================================================
   FICHE EN POPUP (.fx-modale-large)
   Le détail d'un terminal était une page ; il est désormais un formulaire en
   popup au-dessus de la liste. Ce bloc n'ajoute que ce que la popup demande en
   plus du modèle : un en-tête à deux lignes, un pli pour le lecture-seule, et
   les REPRISES DE COULEUR rendues nécessaires par le changement de fond.
   =========================================================================== */

/* Hauteur : la popup ne prend que ce qu'il lui faut, et plafonne à l'écran. */
.fx-modale-large { display: flex; flex-direction: column; max-height: calc(100vh - 3.5rem); }
.fx-modale-large > .fx-modale-corps { flex: 1; min-height: 0; overflow-y: auto; }

/* En-tête à deux lignes : titre + pastilles, puis le numéro de série. */
.fx-modale-titre { flex: 1; min-width: 0; }
.fx-modale-titre .ligne { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.fx-modale-tete .fx-modale-titre h2 { flex: 0 1 auto; }
.fx-modale-titre .sous { margin-top: 2px; font-size: 12px; color: var(--fx-discret); }
.fx-modale-titre .sous.mono { font-family: var(--fx-mono); letter-spacing: .03em; }

/* PASTILLES D'ÉTAT SUR FOND CLAIR.
   Les .fx-etat de base sont dessinées pour le bandeau marine : encre claire sur
   aplat teinté. Reprises telles quelles dans un en-tête de modale, elles
   donneraient du --et-sur-marine-succes sur #F4F7FC — invisible. Même sens,
   mêmes familles de couleur, valeurs inversées.

   LES DEUX MOITIÉS SONT DÉSORMAIS NOMMÉES, ET DANS DEUX FAMILLES DISTINCTES :
   --fx-*-fond / --fx-*-encre ici (fond pâle, encre foncée), et
   --et-fond-marine-* / --et-sur-marine-* là-haut (aplat teinté, encre claire).
   Le commentaire ci-dessus décrivait cette inversion depuis toujours ; il n'y
   avait qu'un seul jeu de valeurs écrit, et l'autre en dur. */
.fx-modale-tete .fx-etat                  { background: var(--fx-neutre-fond);    color: var(--fx-neutre); }
.fx-modale-tete .fx-etat.est-ok           { background: var(--fx-ok-fond);        color: var(--fx-ok-encre); }
.fx-modale-tete .fx-etat.est-attente      { background: var(--fx-attention-fond); color: var(--fx-attention-encre); }
.fx-modale-tete .fx-etat.est-bloque       { background: var(--fx-err-fond);       color: var(--fx-err-encre); }
.fx-modale-tete .fx-etat.est-maintenance  { background: var(--fx-info-fond);      color: var(--fx-info); }
.fx-modale-tete .fx-etat.est-neutre       { background: var(--fx-neutre-fond);    color: var(--fx-neutre); }

/* La grille du formulaire porte son propre espacement ; la règle générique des
   labels de modale s'y ajouterait et décalerait une colonne sur deux. */
.fx-modale-corps .fx-grille .fx-label:not(:first-child) { margin-top: 0; }

/* Pied : le texte d'état occupe la gauche, les boutons restent à droite. */
.fx-modale-pied .fx-pied-txt { flex: 1; min-width: 150px; text-align: left; font-size: 13px; color: var(--fx-discret); }
.fx-modale-pied.est-alerte { background: var(--fx-attention-fond); border-top-color: var(--fx-attention-bord); }
.fx-modale-pied .fx-pied-txt.est-alerte {
    display: flex; align-items: center; gap: 8px;
    color: var(--fx-attention); font-weight: 600;
}

/* ----- Le pli : ce que le terminal renseigne lui-même ----- */
.fx-pli { margin-top: 20px; border: 1px solid var(--fx-carte-bord); border-radius: var(--fx-rayon-btn); background: var(--fx-bandeau); }
.fx-pli > summary { display: flex; align-items: center; gap: 9px; padding: 11px 14px; cursor: pointer; list-style: none; }
.fx-pli > summary::-webkit-details-marker { display: none; }
.fx-pli[open] > summary { border-bottom: 1px solid var(--fx-carte-bord); }
.fx-pli-fleche { font-size: 12px; color: var(--fx-discret); transition: transform .15s ease; }
.fx-pli[open] .fx-pli-fleche { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .fx-pli-fleche { transition: none; } }
.fx-pli-titre { font-size: 13px; font-weight: 600; color: var(--fx-texte-2); }
.fx-pli-note { margin-left: auto; font-size: 12px; color: var(--fx-tres-discret); }
.fx-pli-corps { padding: 14px; background: var(--fx-carte); border-radius: 0 0 var(--fx-rayon-btn) var(--fx-rayon-btn); }
.fx-pli-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); gap: 4px 26px; margin-top: 14px; }
.fx-pli-sect {
    font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    color: var(--fx-marine); padding-bottom: 6px; border-bottom: 2px solid var(--et-tint);
}

/* JAUGES SUR FOND CLAIR — même motif que les pastilles : les jauges d'origine
   vivent sur la carte marine et sont donc écrites en blanc. */
.fx-jauges.est-claires { margin-top: 12px; gap: 11px; }
.fx-jauges.est-claires .fx-jauge-lbl { color: var(--fx-texte-3); }
.fx-jauges.est-claires .fx-jauge-val { color: var(--fx-texte); }
.fx-jauges.est-claires .fx-jauge-piste { background: var(--et-hairline); }
.fx-jauges.est-claires .fx-jauge-barre { background: var(--et-succes); }
.fx-jauges.est-claires .fx-jauge-barre.est-chargee { background: var(--fx-orange); }

/* Thème sombre : les valeurs ci-dessus sont en dur (elles répondent à un fond
   clair précis), il faut donc les redire ici — les jetons ne suffisent pas. */
/* PAS DE BLOC SOMBRE POUR CES PASTILLES : les cinq jetons --fx-* basculent
   d'eux-mêmes. Il y en avait un, cinq règles, qui redisait à la main ce que la
   famille fait déjà — et qui figeait les deux moitiés séparément. */
.appgrid[data-theme="dark"] .fx-pli-sect { color: var(--et-form-blue-encre); border-bottom-color: var(--et-hairline); }
.appgrid[data-theme="dark"] .fx-jauges.est-claires .fx-jauge-piste { background: var(--et-hairline); }

/* Numéro de série cliquable dans une liste : c'est un <button> et non un <a>, car il
   ouvre une popup et ne mène nulle part — un lien annoncerait une navigation qui
   n'a pas lieu, et proposerait un « ouvrir dans un nouvel onglet » sans effet. Il
   garde donc l'apparence d'un lien, mais pas sa nature. */
.lien-sn {
    padding: 0; border: none; background: none; font: inherit; color: var(--fx-marine);
    cursor: pointer; text-align: left; text-decoration: none;
}
.lien-sn:hover { text-decoration: underline; }
.lien-sn:focus-visible { outline: 2px solid var(--fx-orange); outline-offset: 2px; }
.appgrid[data-theme="dark"] .lien-sn { color: var(--et-form-blue-encre); }

/* --- Onglets de fiche — patron de la maquette « Fiche employé » (export 7) -----
   Ils remplacent le pli qui logeait les informations en lecture seule. Un pli se lit
   comme un complément facultatif ; un onglet dit qu'il y a deux faces à la fiche. */
.fx-onglets {
    display: flex; gap: 2px; padding: 0 14px; flex-wrap: wrap;
    background: var(--et-surface-2); border-bottom: 1px solid var(--et-hairline);
}
/* « Un onglet inactif porte un soulignement TRANSPARENT de même épaisseur que
   l'actif : la hauteur ne bouge pas au changement d'onglet. » C'était déjà le cas
   ici ; ce qui change, c'est l'épaisseur (3 px, la valeur de la passation) et la
   couleur — bleu, jamais orange : un onglet ouvert n'engage rien, il montre. */
.fx-onglet {
    display: inline-flex; align-items: center; gap: 8px; flex: none;
    height: 40px; padding: 0 14px; border: none; background: transparent;
    font-family: inherit; font-size: 14px; font-weight: 500; color: var(--et-ink);
    cursor: pointer; border-bottom: 3px solid transparent; margin-bottom: -1px;
}
.fx-onglet:hover { background: var(--et-rang); }
.fx-onglet.est-actif {
    font-weight: 700; color: var(--et-form-blue-encre); border-bottom-color: var(--et-form-blue);
}
.appgrid[data-theme="dark"] .fx-onglet.est-actif { color: var(--et-form-blue-encre); }
/* Compteur d'ÉLÉMENTS porté par un onglet (« Documents 4 »). Il dit ce que
   l'onglet contient sans qu'on l'ouvre. Le compteur d'ERREURS est un autre objet,
   rouge, et il prime : .fe-onglet-err, plus bas — une erreur se voit avant un
   décompte. Les avoir tous deux en rouge revenait à annoncer quatre problèmes là
   où il y a quatre pièces jointes. */
.fx-onglet-compte {
    display: grid; place-items: center; height: 18px; min-width: 18px; padding: 0 5px;
    border-radius: var(--et-r-pill); background: var(--et-tint); color: var(--et-form-blue-d);
    font-family: var(--fx-mono); font-size: 12px; font-weight: 500;
}
.fx-onglet-note {
    margin-bottom: 14px; padding: 9px 13px; font-size: 13px;
    color: var(--fx-texte-3); background: var(--fx-bandeau);
    border: 1px solid var(--fx-carte-bord); border-radius: var(--fx-rayon-btn);
}
/* En onglet, le corps n'a plus besoin du cadre ni du fond du pli. */
.fx-pli-corps.est-onglet { padding: 0; background: transparent; border-radius: 0; }

/* --- .est-a-onglets A ÉTÉ RETIRÉ ICI (2026-09-03) ---------------------------
   Quatorze règles pour fiche à onglets en popup — une de hauteur, treize de
   compactage — plus le jeton --fx-h-onglets. Posées par #801 (5300e5b, 2026-08-27), elles n'ont
   JAMAIS été branchées : `git log -S "est-a-onglets" -- Components` ne rend rien.

   Ce n'était pas un oubli de câblage à rattraper — LES DEUX ÉCRANS QUE LE
   COMMENTAIRE NOMMAIT ONT MIGRÉ AILLEURS :
     - la fiche terminal (« le terminal demande 706 px ») est passée à ModalCadre ;
     - la fiche employé (« l'employé 742 ») n'a plus de popup à onglets ;
     - la seule popup à onglets qui reste, ModelePaieFiche, emploie RailOnglets et
       le gabarit .mx-*, que ces règles ne décrivent pas — elles compactent le
       balisage hérité .fx-onglet / .fx-grille / .fx-def / .fx-pli-*.

   Les hauteurs 706 et 742 étaient des MESURES, et c'est pourquoi le lot précédent
   avait refusé de les effacer. Elles mesuraient un agencement qui n'existe plus
   sous cette forme : les garder revenait à faire lire comme vivant un dispositif
   qui ne s'applique à rien. Elles restent lisibles d'un `git show 5300e5b`.

   SI UNE POPUP À ONGLETS REDEMANDE UNE HAUTEUR STABLE, c'est du gabarit .mx-*
   qu'il faudra partir, et la mesure sera à refaire sur son propre contenu. */


/* Compteurs de données enrôlées (empreintes, paume, visage) : une valeur relevée sur
   les terminaux, pas un champ de saisie. Un <input readonly> l'aurait fait passer pour
   modifiable — ici, ce qui se lit se distingue de ce qui s'écrit. */
.fx-grille-bio { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.fx-bio {
    display: flex; align-items: center; gap: 10px; padding: 8px 11px;
    border: 1px solid var(--fx-carte-bord); background: var(--fx-bandeau);
}
.fx-bio-lbl { flex: 1; font-size: 13px; color: var(--fx-texte-2); }
.fx-bio-lbl em { font-style: normal; color: var(--fx-tres-discret); }
.fx-bio-n { font-size: 15px; font-weight: 700; color: var(--fx-texte); font-variant-numeric: tabular-nums; }

/* Photo du salarié : l'aperçu à côté du champ, et non le champ seul. Sans l'image,
   rien ne dit si l'adresse saisie pointe sur la bonne personne — ni même sur une
   image. Le cadre en pointillés se lit comme un emplacement à remplir. */
.fx-photo { display: flex; align-items: flex-end; gap: 14px; }
.fx-photo-box {
    flex: none; width: 64px; height: 64px; overflow: hidden;
    border: 1.5px dashed var(--fx-champ-bord); background: var(--fx-bandeau);
    display: grid; place-items: center; color: var(--fx-tres-discret); font-size: 24px;
}
.fx-photo-box img { width: 100%; height: 100%; object-fit: cover; }
.fx-photo-champ { flex: 1; min-width: 0; }

/* ===========================================================================
   FICHE EMPLOYÉ PLEINE LARGEUR — design final.

   La grille « contenu + 330 px » vient de la maquette. Elle repasse sur une
   colonne sous 1180 px : à cette largeur, le contenu tomberait sous 600 px et
   ses deux colonnes de champs se serreraient au point d'être illisibles.
   =========================================================================== */
.fe-page { max-width: 1400px; }

.fe-entete { display: flex; align-items: flex-start; gap: 12px; margin: 10px 0 16px; flex-wrap: wrap; }
/* La pastille marine à icône disparaît du dessin de la passation : la place de
   gauche revient à la VIGNETTE PHOTO de la personne, qui identifie mieux qu'un
   pictogramme identique sur les huit cents fiches. Elle reste définie — d'autres
   fiches (terminal, article) n'ont pas de photo et s'en servent encore — mais à
   plat et dans les teintes de la charte. */
.fe-ico {
    flex: none; width: 34px; height: 34px; display: grid; place-items: center;
    background: var(--et-tint); color: var(--et-form-blue-encre); border-radius: 0; font-size: 15px;
}
.fe-entete-txt { flex: 1; min-width: 0; }
.fe-entete-ligne { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.fe-entete-ligne h1 { margin: 0; font-size: 23px; font-weight: 700; letter-spacing: -.02em; color: var(--fx-texte); }
.fe-sous { margin-top: 3px; font-size: 13px; color: var(--fx-texte-3); }
/* Sous-titre TECHNIQUE — un numéro de série, un matricule. La mono n'est pas un
   ornement : elle donne aux caractères la même chasse, et c'est ce qui permet de
   comparer un SN à celui gravé sur l'appareil sans se tromper de caractère. */
.fe-sous.mono { font-family: var(--fx-mono); letter-spacing: .03em; }
.fe-entete-actions { display: flex; align-items: center; gap: 9px; flex: none; }
.fe-sauvegarde { font-size: 13px; color: var(--fx-ok); }

/* L'en-tête vit sur le fond de page : les pastilles d'état doivent donc être
   celles du FOND CLAIR, non celles du bandeau marine. */
.fe-entete .fx-etat                 { background: var(--fx-neutre-fond); color: var(--fx-neutre); }
.fe-entete .fx-etat.est-ok          { background: var(--fx-ok-fond); color: var(--fx-ok-encre); }
.fe-entete .fx-etat.est-attente     { background: var(--fx-attention-fond); color: var(--fx-attention-encre); }
.fe-entete .fx-etat.est-neutre      { background: var(--fx-neutre-fond); color: var(--fx-neutre); }
/* Les deux qui manquaient : posées sur le bandeau marine, elles gardaient un texte
   presque blanc sur un fond translucide — invisible sur le fond clair d'un en-tête
   de page. « Édition » sur la fiche salarié en faisait déjà les frais. */
.fe-entete .fx-etat.est-bloque      { background: var(--fx-err-fond); color: var(--fx-err-encre); }
.fe-entete .fx-etat.est-maintenance { background: var(--fx-info-fond); color: var(--fx-info); }

/* PASTILLE DE PROFIL — rend le périmètre du rail lisible sans compter les
   onglets : « pointage » (trois onglets) ou « paie-RH » (les vingt). Mono
   capitales, à la différence des .fx-etat voisines — ce n'est pas un état de
   la fiche (actif, en édition…), c'est ce que la société a souscrit. */
.fe-profil-pastille {
    display: inline-flex; align-items: center;
    padding: 3px 9px; border-radius: 999px;
    background: var(--et-tint); color: var(--et-form-blue-d);
    font-family: var(--et-font-mono); font-size: 12px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .08em;
}

/* La note du gabarit, en AMBRE. Modificateur de couleur seulement : la géométrie
   reste celle de .mx-note, et la recopier ici aurait fait diverger les deux au
   premier ajustement du gabarit. Sert les avertissements que le serveur rend avec
   la structure de paie — ce sont des constats, pas des erreurs de saisie.
   PAS « .fe-alerte » : ce nom est pris par le BLOC d'alerte contractuelle plus bas
   (fond, bordure, encre), qui l'emporterait par sa position et ferait de cette
   ligne une bande. */
.mx-note.fe-note-ambre { color: var(--et-avertissement-ink); }

/* ABSORPTION DU DOSSIER SALARIÉ — trois formes que la fiche n'avait pas encore.

   Elles servent les onglets de paie devenus saisissables : l'action posée dans
   l'en-tête d'un groupe, les boutons de ligne d'une table de collection, et une
   rangée de cases qui répondent à une même question. */

/* L'ACTION DANS L'EN-TÊTE DE GROUPE. « Ajouter un enfant » appartient au groupe
   « Enfants », pas au pied de la fiche : posé en bas, il aurait fallu redescendre
   après chaque ajout. C'est un lien et non un .mx-btn — il ouvre une saisie, il
   n'engage rien, et un bouton plein le ferait lire aussi fort qu'« Enregistrer ». */
.fe-lien-groupe {
    margin-left: auto; border: 0; background: transparent; padding: 0;
    display: inline-flex; align-items: center; gap: 5px;
    color: var(--et-form-blue-encre); font-family: inherit; font-size: 12px; font-weight: 600;
    cursor: pointer;
}
.fe-lien-groupe:hover { color: var(--et-form-blue-d); text-decoration: underline; }

/* BOUTONS DE LIGNE d'une table de collection : le carré du gabarit ramené à la
   hauteur d'une rangée. Sans cela, un .mx-btn de 42 px doublerait la hauteur des
   lignes qu'il accompagne. */
.fe-btn-mini { width: 26px; height: 26px; padding: 0; font-size: 12px; }
.fe-btn-mini + .fe-btn-mini { margin-left: 4px; }

/* Plusieurs cases sur une rangée : elles répondent à une même question — « quel
   statut ? » — et une rangée par case aurait allongé la modale d'autant. */
.fe-cases { display: flex; flex-wrap: wrap; gap: 6px 22px; padding-top: 6px; }

@media (max-width: 1024px) {
    /* Règle tactile (lot 02) : sous 1024 px, aucune cible ne descend sous 44 px. */
    .fe-btn-mini { width: 44px; height: 44px; font-size: 13px; }
    .fe-lien-groupe { min-height: 44px; }
}

/* PARTS FISCALES — le champ et son bouton de recalcul, sur une rangée.
   Le bouton n'est PAS un suffixe d'unité (.mx-input-suffixe) : celui-là est une
   note posée dans le champ et ne se clique pas, celui-ci agit. Il garde donc sa
   boîte, à côté, et la rangée les tient à la hauteur l'un de l'autre. */
.fe-parts { display: flex; align-items: center; gap: 8px; }
.fe-parts > .mx-btn { flex: none; width: 34px; height: 34px; padding: 0; }
@media (max-width: 1024px) {
    /* Règle tactile (lot 02) : sous 1024 px, aucune cible ne descend sous 44 px. */
    .fe-parts > .mx-btn { width: 44px; height: 44px; }
}

.fe-grille { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 16px; align-items: start; }
.fe-grille.est-seule { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 1180px) { .fe-grille { grid-template-columns: minmax(0, 1fr); } }

.fe-principal { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.fe-cote { display: flex; flex-direction: column; gap: 14px; }

.fe-carte {
    background: var(--fx-carte); border: 1px solid var(--fx-carte-bord);
    border-radius: var(--fx-rayon); padding: 16px 18px 18px;
}
/* Le bloc de départ est un CONSTAT, pas une saisie : l'ambre le distingue des
   sections modifiables sans crier à l'erreur. */
.fe-carte-depart { background: var(--fx-attention-fond); border-color: var(--fx-attention-bord); }

.fe-cote-titre {
    display: flex; align-items: baseline; gap: 8px;
    font-size: 13px; font-weight: 700; color: var(--fx-texte);
    padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid var(--fx-filet);
}
/* .fe-cote-note, .fe-cote-vide, .fe-cote-lien, .fe-photo-zone ET .fe-photo-grande
   NE SONT PAS ICI. La correction du 2026-08-27 en avait retiré deux — « la colonne
   de côté a été refondue plus bas (section “fiche salarié — colonne de droite”), et
   ses deux dernières classes y sont redéclarées. Les garder ici les faisait vivre en
   double dans le MÊME fichier, à trois cent soixante-douze lignes d'écart. »

   Le motif valait pour huit autres, restées en place ; elles partent le 2026-09-03.
   Chacune était ENTIÈREMENT masquée — toutes ses propriétés redéclarées plus bas,
   sans !important nulle part, et hors de tout @media : le second bloc gagnait sur
   chaque déclaration, à sélecteur identique donc à spécificité égale. */

.fe-photo-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px;
                font-size: 13px; color: var(--fx-texte-3); }

/* Pointages récents : le point coloré porte le SENS, et la couleur suffit à le
   lire en balayant — l'entrée en vert, la sortie en bleu, comme ailleurs. */
.fe-pointages { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
/* .fe-pointages li, .fe-pt.est-entree, .fe-pt.est-sortie, .fe-pt-h, .fe-pt-ou et
   .fe-def-liste .fx-def sont redéclarées dans le bloc du restylage, plus bas, et
   partent d'ici. Le commentaire ci-dessus décrivait d'ailleurs un rendu qui n'avait
   plus lieu : « la sortie en bleu » — la version vivante la peint en MARINE.

   .fe-pt RESTE, et c'est la seule de la famille : son margin-top: 5px n'est PAS
   redéclaré plus bas, et positionne la pastille. Une règle partiellement masquée
   n'est pas une règle morte. */
.fe-pt { flex: none; width: 8px; height: 8px; border-radius: 50%; margin-top: 5px; }

/* ---- Fiche employé : compléments du restylage ------------------------------
   La consultation n'affiche pas des champs désactivés mais la valeur elle-même :
   un formulaire grisé se lit mal et suggère à tort qu'on pourrait le déverrouiller
   sur place. La hauteur reste celle d'un champ (42 px) pour que la bascule vers
   l'édition ne fasse pas sauter la page. */
/* AUCUN FILET SOUS UNE VALEUR (2026-08-17). « Aucun filet entre les rangées :
   seuls les en-têtes de groupe en portent. » Un filet par valeur transformait la
   consultation en grille de tableur, et donnait à lire quarante séparateurs pour
   quarante données. La hauteur suit celle du champ de saisie (34 px) : la bascule
   consultation / édition ne fait toujours pas sauter la page. */
.fe-valeur {
    min-height: 34px;
    display: flex;
    align-items: center;
    padding: 0 2px;
    font-size: 13px; font-weight: 500;
    color: var(--et-ink);
}
/* Les valeurs techniques — matricule, dates, heures, montants — en mono. */
.fe-valeur.mono { font-family: var(--fx-mono); font-size: 14px; }

.fe-initiales {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-size: 2.4rem;
    font-weight: 700;
    color: var(--et-form-blue-encre);
    background: var(--et-tint);
}

/* Détail des modèles biométriques : sa largeur ne doit jamais pousser la page. */
.fe-bio-detail { margin-top: 12px; overflow-x: auto; }
/* .fe-bio-detail .tbl est redéclarée plus bas avec sa bordure ; elle part d'ici. */

/* ---- Combo à sélection multiple (ComboMulti) --------------------------------
   Même gabarit qu'un champ du modèle de fiche : 42 px, coins droits, chevron à
   droite. Le panneau se superpose au lieu de pousser le formulaire — c'est tout
   l'intérêt par rapport à une liste de cases dépliée. */
.cbm { position: relative; }

.cbm-champ {
    display: flex; align-items: center; gap: 8px;
    width: 100%; height: 42px; padding: 0 10px;
    border: 1px solid var(--fx-carte-bord);
    background: var(--et-surface); font-family: inherit; font-size: 14px;
    color: var(--et-ink); text-align: left; cursor: pointer;
}
.cbm-champ:hover { border-color: var(--et-info-bord); }
.cbm-champ.est-ouvert { border-color: var(--et-form-blue); }
.cbm-txt { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cbm-txt.est-vide { color: var(--et-inerte); }
.cbm-compte {
    flex: none; min-width: 20px; height: 19px; padding: 0 6px;
    display: grid; place-items: center;
    background: var(--et-surface-2); color: var(--et-form-blue);
    font-size: 12px; font-weight: 600;
}
.cbm-chevron { flex: none; color: var(--et-inerte); font-size: 12px; }

/* Le voile ferme le panneau au clic extérieur sans passer par JavaScript. */
.cbm-voile { position: fixed; inset: 0; z-index: 40; background: transparent; }

.cbm-panneau {
    position: absolute; z-index: 41; top: calc(100% + 2px); left: 0; right: 0;
    background: var(--et-surface); border: 1px solid var(--fx-carte-bord);
    box-shadow: var(--et-ombre-menu);
}
.cbm-barre {
    display: flex; gap: 14px; padding: 7px 11px;
    border-bottom: 1px solid var(--et-hairline);
    background: var(--et-surface-2);
}
.cbm-lien {
    border: none; background: none; padding: 0; font-family: inherit;
    font-size: 12px; color: var(--et-form-blue); cursor: pointer;
}
.cbm-lien:hover { text-decoration: underline; }

.cbm-liste { max-height: 240px; overflow-y: auto; }
.cbm-ligne {
    display: flex; align-items: center; gap: 9px; margin: 0;
    padding: 7px 11px; font-size: 13px; cursor: pointer;
}
.cbm-ligne:hover { background: var(--et-surface-3); }
.cbm-ligne input { width: 17px; height: 17px; border-radius: 0; accent-color: var(--et-form-blue); flex: none; }
.cbm-ligne span { flex: 1; }
.cbm-ligne em {
    font-style: normal; font-size: 12px;
    color: var(--et-muted); font-family: var(--et-font-mono);
}
.cbm-vide { padding: 12px; font-size: 13px; color: var(--et-muted); }

/* Consultation : plus de champ cliquable, seulement la valeur — même traitement
   que les autres champs de la fiche en lecture, .fe-valeur, dont il reprend les
   mesures (34 px, 13 px, sans filet de rangée) depuis la passation « Design 7 ». */
.cbm-lecture {
    min-height: 34px; display: flex; align-items: center; padding: 0 2px;
    font-size: 13px; font-weight: 500; color: var(--et-ink);
}

/* ---- Pied de fiche ----------------------------------------------------------
   2026-08-17, passation « Design 7 » : « Le pied de carte ne porte PAS d'action,
   seulement la mention explicative. » Les boutons sont remontés dans la barre
   d'outils de l'en-tête d'objet (.fe-entete-actions).

   Ce que la barre collante réglait — « le bouton ne doit pas se dérober quand on
   change d'onglet » — l'en-tête le règle mieux : elle ne se dérobe pas davantage,
   elle ne recouvre pas le bas du formulaire, et elle reste au même endroit qu'il y
   ait deux champs ou quarante. La position sticky, elle, coûtait une bande blanche
   permanente en travers de la fiche, sur un écran où la place verticale est
   précisément ce qui manque.
   Le pied cesse donc d'être une barre : c'est un pied de carte en fond alterné,
   qui dit ce que la fiche fait — d'où le gris atténué. */
.fe-pied {
    margin-top: 14px; padding: 10px 16px;
    background: var(--et-surface-3);
    border: 1px solid var(--et-hairline);
    font-size: 13px; line-height: 1.5; color: var(--et-faint);
}
.fe-pied-mention { max-width: 88ch; }

/* La bande de faits saillants se colle sous l'en-tête d'objet — c'est le même
   ensemble — et laisse une gouttière avant le contenu. */
.fe-page .mx-faits { margin-bottom: 14px; }

/* Barre d'outils de la page objet — à droite de l'identité, alignée en bas de la
   ligne de titre : centrée verticalement sur un en-tête à deux lignes, elle
   flottait au milieu de nulle part. */
.fe-entete-actions {
    margin-left: auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    justify-content: flex-end;
}
.fe-entete-etat {
    display: flex; align-items: center; gap: 7px;
    font-size: 12px; color: var(--et-muted);
}

@media (max-width: 720px) {
    .fe-entete-actions { margin-left: 0; width: 100%; justify-content: flex-start; }
}

/* ---- Fiche employé : alignement du pied et hauteur constante ---------------
   RMQ1 — le pied était posé hors de la grille : il faisait 1400 px quand le
   formulaire en fait 1054, et débordait sous la colonne latérale. Il devient
   un élément de grille cantonné à la première colonne, donc exactement aussi
   large que le formulaire qu'il conclut. */
.fe-pied { grid-column: 1; }

/* RMQ2 — hauteur identique d'un onglet à l'autre, calée sur le plus haut.
   Sans cela le pied remonte et redescend à chaque changement d'onglet, et le
   bouton Enregistrer se dérobe sous le curseur.

   C'est bien min-height et non height : un salarié avec beaucoup de modèles
   biométriques doit pouvoir dépasser plutôt que se faire rogner. Le jeton
   permet d'ajuster sans rouvrir la feuille. */
/* .fe-panneaux / .fe-panneau : RETIRÉS le 2026-08-17 (passation « Design 9 »).
   La superposition des panneaux est désormais portée par le gabarit — .mx-panneaux
   / .mx-panneau de modele-erp.css, servis par Components/Shared/RailOnglets.razor —
   et la fiche employé, seule consommatrice de ces deux règles, est passée dessus.
   Même technique, même raison (la hauteur suit le panneau le plus haut) ; elle vaut
   maintenant pour toutes les fiches au lieu d'une seule.
   Un écart tout de même : le gabarit masque en display:none, ces règles-ci
   laissaient les panneaux inactifs en visibility:hidden — donc présents dans le
   parcours au clavier et lus par les lecteurs d'écran, quatre onglets fermés
   compris. */

/* ---- Lien de téléversement de la photo ------------------------------------ */
.fe-photo-lien {
    display: inline-flex; align-items: center; gap: 7px; margin-top: 10px;
    padding: 7px 12px; border: 1px solid var(--fx-carte-bord); background: var(--et-surface);
    font-size: 13px; color: var(--fx-bleu); cursor: pointer;
}
.fe-photo-lien:hover { border-color: var(--fx-bleu); background: var(--fx-bandeau); }
/* Le champ natif est masqué : c'est le libellé qui sert de bouton. */
.fe-photo-lien input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }

/* ---- Tableau des modèles biométriques -------------------------------------
   Reprend les choix de charte déjà arrêtés : en-tête bleu clair #E8EFFA et
   lignes de 31 px, comme les listes du reste de l'application. */
/* 2026-08-15 : l'en-tête suit les jetons au lieu de recopier la charte. Le bleu clair
   était écrit en dur ICI aussi, si bien que la bascule des tableaux à l'anthracite
   l'aurait laissé seul de son ancienne couleur — exactement ce que le commentaire
   ci-dessus voulait éviter en s'alignant sur « le reste de l'application ». Écrit en
   jetons, l'alignement tient tout seul à la prochaine bascule.
   Les valeurs de repli couvrent le cas où ce tableau ne serait pas dans un .tbl-cadre,
   qui porte les jetons ; c'est aussi la convention du reste du fichier (--et-hairline,
   --fx-marine). À savoir : cette règle n'a AUCUN markup à ce jour — la fiche employé
   rend les modèles en liste (.fe-bio-liste), pas en tableau. Elle est conservée telle
   quelle, mais si le tableau revient il naîtra à la bonne couleur. */
.fe-bio-detail .tbl { font-size: 13px; border: 1px solid var(--et-hairline); }
.fe-bio-detail .tbl thead th {
    height: 31px; padding: 0 10px;
    background: var(--tbl-tete-fond); color: var(--tbl-tete-encre);
    font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
    white-space: nowrap;
}
.fe-bio-detail .tbl tbody td {
    height: 31px; padding: 0 10px;
    border-bottom: 1px solid var(--et-hairline); white-space: nowrap;
}
.fe-bio-detail .tbl tbody tr:last-child td { border-bottom: none; }
.fe-bio-detail .tbl tbody tr:hover { background: var(--row-hover); }

/* ---- En-tête de fiche : une carte, pas un texte flottant -------------------
   Posé à même le fond de page, l'en-tête se confondait avec le layout : rien ne
   disait où commençait le formulaire. Il devient une carte à part entière, avec
   le filet orange de la maquette qui l'ancre visuellement au bloc qu'il ouvre. */
/* 2026-08-17, passation « Design 7 » : l'en-tête de fiche devient l'EN-TÊTE DE PAGE
   OBJET — fond #F5F6F7, filet INFÉRIEUR de 3 px bleu. Trois changements, trois
   raisons :
     - le fond recule au lieu d'être blanc : la seule surface blanche de l'écran
       reste celle où l'on saisit, ce qui suffit à dire où commence le formulaire
       (c'était le problème que le filet orange corrigeait de biais) ;
     - le filet passe EN BAS : il ferme l'identité et ouvre le contenu, dans le sens
       de la lecture. En haut, il séparait l'en-tête du fil d'Ariane, qui n'en avait
       pas besoin ;
     - il devient bleu : un filet orange large de toute la page aurait été le second
       orange de l'écran, et la passation n'en autorise qu'un. */
.fe-entete {
    background: var(--et-surface-2);
    border: 0; border-bottom: 3px solid var(--et-form-strip);
    border-radius: 0;
    padding: 12px 18px;
    margin: 10px 0 0;
    align-items: flex-start;
}
/* Le nom de l'objet est à 19 px, pas au 23 px du titre de page : le titre de page
   dit de quel écran il s'agit, le nom dit quel objet y est ouvert. Les mettre à la
   même taille faisait lire deux titres concurrents. */
.fe-entete-ligne h1 { font-size: 20px; }
/* Le matricule est une valeur technique : mono, comme partout ailleurs. */
.fe-sous { font-family: var(--fx-mono); font-size: 13px; color: var(--et-muted); }
/* Le bloc suivant se colle à l'en-tête : ils ne forment qu'un seul ensemble. */
.fe-grille { margin-top: 0; }
.fe-entete + .fx-encart { margin-top: 14px; }

/* Les sections d'un même onglet partagent une carte : seul un espacement les
   sépare, plus un trait ni une bordure. */
.fe-carte .fx-section:not(:first-child) { margin-top: 22px; }

/* ---- Alertes contractuelles ------------------------------------------------
   Bandeau sous l'en-tête, une ligne par constat, empilées. Les trois gravités
   viennent de la passation de design. Chaque ligne porte l'action qui la résout :
   une alerte qui se contente de constater fait perdre du temps. */
.fe-alertes { display: flex; flex-direction: column; margin: 0 0 14px; }
.fe-alerte {
    display: flex; align-items: center; gap: 11px;
    padding: 11px 18px; border: 1px solid transparent; border-bottom-width: 1px;
    font-size: 13px; line-height: 1.5;
}
.fe-alerte + .fe-alerte { border-top: none; }
.fe-alerte-txt { flex: 1; min-width: 0; }
.fe-alerte-btn {
    flex: none; height: 32px; padding: 0 12px; white-space: nowrap;
    background: var(--et-surface); border: 1px solid currentColor; border-radius: var(--et-r-btn);
    font-family: inherit; font-size: 13px; font-weight: 600; color: inherit; cursor: pointer;
}
.fe-alerte-btn:hover { filter: brightness(.96); }

/* Les trois gravités passent aux paires sémantiques de Fiori (2026-08-17) : une
   alerte de fiche et la pastille d'état qu'elle commente portent désormais la même
   couleur, au lieu de deux rouges et deux ambres voisins. */
.fe-alerte.est-rouge { background: var(--et-danger-badge-bg); border-color: var(--et-danger-bord); color: var(--et-danger-ink); }
.fe-alerte.est-ambre { background: var(--et-avertissement-bg); border-color: var(--et-avertissement-bord); color: var(--et-avertissement-ink); }
.fe-alerte.est-bleu  { background: var(--et-tint); border-color: var(--et-form-border); color: var(--et-form-blue-d); }

/* Pastille rouge du nombre d'erreurs portées par un onglet. Elle prime sur le
   compteur bleu : une erreur se voit avant un décompte. */
.fe-onglet-err {
    min-width: 17px; padding: 1px 5px; border-radius: var(--et-r-pill);
    background: var(--et-danger); color: var(--et-sur-aplat);
    font-family: var(--fx-mono); font-size: 12px; font-weight: 500;
    text-align: center;
}

/* ---- Colonne latérale : gabarit de carte de la passation -------------------
   Les trois cartes partagent un même dessin : bandeau de titre bleu pâle, corps
   blanc, rayon de 10 px — plus serré que les 14 px des cartes de formulaire, la
   colonne étant étroite. Le titre passe donc du texte au bandeau. */
.fe-cote .fe-carte { padding: 0; overflow: hidden; border-radius: 0; }

.fe-cote .fe-cote-titre {
    display: flex; align-items: center; gap: 9px;
    margin: 0; padding: 11px 18px;
    background: var(--et-surface-2); border-bottom: 1px solid var(--et-hairline);
    font-family: var(--fx-mono); font-size: 12px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .16em; color: var(--et-table-head-encre);
}
.fe-cote-note {
    margin-left: auto; font-family: var(--fx-mono);
    font-size: 12px; font-weight: 500; text-transform: uppercase;
    letter-spacing: .14em; color: var(--et-faint);
}

.fe-photo-zone { padding: 18px; display: flex; flex-wrap: wrap; gap: 15px; align-items: flex-start; }
/* La vignette EST une colonne : la photo, et immediatement dessous le bouton de
   televersement. Le bouton était un troisieme element de la rangee, donc rejeté
   a droite du texte d'etat, a l'autre bout de la carte que la vignette qu'il
   remplace. La colonne garde la largeur de la vignette pour que le bouton
   s'aligne exactement sous elle. */
.fe-photo-vignette { flex: none; width: 104px; display: flex; flex-direction: column; gap: 8px; }
.fe-photo-grande {
    position: relative;   /* ancre le lien de téléchargement, posé en overlay plein cadre */
    flex: none; width: 100%; height: 126px; border-radius: 0;
    background: var(--et-tint); border: 1px dashed var(--et-info-bord);
    display: grid; place-items: center; overflow: hidden;
}
.fe-photo-grande img { width: 100%; height: 100%; object-fit: cover; }
/* LIEN DE TÉLÉCHARGEMENT — invisible au repos, révélé au survol. Recouvre toute
   la vignette (inset:0) : la cible est la photo elle-même, pas une icône minuscule
   dans un coin. N'existe que quand une photo est affichée (voir le markup). */
.fe-photo-telecharger {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    background: transparent; color: var(--et-sur-aplat); font-size: 20px;
    opacity: 0; transition: opacity .12s ease, background-color .12s ease;
}
.fe-photo-grande:hover .fe-photo-telecharger {
    opacity: 1; background: rgba(50, 54, 58, .55);
}
.fe-photo-txt { flex: 1; min-width: 0; font-size: 13px; line-height: 1.55; color: var(--et-faint); }
/* Sous la vignette, le bouton en prend toute la largeur : la marge haute du lien
   ferait double emploi avec l'ecart de la colonne. Le libelle se replie sur deux
   lignes DANS son span plutot que le span sous l'icone — sans quoi la fleche
   occuperait a elle seule la premiere ligne du bouton. */
.fe-photo-vignette .fe-photo-lien {
    margin-top: 0; width: 100%; padding: 6px 8px;
    flex-wrap: nowrap; gap: 6px; justify-content: center;
    font-size: 12px; line-height: 1.3; text-align: center;
}
.fe-photo-vignette .fe-photo-lien > i { flex: none; }
/* L'erreur passe a la ligne suivante, sur toute la largeur de la carte. */
.fe-photo-erreur { flex: 0 0 100%; margin: 0; }

/* Pointages : pastille verte à l'entrée, marine à la sortie ; horodatage en
   chasse fixe pour que les heures s'alignent d'une ligne à l'autre. */
.fe-pointages { margin: 0; padding: 0; list-style: none; }
.fe-pointages li {
    display: flex; align-items: center; gap: 11px;
    padding: 9px 18px; border-bottom: 1px solid var(--et-hairline);
}
.fe-pointages li:last-child { border-bottom: none; }
.fe-pt { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.fe-pt.est-entree { background: var(--et-succes); }
.fe-pt.est-sortie { background: var(--fx-marine); }
.fe-pt-h { font-family: var(--fx-mono); font-size: 13px; color: var(--fx-texte); }
.fe-pt-ou { margin-top: 1px; font-size: 12px; color: var(--et-faint); }
.fe-pt-sens { flex: none; font-family: var(--fx-mono); font-size: 12px; color: var(--et-faint); }
.fe-cote-vide { padding: 20px 18px; text-align: center; font-size: 13px; color: var(--et-muted); }
/* UN LIEN EST BLEU. L'orange ne se pose que sur le bouton d'engagement d'un
   écran, et « Journal complet des pointages » n'en est pas un — il emmène
   ailleurs, il n'engage rien.

   LA RÈGLE AVAIT DÉJÀ ÉTÉ ÉCRITE, mais sur la déclaration périmée de la section
   précédente : elle ne s'appliquait donc pas, et le lien s'affichait orange au
   milieu d'une carte de données grises, plus voyant que les pointages qu'il
   accompagne. Une correction posée sur un doublon mort ne corrige rien — et rien
   ne le signale, puisque le fichier compile et que l'écran s'affiche.

   Le lien est la DERNIÈRE RANGÉE de la carte : padding de 18 px comme les
   rangées de .fe-pointages au-dessus, et aucune marge haute — celle de 10 px qui
   subsistait venait de la déclaration périmée, où le lien était encore un
   inline-block, et décollait la rangée du bord de la liste. */
.fe-cote-lien { display: block; padding: 11px 18px; font-size: 13px; font-weight: 600; color: var(--et-form-blue-encre); }
.fe-cote-lien:hover { color: var(--et-form-blue-d); text-decoration: underline; }

/* Données non modifiables : libellés en chasse fixe, capitales espacées, sur une
   colonne fixe — la valeur s'aligne d'une ligne à l'autre. */
.fe-def-liste { padding: 12px 18px 14px; display: flex; flex-direction: column; gap: 9px; }
.fe-def-liste .fx-def { display: flex; align-items: baseline; gap: 10px; padding: 0; border: none; }
.fe-def-liste .fx-def-lbl {
    flex: none; width: 96px; font-family: var(--fx-mono);
    font-size: 12px; text-transform: uppercase; letter-spacing: .12em; color: var(--et-muted);
}
.fe-def-liste .fx-def-val {
    flex: 1; min-width: 0; font-family: var(--fx-mono);
    font-size: 12px; color: var(--et-muted); text-align: left;
}

/* ---- Modèles biométriques : liste de cartes -------------------------------
   Le tableau à sept colonnes disait la même chose, mais forçait à lire une
   ligne de chiffres pour retrouver le terminal. La carte met en avant ce qu'on
   cherche — le type et l'appareil — et relègue les valeurs techniques. */
.fe-bio-liste { margin-top: 14px; border: 1px solid var(--et-hairline); border-radius: 0; overflow: hidden; }
.fe-bio-ligne {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 14px; border-bottom: 1px solid var(--et-hairline);
}
.fe-bio-ico {
    flex: none; width: 28px; height: 28px; border-radius: 0;
    background: var(--et-tint); color: var(--fx-bleu);
    display: grid; place-items: center; font-size: 14px;
}
.fe-bio-txt { flex: 1; min-width: 0; }
.fe-bio-nom { font-size: 13px; font-weight: 600; color: var(--fx-texte); }
.fe-bio-meta {
    margin-top: 1px; font-family: var(--fx-mono);
    font-size: 12px; color: var(--et-faint);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fe-bio-etat {
    flex: none; padding: 2px 9px; border-radius: 999px;
    font-size: 12px; font-weight: 600; background: var(--et-surface-2); color: var(--et-faint);
}
.fe-bio-etat.est-ok { background: var(--fx-ok-fond); color: var(--fx-ok-encre); }
.fe-bio-etat.est-attente { background: var(--fx-attention-fond); color: var(--fx-attention-encre); }

.fe-bio-pied {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap; row-gap: 9px;
    padding: 11px 14px; background: var(--et-surface-2);
}
.fe-bio-note { flex: 1 1 240px; min-width: 240px; font-size: 12px; line-height: 1.5; color: var(--et-faint); }

/* ---- Vignette de départ ---------------------------------------------------
   Bordure et bandeau rouges : c'est un constat de rupture, pas une carte
   d'information ordinaire. */
.fe-vignette-depart { border-color: var(--et-danger-bord); }
.fe-vignette-depart .fe-cote-titre {
    background: var(--et-danger-badge-bg); border-bottom-color: var(--et-danger-bord); color: var(--et-danger-ink);
}
.fe-vignette-note {
    margin: 0 18px; padding: 9px 11px;
    background: var(--et-surface-3); border-left: 3px solid var(--et-danger-bord);
    font-size: 12px; line-height: 1.5; color: var(--et-faint);
}
.fe-vignette-pied { display: flex; align-items: center; gap: 9px; padding: 12px 18px 16px; }
.fe-vignette-pastille {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 9px; border-radius: 999px;
    font-size: 12px; font-weight: 600; background: var(--et-surface-2); color: var(--et-faint);
}
.fe-vignette-pastille.est-attente { background: var(--et-avertissement-bg); color: var(--et-avertissement-ink); }
/* Le salarié n'a été retiré d'aucun terminal : il peut encore badger. */
.fe-vignette-pastille.est-alerte { background: var(--et-danger-badge-bg); color: var(--et-danger-ink); }

/* ---- Modales de rupture : bloc RETIRÉ le 2026-09-10 ------------------------
   Il portait onze règles pour la modale de départ et les deux modales de
   suppression de la fiche employé. Neuf ne pouvaient plus rien atteindre, et
   deux sont parties avec leur dernier appelant :

     .fe-modale-rupture .fx-modale-tete (et ses quatre descendants), ainsi que
       .fe-modale-rupture .fx-input / .fx-select — INERTES DEPUIS QUE LES DEUX
       MODALES DE SUPPRESSION SONT AU GABARIT. Elles portaient encore la classe
       .fe-modale-rupture, mais leur en-tête est un .mx-modale-tete : le sélecteur
       descendait vers un .fx-modale-tete qui n'existait plus. Une intention de
       dessin — un bandeau rouge sur une action qu'on ne défait pas — survivait
       ainsi dans la feuille sans rien peindre depuis des semaines. Si on la veut,
       c'est un modificateur du GABARIT qu'il faut (.mx-modale-cadre.est-rupture),
       pas une règle qui vise une famille abandonnée ;
     .fx-input.est-rupture / .est-mono — aucun balisage ne les composait plus.
       « est-rupture » subsiste ailleurs, sur .dev-sugg-stock de la grille de
       documents : un HOMONYME, et c'est précisément le piège que le dépôt
       signale sur les noms de classes (docs/conventions-nommage.md) — deux blocs
       de même nom ne se signalent pas, ils fusionnent ;
     .fe-grille-depart et .md-inv-detail — partis avec la mise au gabarit de
       ModaleDepart, qui était leur dernier appelant.

   .fe-modale-ligne est partie avec elles, dans le même lot : la modale de dossier
   de sortie, son dernier appelant, a suivi les deux autres au gabarit. Les quatre
   classes que la modale de départ portait ont donc quitté cette feuille ensemble. */

/* Sélecteur de salarié de la sortie d'effectif. Une liste de boutons pleine largeur plutôt
   qu'un <select> : le matricule, le nom et le service se lisent d'un coup, là où une liste
   déroulante native écrase tout sur une ligne et ne permet pas de départager deux homonymes. */
.md-choix-liste { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; }
.md-choix {
    display: flex; align-items: baseline; gap: 10px; width: 100%; padding: 8px 11px;
    border: 1px solid var(--et-form-border); background: var(--et-surface);
    font-family: inherit; font-size: 13px; color: var(--et-ink); text-align: left; cursor: pointer;
}
.md-choix:hover { border-color: var(--et-form-blue); background: var(--row-hover); }
.md-choix-code { flex: none; min-width: 62px; font-size: 12px; color: var(--et-muted); font-variant-numeric: tabular-nums; }
.md-choix-nom { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.md-choix-svc { flex: none; font-size: 12px; color: var(--et-muted); }

.fe-modale-texte { font-size: 13px; line-height: 1.6; color: var(--et-muted); }
.fe-modale-code { font-family: var(--fx-mono); color: var(--fx-marine); }

/* ---------------------------------------------------------------------------
   LISTE DE FAITS EN LECTURE — passation « design_handoff_traitement_absences ».

   Ce qu'un objet EST, quand il ne se corrige pas sur la fiche qui l'affiche : les
   faits du constat d'absence viennent du pointage calculé, et se corrigent sur
   l'écran de correction des pointages. La forme le dit — pas de champs, pas de
   bordures de saisie, une grille encadrée d'un seul filet.

   Même colonne d'intitulés que le formulaire dense, à droite : la fiche alterne
   lecture et saisie, et deux gouttières différentes en feraient deux fiches.
   --------------------------------------------------------------------------- */
.fx-liste {
    margin: 10px 0 0;
    border: 1px solid var(--et-hairline);
}
.fx-liste > div {
    display: grid;
    grid-template-columns: 190px minmax(0, 1fr);
    gap: 14px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--et-rang);
}
.fx-liste > div:last-child { border-bottom: none; }
.fx-liste dt { font-size: 12px; font-weight: 400; color: var(--et-form-label); text-align: right; }
.fx-liste dd { margin: 0; font-size: 13px; font-weight: 500; color: var(--et-form-text); }

@media (max-width: 560px) {
    .fx-liste > div { grid-template-columns: minmax(0, 1fr); gap: 2px; }
    .fx-liste dt { text-align: left; }
}

/* ---------------------------------------------------------------------------
   LA MISE EN PAGE DE LA FICHE EMPLOYÉ A ÉTÉ RETIRÉE — 2026-09-09.

   Elle occupait une cinquantaine de lignes : `.fe-gen`, `.fe-grid4`,
   `.fe-tabbody`, leurs descendants `.fe-lb`, `.fe-qte`, `.fe-photo`,
   `.fe-photo-box`, et les trois surcharges sombres qui les accompagnaient.
   AUCUN de ces jetons n'était écrit dans un attribut `class` du dépôt — relevé
   jeton par jeton sur toutes les vues (les noms voisins de `FicheEmploye.razor`
   sont `.fe-photo-zone`, `.fe-photo-vignette`, `.fe-photo-grande`, qui sont
   d'autres classes : un `grep` sur « fe-photo » les compte à tort).

   CE QUI L'A RÉVÉLÉ : le lot des paliers 860 px. Trois de ces règles portaient un
   seuil hors échelle, et en cherchant quoi mettre à la place on s'est aperçu
   qu'elles ne s'appliquaient à rien. Une valeur hors échelle sur du code mort est
   le seul cas où la garde a raison de crier pour une mauvaise raison.

   Le bloc venait de easytime-shell.css le 2026-09-03 — déplacé, jamais relu.
   Avec lui partent les trois `#0d1524` écrits en dur dans des RÈGLES ; celui qui
   reste (`--fx-champ-fond`, bloc sombre) est une DÉCLARATION de jeton, c'est-à-dire
   le seul endroit où une couleur doit être écrite. */

