/* =========================================================================
   Feuille applicative : jetons de conception, châssis (rail + barre
   supérieure), et les motifs partagés par les écrans.

   La recoloration du thème PrimeFaces n'est PAS ici : elle est dans
   theme-goypro.css, généré depuis le thème (voir son en-tête). Ici on ne
   traite que ce qui nous appartient — la mise en page, le rythme, et les
   quelques endroits où un composant PrimeFaces doit s'aligner sur nos motifs.

   Règle de spécificité : tout sélecteur qui vise une classe .ui-* du thème
   est préfixé « html body », pour la même raison que dans theme-goypro.css
   — l'ordre de chargement des feuilles n'est pas garanti.
   ========================================================================= */

:root {
    /* --- Couleurs ------------------------------------------------------- */
    --ardoise-900: #0F172A;   /* rail, titres */
    --ardoise-800: #1E293B;   /* survol dans le rail */
    --ardoise-700: #334155;   /* texte courant */
    --ardoise-500: #64748B;   /* texte secondaire */
    --ardoise-300: #CBD5E1;   /* bordures de champ */
    --ardoise-200: #E2E8F0;   /* bordures de carte */
    --ardoise-100: #F1F5F9;   /* survol de ligne */

    --action: #1264C8;
    --action-survol: #0F58AD;
    --action-douce: #E8F0FC;  /* fond des états sélectionnés */

    --accent: #F59E0B;        /* alertes, retards, seuils */
    --succes: #059669;
    --danger: #DC2626;
    --info: #0284C7;

    --fond-page: #F6F8FB;
    --fond-carte: #FFFFFF;
    --fond-creux: #FCFDFE;    /* barre de filtres, pied de dialogue, pagination */
    --fond-entete: #FAFBFD;   /* en-tête de tableau, ligne dépliée */
    --bord-doux: #EEF2F7;     /* séparateurs internes, plus discrets que -200 */
    --bord-natif: #d0d5dd;    /* champs HTML natifs, hors thème PrimeFaces */

    /* Le rail est le seul fond SOMBRE du thème clair, et il le reste en
       thème sombre. Séparé de --ardoise-900 pour cette raison exactement :
       ce niveau-là sert aussi de couleur aux titres, qui doivent s'éclaircir
       quand le rail, lui, ne bouge pas. Un nom qui décrit une clarté ne peut
       pas porter deux rôles opposés. */
    --rail-fond: #0F172A;
    --rail-survol: #1E293B;

    /* --- Statuts : un fond et un texte par famille ----------------------
       Écrits ici plutôt qu'en dur dans les règles depuis le thème sombre :
       c'étaient les cinquante-cinq couleurs qui empêchaient de basculer. */
    --info-texte: #0F55AA;
    --succes-fond: #E7F6EF;
    --succes-texte: #047857;
    --alerte-fond: #FEF3E2;
    --alerte-texte: #B45309;
    --danger-fond: #FEECEC;
    --danger-fond-doux: #FEF2F2;
    --danger-bord: #FECACA;
    --danger-texte: #B91C1C;
    --attente-fond: #FEF3C7;      /* le reste dû d'un règlement partiel */
    --avertissement-fond: #FEF9EC;
    --avertissement-bord: #FDE9B8;
    --avertissement-texte: #92400E;
    --ambre-fond: #fff8e6;        /* bandeau de licence, réserve, dépassement */
    --ambre-bord: #f0d089;
    --ambre-texte: #7a5300;
    --grave-fond: #fdecea;        /* licence expirée, marge négative */
    --grave-bord: #f0a9a2;
    --grave-texte: #8c1c13;
    --vert-texte: #1f7a3d;        /* licence valide, marge positive */

    /* --- Rythme --------------------------------------------------------- */
    --pas-1: 4px;
    --pas-2: 8px;
    --pas-3: 12px;
    --pas-4: 16px;
    --pas-5: 24px;
    --pas-6: 32px;

    --rayon: 10px;
    --rayon-petit: 6px;

    /* Ombres discrètes : une application de gestion se lit, elle ne
       s'exhibe. Deux niveaux suffisent — posé (cartes) et flottant
       (dialogues, menus). */
    --ombre-posee: 0 1px 2px rgba(15, 23, 42, .04), 0 1px 3px rgba(15, 23, 42, .06);
    --ombre-flottante: 0 10px 25px rgba(15, 23, 42, .12), 0 4px 10px rgba(15, 23, 42, .06);

    /* --- Châssis -------------------------------------------------------- */
    --rail-largeur: 248px;
    --rail-largeur-replie: 68px;
    --barre-hauteur: 60px;
}

/* =========================================================================
   Le thème sombre

   UNIQUEMENT DES VARIABLES. Pas une seule règle de mise en page n'est
   répétée ici, et c'est la condition pour que ça tienne : une variante qui
   redéclare des sélecteurs se désynchronise au premier écran ajouté, et le
   défaut ne se voit que sur cet écran-là, en sombre, chez la personne qui
   l'a choisi. C'est aussi pour ça que les cinquante-cinq couleurs écrites
   en dur plus bas ont été rapatriées au-dessus : elles étaient exactement
   ce qui rendait la bascule impossible.

   L'ÉCHELLE ARDOISE S'INVERSE PAR RÔLE, PAS PAR NOM. --ardoise-900 reste
   « ce dont on peint les titres » et devient donc clair ; --ardoise-100
   reste « le survol d'une ligne » et reste donc à peine détaché du fond. Le
   rail, lui, ne bouge pas : il était déjà sombre, c'est --rail-fond.

   LES STATUTS S'INVERSENT AUSSI : fonds assombris, textes éclaircis. Poser
   un texte rouge foncé sur un fond rouge clair marche sur du blanc et
   devient illisible sur du sombre — les deux moitiés de chaque paire
   changent ensemble, jamais l'une sans l'autre.
   ========================================================================= */
html[data-theme="sombre"] {
    /* Surfaces, du plus bas au plus haut. Le rail se détache du fond de
       page parce qu'il est un cran AU-DESSUS : sur un fond identique il
       aurait disparu, et le châssis avec lui. */
    --fond-page: #0B1220;
    --rail-fond: #0F172A;
    --rail-survol: #1E293B;
    --fond-creux: #131C30;
    --fond-entete: #131C30;
    --fond-carte: #16203A;

    /* Textes et traits */
    --ardoise-900: #F1F5F9;
    --ardoise-800: #E2E8F0;
    --ardoise-700: #CBD5E1;
    --ardoise-500: #94A3B8;
    --ardoise-300: #3F4E68;
    --ardoise-200: #2B3A52;
    --ardoise-100: #1E293B;
    --bord-doux: #243146;
    --bord-natif: #3A4B66;

    /* Le bleu d'action s'éclaircit : #1264C8 sur #0B1220 tombe sous le
       seuil de lisibilité d'un lien. Même valeur que la couche sombre
       engendrée du thème PrimeFaces — les deux feuilles doivent parler du
       même bleu, sinon un bouton et le lien à côté de lui divergent. */
    --action: #2F7FE0;
    --action-survol: #3D8CEC;
    --action-douce: #1C3252;

    --accent: #FBBF24;
    --succes: #34D399;
    --danger: #F87171;
    --info: #38BDF8;

    --info-texte: #93C5FD;
    --succes-fond: #10281F;
    --succes-texte: #6EE7B7;
    --alerte-fond: #2E2213;
    --alerte-texte: #FBBF24;
    --danger-fond: #2E1618;
    --danger-fond-doux: #241214;
    --danger-bord: #5B2326;
    --danger-texte: #FCA5A5;
    --attente-fond: #33280E;
    --avertissement-fond: #2A2113;
    --avertissement-bord: #4A3A1B;
    --avertissement-texte: #FCD34D;
    --ambre-fond: #2A2113;
    --ambre-bord: #4A3A1B;
    --ambre-texte: #FCD34D;
    --grave-fond: #2E1618;
    --grave-bord: #5B2326;
    --grave-texte: #FCA5A5;
    --vert-texte: #6EE7B7;

    /* Une ombre noire ne se voit pas sur du noir : ce sont les mêmes
       ombres, portées beaucoup plus loin en opacité. Sans ça, cartes et
       dialogues perdent leur relief et l'interface s'aplatit. */
    --ombre-posee: 0 1px 2px rgba(0, 0, 0, .40), 0 1px 3px rgba(0, 0, 0, .50);
    --ombre-flottante: 0 10px 25px rgba(0, 0, 0, .55), 0 4px 10px rgba(0, 0, 0, .40);
}

/* Pile système : aucune police téléchargée, donc aucune requête sortante
   depuis le Tomcat (et aucun binaire dans le dépôt). 15px de base plutôt que
   16 : tout PrimeFaces est dimensionné en rem, l'interface se densifie donc
   d'un bloc, proportionnellement, sans retoucher une seule règle du thème. */
html {
    font-size: 15px;
}

html body {
    margin: 0;
    background: var(--fond-page);
    color: var(--ardoise-700);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                 "Helvetica Neue", Arial, "Noto Sans", sans-serif;
    -webkit-font-smoothing: antialiased;
}

/* =========================================================================
   1. Châssis
   ========================================================================= */

/* Rail fixe plutôt qu'en flux : le contenu des pages est réécrit par les
   mises à jour AJAX de JSF, le châssis ne doit jamais être entraîné dans ces
   recalculs. */
.rail {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--rail-largeur);
    background: var(--rail-fond);
    display: flex;
    flex-direction: column;
    z-index: 1000;
    transition: width .18s ease;
    overflow: hidden;
}

.rail-marque {
    display: flex;
    align-items: center;
    gap: var(--pas-3);
    height: var(--barre-hauteur);
    padding: 0 var(--pas-4);
    flex: 0 0 auto;
    border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.rail-logo {
    max-height: 32px;
    max-width: 32px;
    border-radius: var(--rayon-petit);
    flex: 0 0 auto;
}

/* Repli quand aucun logo n'a été téléversé : l'initiale du nom de
   l'entreprise, plutôt qu'une image cassée. */
.rail-monogramme {
    width: 32px;
    height: 32px;
    flex: 0 0 auto;
    border-radius: var(--rayon-petit);
    background: var(--action);
    color: #fff;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    text-transform: uppercase;
}

/* Deux lignes au plus, coupées proprement : le nom de l'entreprise vient des
   paramètres et peut être très long ; sur une seule ligne tronquée, il ne
   resterait que « ETS. ADAMOU… ». */
.rail-nom {
    color: #fff;
    font-weight: 600;
    font-size: .88rem;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.rail-nav {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: var(--pas-3) var(--pas-2);
}

.rail-groupe {
    color: rgba(255, 255, 255, .38);
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    padding: var(--pas-4) var(--pas-3) var(--pas-2);
    white-space: nowrap;
}

html body .rail-item {
    display: flex;
    align-items: center;
    gap: var(--pas-3);
    padding: 10px var(--pas-3);
    margin-bottom: 2px;
    border-radius: var(--rayon-petit);
    color: rgba(255, 255, 255, .72);
    text-decoration: none;
    font-size: .9rem;
    white-space: nowrap;
    transition: background-color .15s, color .15s;
}

html body .rail-item:hover {
    background: var(--rail-survol);
    color: #fff;
    text-decoration: none;
}

/* L'écran courant : fond plein et liseré, pour qu'on sache où l'on est sans
   avoir à relire le titre. */
html body .rail-item.est-actif {
    background: var(--action);
    color: #fff;
    font-weight: 600;
}

.rail-item .pi {
    font-size: 1.05rem;
    width: 20px;
    flex: 0 0 auto;
    text-align: center;
}

.rail-item-libelle {
    overflow: hidden;
    text-overflow: ellipsis;
}

.rail-separateur {
    height: 1px;
    background: rgba(255, 255, 255, .08);
    margin: var(--pas-3) var(--pas-3);
}

.rail-pied {
    flex: 0 0 auto;
    padding: var(--pas-2);
    border-top: 1px solid rgba(255, 255, 255, .08);
}

html body .rail-bascule {
    display: flex;
    align-items: center;
    gap: var(--pas-3);
    width: 100%;
    padding: 10px var(--pas-3);
    background: none;
    border: 0;
    border-radius: var(--rayon-petit);
    color: rgba(255, 255, 255, .55);
    font: inherit;
    font-size: .85rem;
    cursor: pointer;
    white-space: nowrap;
}

html body .rail-bascule:hover {
    background: var(--rail-survol);
    color: #fff;
}

/* Signature du concepteur, en pied de rail. Rien ne la recolore ici : le
   fichier employé est DÉJÀ la version pour fond sombre — Calcaire #F5F4F0 et
   Braise #F2C14E, la palette que la planche de marque réserve au fond sombre
   (outils/marque/sahelforge-identite.html). Le logo de base est en Indigo
   Ténéré #0E2E4A, qui sur ce fond-ci donne 1,4 pour 1 : une forme qu'on ne
   distingue pas.

   Le padding vaut la zone de protection exigée par la planche — un vide égal
   au diamètre de l'anneau tout autour, soit une dizaine de pixels à cette
   taille. Les 8px de .rail-pied s'y ajoutent.

   line-height à 0 : sans lui, la ligne de base du conteneur réserve sous
   l'image quelques pixels de blanc que le padding rendrait dissymétrique. */
.rail-signature {
    padding: var(--pas-3);
    line-height: 0;
}

/* .55, la valeur que .rail-bascule porte juste au-dessus dans l'alpha de sa
   couleur : ces deux-là sont du même registre, en dessous de la navigation.
   Elle ne s'éclaircit PAS au survol — ce n'est pas un lien, et rien ne doit
   laisser croire qu'on peut cliquer dessus. */
.rail-signature img {
    display: block;
    max-width: 100%;
    height: auto;      /* le SVG porte width/height en attributs : sans ça,
                          une largeur bornée par max-width l'écraserait */
    opacity: .55;
}

/* 180px pour 36 de haut (le dessin est au ratio 5/1). La planche pose 32px
   comme hauteur minimale du logo sans slogan : descendre à 150, comme la
   première version le faisait, passait dessous. */
.rail-signature-mot {
    width: 180px;
}

/* La même marque, mais en TÊTE du rail et sur la console du super admin —
   l'exact inverse de .rail-signature. Là-bas c'est une signature discrète
   sous la marque du client ; ici l'écran appartient à l'éditeur, et la
   place du haut est celle de son propriétaire. D'où l'opacité pleine.

   height auto pour la raison déjà écrite au-dessus, et qui vaut deux fois
   ici : le SVG porte width="499.9" height="100" en attributs, une largeur
   posée seule le rendrait à 180 sur 100. */
.rail-marque-editeur {
    display: block;
    width: 176px;
    height: auto;
}

/* --- Rail replié -------------------------------------------------------- */
/* La classe est posée sur <html> par le script du template AVANT peinture :
   restaurer le repli après coup ferait clignoter le rail à chaque page. */
.rail-replie .rail {
    width: var(--rail-largeur-replie);
}

.rail-replie .zone {
    margin-left: var(--rail-largeur-replie);
}

/* La signature disparaît avec les libellés, et le rail replié n'en porte
   alors AUCUNE. Un symbole seul y a existé, retiré depuis du châssis : le
   mot, large de 180, ne peut pas rester — à 68px il serait rogné par
   l'overflow du rail, pas réduit mais COUPÉ, et il n'en resterait que
   « SAHELF » ; le réduire jusqu'à tenir le ferait passer sous les 32px de
   haut que la planche de marque pose comme minimum. */
.rail-replie .rail-nom,
.rail-replie .rail-item-libelle,
.rail-replie .rail-groupe,
.rail-replie .rail-signature-mot,
.rail-replie .rail-bascule span {
    display: none;
}

.rail-replie .rail-item,
.rail-replie .rail-bascule {
    justify-content: center;
}

.rail-replie .rail-marque {
    justify-content: center;
    padding: 0;
}

.rail-replie .rail-bascule .pi {
    transform: rotate(180deg);
}

/* --- Zone de travail ---------------------------------------------------- */
/* Voile de fermeture du tiroir : masqué ICI et pas seulement dans la règle
   du mode tiroir. Sans cette base, le div reste dans le flux sur grand écran
   — sans hauteur donc invisible, mais présent : une négligence, pas une
   intention. */
.tiroir-voile {
    display: none;
}

.zone {
    margin-left: var(--rail-largeur);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    transition: margin-left .18s ease;
}

.barre {
    position: sticky;
    top: 0;
    z-index: 900;
    height: var(--barre-hauteur);
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--pas-4);
    padding: 0 var(--pas-5);
    background: var(--fond-carte);
    border-bottom: 1px solid var(--ardoise-200);
}

.barre-titre {
    font-size: 1rem;
    font-weight: 600;
    color: var(--ardoise-900);
    margin: 0;
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

html body .barre-tiroir {
    display: none;   /* n'apparaît qu'en dessous de 1024px */
    background: none;
    border: 0;
    color: var(--ardoise-700);
    font-size: 1.2rem;
    cursor: pointer;
    padding: var(--pas-2);
}

.barre-compte {
    display: flex;
    align-items: center;
    gap: var(--pas-3);
    flex: 0 0 auto;
}

.compte-pastille {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--action-douce);
    color: var(--action);
    font-weight: 700;
    font-size: .85rem;
    display: flex;
    align-items: center;
    justify-content: center;
    text-transform: uppercase;
}

/* La pastille et le nom forment UN lien vers « Mon compte ». C'est le
   geste attendu là où on lit son propre nom, et ça évite une entrée de
   plus dans un rail qui en porte déjà quatorze — celle-ci ne concerne
   aucun métier, elle concerne la personne. */
html body .compte-lien {
    display: flex;
    align-items: center;
    gap: var(--pas-3);
    text-decoration: none;
    color: inherit;
    border-radius: var(--rayon-petit);
    padding: var(--pas-1);
    margin: calc(-1 * var(--pas-1));
    transition: background-color .15s;
}

html body .compte-lien:hover {
    background: var(--ardoise-100);
    text-decoration: none;
}

.compte-identite {
    line-height: 1.25;
    text-align: right;
}

.compte-nom {
    display: block;
    font-weight: 600;
    color: var(--ardoise-900);
    font-size: .875rem;
}

.compte-role {
    display: block;
    color: var(--ardoise-500);
    font-size: .75rem;
}

/* La bascule de thème, dans son propre h:form : les formulaires ne
   s'imbriquent pas, et celui-ci voisine avec celui de la déconnexion. Le
   form ne doit donc rien peser dans la mise en page de la barre. */
.barre-theme {
    display: flex;
    flex: 0 0 auto;
}

/* Habillée EXACTEMENT comme la déconnexion : ce sont deux boutons-icônes
   voisins, et deux tailles différentes côte à côte se verraient tout de
   suite. Les règles ne sont pas partagées avec .compte-sortie parce que
   leurs SURVOLS diffèrent — celui-ci ne vire pas au rouge, il ne détruit
   rien.

   La spécificité « html body » et le !important sur le fond : c'est un
   p:commandButton, donc le thème PrimeFaces le peint en bouton primaire
   plein. Sans cette reprise, la barre porterait un gros bouton bleu. */
html body .compte-theme.ui-button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    background: none !important;
    border: 1px solid var(--ardoise-200);
    border-radius: var(--rayon-petit);
    color: var(--ardoise-500);
    cursor: pointer;
    transition: background-color .15s, color .15s, border-color .15s;
}

html body .compte-theme.ui-button:hover {
    background: var(--action-douce) !important;
    border-color: var(--action);
    color: var(--action);
}

html body .compte-theme.ui-button .ui-button-icon-left,
html body .compte-theme.ui-button .ui-icon {
    margin: 0;
}

/* Le libellé vide qu'un p:commandButton sans value insère malgré tout : il
   ajoute une espace insécable, donc décale l'icône hors du centre. */
html body .compte-theme.ui-button .ui-button-text {
    display: none;
}

/* Déconnexion : bouton d'un formulaire HTML natif posté vers /logout (voir
   template.xhtml pour le raisonnement), habillé en icône. */
html body .compte-sortie {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    background: none;
    border: 1px solid var(--ardoise-200);
    border-radius: var(--rayon-petit);
    color: var(--ardoise-500);
    cursor: pointer;
    transition: background-color .15s, color .15s, border-color .15s;
}

html body .compte-sortie:hover {
    background: var(--danger-fond-doux);
    border-color: var(--danger-bord);
    color: var(--danger);
}

.contenu {
    flex: 1 1 auto;
    padding: var(--pas-5);
    max-width: 1440px;
    width: 100%;
    box-sizing: border-box;
}

/* =========================================================================
   2. En-tête d'écran
   ========================================================================= */

.ecran-entete {
    display: flex;
    align-items: flex-start;
    gap: var(--pas-4);
    margin-bottom: var(--pas-5);
}

.ecran-entete h1 {
    font-size: 1.5rem;
    font-weight: 650;
    color: var(--ardoise-900);
    margin: 0;
    letter-spacing: -.01em;
}

.ecran-soustitre {
    display: block;
    margin-top: var(--pas-1);
    color: var(--ardoise-500);
    font-size: .9rem;
}

/* =========================================================================
   3. Cartes et barres de filtres
   ========================================================================= */

/* PAS d'overflow:hidden ici, malgré la tentation : c'était le moyen le plus
   court d'arrondir les coins du contenu, mais PrimeFaces rend les panneaux
   déroulants (selectOneMenu, datePicker, autoComplete) À L'INTÉRIEUR du
   composant, donc à l'intérieur de la carte — vérifié dans le HTML servi.
   Un rognage y est un menu invisible. Les coins sont donc arrondis
   explicitement sur le premier et le dernier bloc de la carte. */
.carte {
    background: var(--fond-carte);
    border: 1px solid var(--ardoise-200);
    border-radius: var(--rayon);
    box-shadow: var(--ombre-posee);
    margin-bottom: var(--pas-5);
}

.carte > :first-child,
.carte > form > :first-child {
    border-top-left-radius: var(--rayon);
    border-top-right-radius: var(--rayon);
}

.carte > :last-child,
.carte > form > :last-child {
    border-bottom-left-radius: var(--rayon);
    border-bottom-right-radius: var(--rayon);
}

.carte-titre {
    display: flex;
    align-items: center;
    gap: var(--pas-2);
    padding: var(--pas-4) var(--pas-5);
    border-bottom: 1px solid var(--ardoise-200);
    font-weight: 600;
    color: var(--ardoise-900);
}

.carte-corps {
    padding: var(--pas-5);
}

/* La p:toolbar de filtres est soudée au tableau qui la suit : dans le même
   cadre, ils se lisent comme un seul objet — le tableau et ce qui le filtre.
   Sans ça la barre flottait au-dessus, détachée de ce sur quoi elle agit. */
html body .carte .ui-toolbar {
    background: var(--fond-creux);
    border: 0;
    border-bottom: 1px solid var(--ardoise-200);
    border-radius: 0;
    padding: var(--pas-3) var(--pas-4);
    display: flex;
    flex-wrap: wrap;
    gap: var(--pas-3);
    align-items: center;
}

html body .carte .ui-toolbar-group-left,
html body .carte .ui-toolbar-group-right {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--pas-2);
}

html body .carte .ui-toolbar-group-right {
    margin-left: auto;
}

/* Champ de recherche : une largeur confortable, mais qui cède sur petit
   écran plutôt que de déborder. */
html body .champ-recherche {
    width: 320px;
    max-width: 100%;
}

html body .champ-filtre {
    min-width: 190px;
}

/* Référence produit : saisie en majuscules, comme elle sera citée au
   fournisseur. La transformation est visuelle — le bean reçoit ce qui est
   tapé, la contrainte d'unicité reste côté service. */
html body .champ-majuscules {
    text-transform: uppercase;
}

html body .champ-date .ui-inputfield {
    width: 130px;
}

/* Note attachée à une ligne de journal : signalée par une icône, lue en
   infobulle. Discrète tant qu'on ne la cherche pas. */
html body .icone-note {
    margin-left: var(--pas-2);
    color: var(--ardoise-500);
    cursor: help;
}

/* Sous-bloc apparaissant dans un champ (le client d'un chantier à ouvrir
   depuis le dialogue du planning) : détaché de ce qui le précède. */
.sous-bloc {
    margin-top: var(--pas-2);
}

/* Libellé d'un champ imbriqué : plus discret que celui de la grille, pour
   ne pas rivaliser avec le libellé principal de la ligne. */
html body .libelle-secondaire {
    display: block;
    margin-bottom: var(--pas-1);
    color: var(--ardoise-500);
    font-size: .8rem;
    font-weight: 600;
}

/* Le calendrier occupe toute la carte, sans bordure propre. */
html body .carte .ui-schedule {
    padding: var(--pas-4);
}

/* =========================================================================
   4. Tableaux
   ========================================================================= */

/* CORRECTIF DE FOND, et non cosmétique.
   PrimeFaces pose table-layout:fixed sur .ui-datatable table, et le thème
   box-sizing:content-box sur les th : une colonne consomme alors sa width
   PLUS 32px de padding, la somme dépasse 100%, et les colonnes sans width
   déclarée sont écrasées à zéro — c'est ce qui rendait autrefois la colonne
   « Client » invisible, et ce qui a imposé de calculer à la main un budget de
   largeurs page par page sous une contrainte de 1200px.
   Avec border-box et un dimensionnement automatique, le navigateur répartit
   selon le contenu : plus de budget à tenir, plus de colonne perdue, et les
   tableaux acceptent n'importe quelle largeur de conteneur — ce qui rend le
   rail latéral et l'affichage sur tablette possibles. */
html body .ui-datatable table {
    table-layout: auto;
}

html body .ui-datatable thead th,
html body .ui-datatable tbody td,
html body .ui-datatable tfoot td {
    box-sizing: border-box;
}

/* Défilement horizontal de secours, sur TOUS les tableaux et pas seulement
   sur ceux qui sont dans une carte : ceux des dialogues (lignes de devis, de
   facture, de commande, réception, pièces posées) sont les plus étroitement
   logés. Sans cette règle, une fenêtre plus étroite que le tableau coupe les
   dernières colonnes sans aucun moyen d'y accéder. La restreindre à .carte
   était une erreur de portée de ma part. */
html body .ui-datatable-tablewrapper {
    overflow-x: auto;
}

html body .ui-datatable thead th {
    background: var(--fond-entete);
    border-bottom: 1px solid var(--ardoise-200);
    color: var(--ardoise-500);
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    padding: var(--pas-3) var(--pas-4);
    white-space: nowrap;
}

html body .ui-datatable tbody td {
    padding: var(--pas-3) var(--pas-4);
    border-bottom: 1px solid var(--bord-doux);
    vertical-align: middle;
}

html body .ui-datatable tbody tr:last-child td {
    border-bottom: 0;
}

html body .ui-datatable tbody tr.ui-widget-content:hover {
    background: var(--ardoise-100);
}

/* Colonnes typées : le sens de la donnée décide de son alignement, pas un
   style posé ligne à ligne. */
html body .col-ref,
html body .col-ref .ui-column-title {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .85rem;
    white-space: nowrap;
}

html body th.col-ref .ui-column-title {
    font-family: inherit;
}

/* Chiffres tabulaires : sans eux, une colonne de montants en FCFA ne
   s'aligne pas verticalement, les chiffres n'ayant pas la même chasse. */
html body .col-montant {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

html body th.col-montant .ui-column-title {
    display: block;
    text-align: right;
}

html body .col-nombre {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

html body th.col-nombre .ui-column-title {
    display: block;
    text-align: right;
}

html body .col-date {
    white-space: nowrap;
}

html body .col-statut {
    white-space: nowrap;
}

html body .col-actions {
    text-align: right;
    white-space: nowrap;
}

html body .col-actions .ui-button {
    margin-left: var(--pas-1);
}

/* Colonne de texte long : on borne et on coupe proprement plutôt que de
   laisser une description pousser toutes les autres colonnes hors du cadre. */
html body .col-texte {
    max-width: 340px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Colonne du chevron de dépliage : juste la place de l'icône. */
html body .col-deplier {
    width: 2.4rem;
    text-align: center;
}

/* Contenu d'une ligne dépliée : en retrait et sur un fond légèrement creusé,
   pour qu'on voie qu'il appartient à la ligne du dessus. */
html body .bloc-deplie {
    padding: var(--pas-3) var(--pas-5);
    background: var(--fond-entete);
}

html body .ui-datatable .ui-paginator {
    background: var(--fond-creux);
    border: 0;
    border-top: 1px solid var(--ardoise-200);
    padding: var(--pas-3) var(--pas-4);
}

/* Message de liste vide : une icône et une phrase, centrées, plutôt qu'un
   fragment de texte collé à gauche dans une cellule. */
.vide {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--pas-2);
    padding: var(--pas-6) var(--pas-4);
    color: var(--ardoise-500);
}

.vide .pi {
    font-size: 1.8rem;
    color: var(--ardoise-300);
}

/* =========================================================================
   5. Statuts
   ========================================================================= */

/* Pastilles à fond doux plutôt que blocs pleins : sur une colonne entière,
   les aplats saturés du thème écrasent la lecture du reste de la ligne. */
html body .ui-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .01em;
    line-height: 1.5;
    background: var(--ardoise-100);
    color: var(--ardoise-700);
}

html body .ui-tag::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

html body .ui-tag.ui-tag-info {
    background: var(--action-douce);
    color: var(--info-texte);
}

html body .ui-tag.ui-tag-success {
    background: var(--succes-fond);
    color: var(--succes-texte);
}

html body .ui-tag.ui-tag-warning {
    background: var(--alerte-fond);
    color: var(--alerte-texte);
}

html body .ui-tag.ui-tag-danger {
    background: var(--danger-fond);
    color: var(--danger-texte);
}

html body .ui-tag .ui-tag-icon {
    display: none;   /* le point coloré tient déjà ce rôle */
}

/* =========================================================================
   6. Boutons
   ========================================================================= */

html body .ui-button {
    border-radius: var(--rayon-petit);
    font-weight: 600;
    font-size: .875rem;
    box-shadow: none;
}

html body .ui-button .ui-button-text {
    padding: .55rem .9rem;
}

/* Boutons d'action dans les tableaux : ronds, sans texte, alignés. */
html body .bouton-rond {
    border-radius: 50%;
    width: 2.1rem;
    height: 2.1rem;
    padding: 0;
}

html body .bouton-rond .ui-button-icon-left {
    margin: 0;
}

/* Bouton discret : pour les actions secondaires d'une ligne (voir, PDF),
   qui ne doivent pas rivaliser avec l'action principale de l'écran. */
html body .ui-button.ui-button-flat,
html body .bouton-discret {
    background: transparent;
    border-color: transparent;
    color: var(--ardoise-500);
}

html body .bouton-discret:hover {
    background: var(--ardoise-100);
    border-color: transparent;
    color: var(--ardoise-900);
}

/* Lien de retour, de navigation contextuelle. */
html body .lien-retour {
    display: inline-flex;
    align-items: center;
    gap: var(--pas-2);
    color: var(--ardoise-500);
    text-decoration: none;
    font-size: .875rem;
}

html body .lien-retour:hover {
    color: var(--action);
}

/* =========================================================================
   7. Formulaires et dialogues
   ========================================================================= */

/* La structure p:panelGrid des formulaires est conservée (elle est vérifiée
   par la recette) ; on n'en retouche que le rythme et l'alignement. */
html body .ui-panelgrid.ui-panelgrid-blank .ui-grid-row {
    align-items: center;
    margin-bottom: var(--pas-3);
}

html body .ui-panelgrid.ui-panelgrid-blank .ui-panelgrid-cell {
    padding: 0 var(--pas-2);
}

html body .ui-panelgrid .ui-outputlabel {
    color: var(--ardoise-500);
    font-size: .82rem;
    font-weight: 600;
}

/* Les champs occupent leur cellule : des largeurs hétérogènes dans une même
   colonne, c'est ce qui donne le plus vite l'impression d'un formulaire
   bricolé. */
html body .ui-panelgrid .ui-inputfield,
html body .ui-panelgrid .ui-selectonemenu,
html body .ui-panelgrid .ui-inputnumber,
html body .ui-panelgrid .ui-calendar,
html body .ui-panelgrid .ui-autocomplete {
    width: 100%;
}

html body .ui-inputfield,
html body .ui-selectonemenu {
    border-radius: var(--rayon-petit);
    border-color: var(--ardoise-300);
}

html body .ui-dialog {
    border: 0;
    border-radius: var(--rayon);
    box-shadow: var(--ombre-flottante);
    overflow: hidden;
}

html body .ui-dialog .ui-dialog-titlebar {
    background: var(--fond-carte);
    border: 0;
    border-bottom: 1px solid var(--ardoise-200);
    padding: var(--pas-4) var(--pas-5);
    color: var(--ardoise-900);
    font-weight: 650;
    border-radius: 0;
}

html body .ui-dialog .ui-dialog-content {
    padding: var(--pas-5);
    background: var(--fond-carte);
}

html body .ui-dialog .ui-dialog-footer {
    background: var(--fond-creux);
    border-top: 1px solid var(--ardoise-200);
    padding: var(--pas-3) var(--pas-5);
    display: flex;
    justify-content: flex-end;
    gap: var(--pas-2);
}

html body .ui-growl {
    box-shadow: var(--ombre-flottante);
}

html body .ui-dialog .ui-messages,
html body .ui-dialog .ui-message {
    margin-top: var(--pas-4);
}

/* =========================================================================
   7 bis. Documents à lignes (devis, factures, commandes)
   ========================================================================= */

/* Le tableau des lignes est le cœur du dialogue : il se détache du bloc
   d'en-tête au lieu d'y être collé. */
.bloc-lignes {
    margin-top: var(--pas-5);
}

.barre-lignes {
    margin-top: var(--pas-3);
}

html body .champ-large {
    width: 100%;
}

html body .champ-catalogue .ui-autocomplete-input {
    width: 300px;
    max-width: 100%;
}

/* Provenance de la ligne : la référence catalogue, et l'écart au tarif s'il
   y en a un. Discret par construction — c'est une annotation, pas une
   colonne. */
.ligne-rattachement {
    font-size: .78rem;
    line-height: 1.6;
    margin-top: 2px;
}

.ecart-catalogue {
    color: var(--alerte-texte);
    font-weight: 600;
}

/* Échéance dépassée : signalée dans la colonne des dates et pas seulement
   par le statut — c'est là que va l'œil quand on cherche qui relancer. */
html body .echeance-depassee {
    color: var(--danger-texte);
    font-weight: 700;
}

/* Une facture entamée sans être soldée. Le repère est nécessaire parce que
   le statut ne dit rien de cet état : une facture à moitié réglée reste
   ENVOYEE ou EN_RETARD, et sans marque « 300 000 » dans la colonne du reste
   dû se lirait comme le montant de la facture.

   Un fond et non une couleur de texte : la colonne voisine porte déjà du
   rouge pour l'échéance dépassée, et les deux états se cumulent souvent —
   une facture en retard partiellement réglée est même le cas le plus
   fréquent. Deux rouges côte à côte ne diraient plus lequel des deux
   signale quoi. */
html body .reste-partiel {
    background: var(--attente-fond);
    border-radius: 4px;
    padding: 1px 6px;
    font-weight: 700;
}

/* Totaux : alignés à droite, en chiffres tabulaires, le TTC détaché. Une
   pile de <div> alignés à droite ne suffisait pas — les montants ne se
   superposaient pas d'une ligne à l'autre. */
.totaux {
    margin-top: var(--pas-5);
    margin-left: auto;
    width: 280px;
    max-width: 100%;
}

.totaux > div {
    display: flex;
    justify-content: space-between;
    gap: var(--pas-4);
    padding: 6px 0;
    font-variant-numeric: tabular-nums;
}

.totaux > div > span {
    color: var(--ardoise-500);
}

.totaux .totaux-final {
    margin-top: var(--pas-2);
    padding-top: var(--pas-3);
    border-top: 1px solid var(--ardoise-200);
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--ardoise-900);
}

.totaux .totaux-final > span {
    color: var(--ardoise-900);
}

/* Lien vers le PDF : aligné avec les boutons ronds de la colonne Actions,
   et de la couleur d'un PDF. */
html body .lien-pdf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    margin-left: var(--pas-1);
    border-radius: 50%;
    color: var(--danger-texte);
    text-decoration: none;
    vertical-align: middle;
}

html body .lien-pdf:hover {
    background: var(--danger-fond);
}

html body .lien-pdf .pi {
    font-size: 1.1rem;
}

/* Lien d'action porté par une icône seule (ouvrir une fiche) : même gabarit
   que les boutons ronds voisins, pour que la colonne Actions reste alignée
   qu'elle contienne des boutons ou des liens. */
html body .lien-icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    margin-left: var(--pas-1);
    border-radius: 50%;
    color: var(--action);
    text-decoration: none;
    vertical-align: middle;
}

html body .lien-icone:hover {
    background: var(--action-douce);
}

html body .lien-icone .pi {
    font-size: 1.1rem;
}

/* Les exports : de vrais boutons, qui restent des ancres.

   p:linkButton rend <span class="ui-button…"><a href>…</a></span> — le
   gabarit du bouton vient donc du thème, et la pastille dessinée à la main
   qui vivait ici (.lien-export) n'a plus lieu d'être. L'ancre, elle, reste
   nécessaire : le téléchargement passe par un contrôleur Spring, en GET,
   hors du cycle JSF, pour la même raison que .lien-pdf juste au-dessus.

   Reste ce que le thème PrimeFaces n'écrit pas. Il ne pose qu'une seule
   déclaration sur ce <a> intérieur, « color: inherit » — ni display, ni
   text-decoration. Et cette feuille n'a AUCUN reset global sur `a` : chaque
   classe traite le sien (.rail-item, .lien-pdf, .lien-icone). Sans les deux
   lignes ci-dessous, le libellé du bouton serait souligné et la zone
   cliquable se limiterait au texte au lieu du bouton entier. */
html body .ui-linkbutton > a {
    display: block;
    text-decoration: none;
}

/* Le bloc qui les porte, sous un tableau. Le `gap` remplace le margin-right
   que portait .lien-export : sans lui les deux boutons se touchent. */
html body .exports {
    display: flex;
    flex-wrap: wrap;
    gap: var(--pas-2);
    margin-top: var(--pas-4);
}

/* =========================================================================
   8. Planning
   ========================================================================= */

/* Couleur des blocs du calendrier par statut d'intervention. !important
   parce que FullCalendar pose ses propres background/border en style inline
   sur chaque événement : sans ça la classe passée par le ScheduleEvent
   n'aurait aucun effet visible. */
.creneau-planifiee,
.creneau-en_cours,
.creneau-terminee,
.creneau-a_facturer,
.creneau-facturee {
    color: #fff !important;
    border: none !important;
}

/* Ces cinq-là restent écrites en dur, et ne suivent pas le thème : ce sont
   des couleurs de STATUT, pas de surface. Un créneau terminé est vert
   partout, et l'œil qui a appris le code sur un écran clair le relit à
   l'identique sur un écran sombre. Les assombrir aurait rendu le calendrier
   illisible pour gagner une cohérence dont personne n'a besoin. */
.creneau-planifiee  { background-color: #1264C8 !important; }
.creneau-en_cours   { background-color: #EA8A0B !important; }
.creneau-terminee   { background-color: #059669 !important; }
.creneau-a_facturer { background-color: #7C3AED !important; }
.creneau-facturee   { background-color: #64748B !important; }

/* Intervention sans technicien affecté : la couleur du statut ne dit rien
   du fait que personne n'ira. Un liseré clair la signale sans masquer le
   statut. */
.creneau-sans-technicien {
    box-shadow: inset 0 0 0 2px var(--accent) !important;
}

/* Légende de la barre de filtres, mêmes couleurs que les blocs. */
.legende-creneau {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: .72rem;
    font-weight: 600;
    color: #fff;
}

/* =========================================================================
   9. Fiches (chantier, interventions du technicien)
   ========================================================================= */

html body .ui-card {
    border: 1px solid var(--ardoise-200);
    border-radius: var(--rayon);
    box-shadow: var(--ombre-posee);
    margin-bottom: var(--pas-4);
}

html body .ui-card .ui-card-body {
    padding: var(--pas-5);
}

html body .ui-card .ui-card-title {
    font-size: 1.05rem;
    font-weight: 650;
    color: var(--ardoise-900);
    display: flex;
    align-items: center;
    gap: var(--pas-3);
    flex-wrap: wrap;
}

html body .ui-card .ui-card-subtitle {
    color: var(--ardoise-500);
    font-size: .875rem;
    margin-top: var(--pas-1);
}

html body .ui-card .ui-card-footer {
    padding-top: var(--pas-4);
    margin-top: var(--pas-4);
    border-top: 1px solid var(--ardoise-200);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--pas-2);
}

/* Liseré de gauche : distingue d'un coup d'œil la fiche du jour, ou
   l'en-tête d'un chantier, du reste de la pile. */
html body .fiche-vedette {
    border-left: 3px solid var(--action);
}

.fiche-libelle {
    color: var(--ardoise-500);
    font-size: .78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.fiche-absent {
    color: var(--ardoise-500);
    font-style: italic;
}

/* Information manquante qui, elle, appelle une action — une intervention sans
   technicien n'est pas une donnée absente, c'est un problème à traiter. */
html body .texte-alerte {
    color: var(--danger-texte);
    font-weight: 600;
}

/* Bloc d'avertissement pleine largeur : ressource introuvable, action
   impossible. Une carte plutôt qu'un fond jaune brut. */
.avertissement {
    display: flex;
    align-items: flex-start;
    gap: var(--pas-3);
    padding: var(--pas-4) var(--pas-5);
    background: var(--avertissement-fond);
    border: 1px solid var(--avertissement-bord);
    border-radius: var(--rayon);
    color: var(--avertissement-texte);
}

.avertissement .pi {
    font-size: 1.2rem;
    margin-top: 2px;
}

.fiche-adresse {
    display: flex;
    align-items: center;
    gap: var(--pas-2);
    color: var(--ardoise-500);
    font-size: .9rem;
}

.fiche-compte-rendu {
    margin-top: var(--pas-3);
    padding: var(--pas-3);
    background: var(--ardoise-100);
    border-radius: var(--rayon-petit);
    color: var(--ardoise-700);
    font-size: .9rem;
}

/* Intervention déjà clôturée : un état, pas une action — il se lit, il ne
   se clique pas. */
html body .texte-cloture {
    color: var(--succes-texte);
    font-weight: 600;
}

/* Rappel du contexte en tête de dialogue (« quel client, quel chantier »),
   avant les champs de saisie. */
.rappel-contexte {
    margin-bottom: var(--pas-4);
    padding-bottom: var(--pas-3);
    border-bottom: 1px solid var(--ardoise-200);
}

.equipe-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--pas-2);
    padding: 5px 12px;
    margin: 0 var(--pas-2) var(--pas-2) 0;
    border-radius: 999px;
    background: var(--action-douce);
    color: var(--action-survol);
    font-size: .85rem;
    font-weight: 600;
}

/* =========================================================================
   10. Tableau de bord
   ========================================================================= */

.tuiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: var(--pas-4);
    margin-bottom: var(--pas-5);
}

html body .tuile {
    display: block;
    background: var(--fond-carte);
    border: 1px solid var(--ardoise-200);
    border-radius: var(--rayon);
    box-shadow: var(--ombre-posee);
    padding: var(--pas-4) var(--pas-5);
    text-decoration: none;
    color: inherit;
    transition: box-shadow .15s, transform .15s, border-color .15s;
}

html body a.tuile:hover {
    border-color: var(--action);
    box-shadow: var(--ombre-flottante);
    transform: translateY(-1px);
    text-decoration: none;
}

.tuile-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--pas-2);
    color: var(--ardoise-500);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
}

.tuile-icone {
    width: 30px;
    height: 30px;
    border-radius: var(--rayon-petit);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--action-douce);
    color: var(--action);
    font-size: .95rem;
}

.tuile-valeur {
    display: block;
    margin-top: var(--pas-3);
    font-size: 1.9rem;
    font-weight: 700;
    color: var(--ardoise-900);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.tuile-detail {
    display: block;
    margin-top: var(--pas-1);
    color: var(--ardoise-500);
    font-size: .82rem;
}

/* Une tuile qui appelle une action (retard, seuil franchi) porte sa couleur
   sur l'icône et le chiffre, pas sur tout le cadre : lisible sans crier. */
.tuile-alerte .tuile-icone { background: var(--alerte-fond); color: var(--alerte-texte); }
.tuile-alerte .tuile-valeur { color: var(--alerte-texte); }
.tuile-danger .tuile-icone { background: var(--danger-fond); color: var(--danger-texte); }
.tuile-danger .tuile-valeur { color: var(--danger-texte); }
.tuile-succes .tuile-icone { background: var(--succes-fond); color: var(--succes-texte); }

.tuile-vide {
    color: var(--ardoise-500);
    font-size: .9rem;
    padding: var(--pas-3) 0;
}

/* Deux colonnes sur large écran pour les listes du tableau de bord. */
.colonnes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
    gap: var(--pas-5);
    align-items: start;
}

.liste-simple {
    list-style: none;
    margin: 0;
    padding: 0;
}

.liste-simple li {
    display: flex;
    align-items: baseline;
    gap: var(--pas-3);
    padding: var(--pas-3) 0;
    border-bottom: 1px solid var(--bord-doux);
}

.liste-simple li:last-child {
    border-bottom: 0;
}

.liste-heure {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    color: var(--ardoise-900);
    flex: 0 0 auto;
}

.liste-secondaire {
    color: var(--ardoise-500);
    font-size: .85rem;
    margin-left: auto;
    text-align: right;
}

/* =========================================================================
   11. Connexion
   ========================================================================= */

.connexion {
    display: flex;
    min-height: 100vh;
}

/* Panneau de marque : c'est le premier écran de l'application, il porte
   l'identité. Il disparaît sous 900px, où l'espace doit aller au formulaire. */
.connexion-marque {
    flex: 1 1 45%;
    background: linear-gradient(160deg, var(--rail-fond) 0%, #143257 100%);
    color: #fff;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--pas-6) 8%;
}

/* Taille fluide et non fixe : le nom vient des paramètres, et il peut être
   très long (« ETS. ADAMOU BALLO COMMERCE GENERAL PLOMBERIE/SANITAIRE »).
   À 2rem fixes, un nom pareil débordait du panneau. */
.connexion-marque h1 {
    font-size: clamp(1.35rem, 2.4vw, 2rem);
    font-weight: 650;
    margin: var(--pas-5) 0 var(--pas-3);
    letter-spacing: -.02em;
    line-height: 1.25;
    overflow-wrap: anywhere;
}

.connexion-marque p {
    color: rgba(255, 255, 255, .65);
    font-size: 1rem;
    line-height: 1.6;
    margin: 0;
    max-width: 32ch;
}

.connexion-logo {
    max-height: 56px;
    max-width: 180px;
}

/* Même monogramme que dans le rail, à l'échelle du panneau de marque. */
.connexion-monogramme {
    width: 56px;
    height: 56px;
    font-size: 1.6rem;
}

.connexion-panneau {
    flex: 1 1 55%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--pas-6) var(--pas-5);
}

.connexion-boite {
    width: 100%;
    max-width: 380px;
}

.connexion-boite h2 {
    font-size: 1.35rem;
    font-weight: 650;
    color: var(--ardoise-900);
    margin: 0 0 var(--pas-2);
}

.connexion-intro {
    color: var(--ardoise-500);
    font-size: .9rem;
    margin: 0 0 var(--pas-5);
}

.champ {
    margin-bottom: var(--pas-4);
}

.champ label {
    display: block;
    margin-bottom: 6px;
    font-weight: 600;
    font-size: .82rem;
    color: var(--ardoise-700);
}

.champ input {
    width: 100%;
    box-sizing: border-box;
    padding: .6rem .75rem;
    border: 1px solid var(--ardoise-300);
    border-radius: var(--rayon-petit);
    font-size: .95rem;
    font-family: inherit;
    color: var(--ardoise-900);
    transition: border-color .15s, box-shadow .15s;
}

.champ input:focus {
    outline: 0;
    border-color: var(--action);
    box-shadow: 0 0 0 3px var(--action-douce);
}

html body .bouton-pleine-largeur {
    display: block;
    width: 100%;
    padding: .7rem 1rem;
    background: var(--action);
    color: #fff;
    border: 0;
    border-radius: var(--rayon-petit);
    font: inherit;
    font-weight: 600;
    font-size: .95rem;
    cursor: pointer;
    transition: background-color .15s;
}

html body .bouton-pleine-largeur:hover {
    background: var(--action-survol);
}

/* Signature du concepteur, sous la boîte de connexion. Le filet la détache
   du formulaire : sans lui, elle se lit comme une troisième ligne de celui-ci.

   Le fichier employé ici est celui d'ORIGINE, en Indigo Ténéré — le fond est
   blanc de ce côté-ci de l'écran. C'est le rail, sur fond sombre, qui prend
   l'autre.

   L'écart au libellé vaut la zone de protection exigée par la planche de
   marque : un vide égal au diamètre de l'anneau tout autour du logo. */
.connexion-signature {
    display: flex;
    align-items: center;
    gap: var(--pas-3);
    margin: var(--pas-6) 0 0;
    padding-top: var(--pas-4);
    border-top: 1px solid var(--ardoise-200);
    color: var(--ardoise-500);
    font-size: .75rem;
}

/* 170px pour 34 de haut, au ratio 5/1 du dessin. Comme dans le rail, c'est
   le plancher de 32px de la planche qui fixe la borne basse — pas le confort
   de mise en page. */
.connexion-signature img {
    display: block;
    width: 170px;
}

.connexion-erreur {
    display: flex;
    align-items: center;
    gap: var(--pas-2);
    padding: var(--pas-3);
    margin-bottom: var(--pas-4);
    background: var(--danger-fond);
    border: 1px solid var(--danger-bord);
    border-radius: var(--rayon-petit);
    color: var(--danger-texte);
    font-size: .875rem;
}

/* =========================================================================
   12. Paramètres — bloc logo
   ========================================================================= */

.logo-bloc {
    display: flex;
    align-items: center;
    gap: var(--pas-5);
    flex-wrap: wrap;
}

.logo-apercu {
    max-height: 100px;
    max-width: 220px;
    border: 1px solid var(--ardoise-200);
    border-radius: var(--rayon-petit);
    padding: var(--pas-2);
}

.logo-absent {
    width: 220px;
    height: 100px;
    border: 1px dashed var(--ardoise-300);
    border-radius: var(--rayon-petit);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ardoise-500);
    font-size: .875rem;
}

.aide {
    color: var(--ardoise-500);
    font-size: .8rem;
    margin-top: 6px;
}

/* Une valeur qu'on lit sans pouvoir la modifier, dans une grille où la
   colonne de gauche porte le libellé. Sans elle, l'étiquette et la valeur
   ont le même poids et la grille se lit comme deux colonnes de texte. */
.valeur-forte {
    font-weight: 600;
    color: var(--ardoise-900);
}

/* Bouton d'un formulaire HTML natif (le téléversement du logo passe hors du
   cycle JSF) : habillé comme un p:commandButton, sans en être un. */
html body .bouton-televerser {
    margin-left: var(--pas-2);
    padding: .55rem 1rem;
    background: var(--action);
    color: #fff;
    border: 0;
    border-radius: var(--rayon-petit);
    font: inherit;
    font-weight: 600;
    font-size: .875rem;
    cursor: pointer;
}

html body .bouton-televerser:hover {
    background: var(--action-survol);
}

/* p:panel : mêmes surfaces que les cartes, pour que l'écran Paramètres ne
   détonne pas au milieu des autres. */
html body .ui-panel {
    border: 1px solid var(--ardoise-200);
    border-radius: var(--rayon);
    box-shadow: var(--ombre-posee);
    margin-bottom: var(--pas-5);
}

html body .ui-panel .ui-panel-titlebar {
    background: var(--fond-carte);
    border: 0;
    border-bottom: 1px solid var(--ardoise-200);
    border-radius: var(--rayon) var(--rayon) 0 0;
    padding: var(--pas-4) var(--pas-5);
    color: var(--ardoise-900);
    font-weight: 600;
}

html body .ui-panel .ui-panel-content {
    padding: var(--pas-5);
}

/* =========================================================================
   13. Utilitaires
   ========================================================================= */

.pile-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--pas-2);
}

.pousse-droite { margin-left: auto; }
.texte-discret { color: var(--ardoise-500); }
.texte-fort    { font-weight: 650; color: var(--ardoise-900); }
.montant       { font-variant-numeric: tabular-nums; font-weight: 650; }
.sans-marge    { margin: 0; }

/* =========================================================================
   14. Adaptation aux petits écrans
   ========================================================================= */

@media (max-width: 1280px) {
    .contenu {
        padding: var(--pas-4);
    }
}

/* Tablette : le rail devient un tiroir, ouvert depuis la barre supérieure.
   Le technicien consulte ses interventions sur le terrain — l'espace doit
   aller au contenu. */
@media (max-width: 1024px) {
    .rail {
        transform: translateX(-100%);
        transition: transform .2s ease;
        width: var(--rail-largeur);
        box-shadow: var(--ombre-flottante);
    }

    .tiroir-ouvert .rail {
        transform: translateX(0);
    }

    .zone,
    .rail-replie .zone {
        margin-left: 0;
    }

    html body .barre-tiroir {
        display: block;
    }

    /* Le BOUTON de repli n'a plus de sens quand le rail est un tiroir. Le
       pied, lui, reste : il porte désormais la signature du concepteur, et
       la masquer ici la retirerait de tous les écrans où le rail est un
       tiroir — c'est-à-dire de toute la tablette et de tout le téléphone.
       « html body » pour égaler la spécificité de la règle qui pose le
       display:flex de ce bouton. */
    html body .rail-bascule {
        display: none;
    }

    /* Voile de fermeture : un clic à côté du tiroir le referme. */
    .tiroir-voile {
        display: none;
        position: fixed;
        inset: 0;
        background: rgba(15, 23, 42, .4);
        z-index: 999;
    }

    .tiroir-ouvert .tiroir-voile {
        display: block;
    }

    /* Le rail replié n'existe pas en mode tiroir : on rétablit les libellés,
       sinon un repli mémorisé sur poste fixe donnerait un tiroir muet. */
    .rail-replie .rail-nom,
    .rail-replie .rail-item-libelle,
    .rail-replie .rail-groupe,
    .rail-replie .rail-signature-mot {
        display: revert;
    }

    .rail-replie .rail-item {
        justify-content: flex-start;
    }

    .rail-replie .rail-marque {
        justify-content: flex-start;
        padding: 0 var(--pas-4);
    }
}

@media (max-width: 768px) {
    .contenu {
        padding: var(--pas-3);
    }

    .barre {
        padding: 0 var(--pas-3);
        gap: var(--pas-2);
    }

    /* Sur un téléphone, le nom et le rôle prennent la place du titre ; la
       pastille suffit à identifier le compte. */
    .compte-identite {
        display: none;
    }

    .ecran-entete {
        flex-direction: column;
        gap: var(--pas-2);
        margin-bottom: var(--pas-4);
    }

    .ecran-entete h1 {
        font-size: 1.25rem;
    }

    /* Les grilles de formulaire passent en libellé au-dessus du champ : à
       cette largeur, une colonne de libellés mange la moitié de l'écran.
       Fait en CSS seul, sans toucher au markup des pages. */
    html body .ui-panelgrid.ui-panelgrid-blank .ui-grid-row {
        display: block;
        margin-bottom: var(--pas-4);
    }

    html body .ui-panelgrid.ui-panelgrid-blank .ui-panelgrid-cell {
        display: block;
        width: 100%;
        padding: 0;
    }

    html body .ui-panelgrid.ui-panelgrid-blank .ui-outputlabel {
        display: block;
        margin-bottom: 6px;
    }

    /* Dialogues en plein écran : une fenêtre modale de 480px centrée sur un
       téléphone laisse des marges inutilisables. */
    html body .ui-dialog {
        width: 100vw !important;
        max-width: 100vw;
        height: 100vh !important;
        max-height: 100vh;
        top: 0 !important;
        left: 0 !important;
        border-radius: 0;
    }

    html body .ui-dialog .ui-dialog-content {
        max-height: calc(100vh - 130px);
    }

    /* Cibles tactiles : 44px est le minimum confortable au doigt. */
    html body .ui-button {
        min-height: 44px;
    }

    html body .bouton-rond {
        width: 44px;
        height: 44px;
    }

    .connexion-marque {
        display: none;
    }

    .col-texte {
        max-width: 200px;
    }
}

/* ============================================================
   Bandeau de licence
   ============================================================
   Affiché en tête de la zone de contenu, au-dessus du titre
   d'écran : c'est la première chose lue, et il n'est là que
   lorsqu'il y a quelque chose à faire — préavis, évaluation, ou
   passage en consultation seule.

   Deux tons seulement, et pas de rouge vif pour le préavis : une
   application qui crie pendant les trente derniers jours d'un
   contrat est une application qu'on apprend à ne plus regarder.
   ============================================================ */

.bandeau-licence {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin: 0 0 1.2rem;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    border: 1px solid transparent;
    font-size: 0.92rem;
    line-height: 1.35;
}

.bandeau-licence .pi {
    font-size: 1.1rem;
    flex: 0 0 auto;
}

.bandeau-licence span {
    flex: 1 1 auto;
}

.bandeau-licence.est-preavis {
    background: var(--ambre-fond);
    border-color: var(--ambre-bord);
    color: var(--ambre-texte);
}

.bandeau-licence.est-expiree {
    background: var(--grave-fond);
    border-color: var(--grave-bord);
    color: var(--grave-texte);
}

.bandeau-licence-action {
    flex: 0 0 auto;
    font-weight: 600;
    text-decoration: underline;
    color: inherit;
    white-space: nowrap;
}

/* L'état dans l'écran Licence : même code couleur que le bandeau,
   pour qu'on n'ait pas à relire le texte pour savoir où on en est. */
.licence-etat-valide {
    font-weight: 600;
    color: var(--vert-texte);
}

.licence-etat-expiree {
    font-weight: 600;
    color: var(--grave-texte);
}

@media (max-width: 700px) {
    .bandeau-licence {
        flex-wrap: wrap;
    }
}

/* ------------------------------------------------------------------
   La rentabilité des chantiers
   ------------------------------------------------------------------ */

/* Les deux réserves du rapport : taux horaire non réglé, matière non
   valorisée. Un bandeau et non un p:messages — ce n'est pas le résultat
   d'une action, c'est un état permanent de l'écran tant que le réglage
   manque, et un message que l'on peut fermer disparaîtrait au premier
   filtrage pour ne jamais revenir.

   Le même ambre que .reste-partiel, et pour la même raison qu'à cet
   endroit-là : le rouge est déjà pris par ce qui est en perte, et deux
   rouges côte à côte ne diraient plus lequel des deux signale quoi. */
.bandeau-reserve {
    display: flex;
    align-items: center;
    gap: var(--pas-3);
    margin-bottom: var(--pas-4);
    padding: var(--pas-3) var(--pas-4);
    background: var(--ambre-fond);
    border: 1px solid var(--ambre-bord);
    border-radius: var(--rayon-petit);
    color: var(--ambre-texte);
    font-size: 0.9rem;
}

.bandeau-reserve i {
    flex: 0 0 auto;
}

/* Une marge se juge d'abord au signe. Le seuil est zéro et non un
   pourcentage cible : l'application ne sait pas ce qu'est une bonne marge
   dans ce métier, et un seuil inventé peindrait en rouge des chantiers
   parfaitement sains. */
html body .marge-positive {
    color: var(--vert-texte);
}

html body .marge-negative {
    color: var(--grave-texte);
}

/* Le temps réel a dépassé le temps planifié. Un fond ambre comme les
   réserves, et non du rouge : dépasser une estimation n'est pas une
   perte, c'est un signal — un chantier peut déborder et rester très
   rentable. */
html body .temps-depasse {
    background: var(--ambre-fond);
    border-radius: 4px;
    padding: 1px 6px;
    font-weight: 600;
}

/* Le marqueur posé sur la référence d'un chantier dont la matière n'a
   pas pu être entièrement valorisée. Discret : il attire l'œil sans
   crier, et son title porte le détail. */
html body .marque-incomplet {
    color: var(--alerte-texte);
    cursor: help;
}

/* ------------------------------------------------------------------
   Le dossier de chantier
   ------------------------------------------------------------------ */

/* Le formulaire de dépôt. HTML natif, donc aucune classe PrimeFaces ne
   s'y applique : tout ce qui suit remplace ce que le thème pose
   d'ordinaire sur un p:panelGrid. Une colonne, parce qu'il se remplit
   sur un téléphone à une main, debout dans une salle de bains. */
.depot-formulaire {
    display: flex;
    flex-direction: column;
    gap: var(--pas-2);
    margin-top: var(--pas-3);
}

.depot-formulaire label {
    font-weight: 600;
    font-size: 0.9rem;
}

/* Les champs texte et nombre sont arrivés avec la sortie de caisse : ce
   formulaire ne portait qu'un select et un fichier tant qu'il ne servait
   qu'à déposer une photo de chantier. */
.depot-formulaire select,
.depot-formulaire input[type="file"],
.depot-formulaire input[type="text"],
.depot-formulaire input[type="number"] {
    width: 100%;
    padding: var(--pas-2);
    border: 1px solid var(--bord-natif);
    border-radius: var(--rayon-petit);
    background: var(--fond-carte);
    font: inherit;
}

/* Une cible de 44 px de haut : c'est le minimum tenable au doigt, et
   ce formulaire ne se remplit presque jamais à la souris. */
.depot-formulaire .bouton-televerser {
    align-self: flex-start;
    min-height: 44px;
    margin-top: var(--pas-2);
}

/* Le lien d'une pièce du dossier : l'icône dit le format d'un coup
   d'œil, le nom reste cliquable en entier. */
html body .lien-fichier {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--action);
    text-decoration: none;
}

html body .lien-fichier:hover {
    text-decoration: underline;
}

/* Ce qui est sorti du tiroir autrement que par une vente.
   Détaché du tableau des encaissements par un liseré, et non fondu
   dedans : ce sont deux sens de circulation opposés, et le vendeur qui
   compte son tiroir doit voir lequel il lit. */
.bloc-sorties {
    margin-top: var(--pas-4);
    padding-top: var(--pas-3);
    border-top: 2px solid var(--ardoise-200);
}

.bloc-sorties h4 {
    margin: 0 0 var(--pas-2) 0;
    font-size: 0.95rem;
    color: var(--ardoise-500);
}
