/* =========================================================================
   BELENOS - complements : modale, rubriques repliables, carte
   A charger APRES app.css, dont il reprend les variables.
   ========================================================================= */

/* ---------- modale : aucun JavaScript, uniquement de l'etat Blazor ---------- */
.fond-modale {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .58);
  z-index: 1040;
}

.modale {
  position: fixed;
  z-index: 1050;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(920px, calc(100vw - 2rem));
  max-height: calc(100vh - 3rem);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--bordure-forte);
  border-radius: 8px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .55);
}

.modale-tete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: .9rem 1.1rem;
  border-bottom: 1px solid var(--bordure);
}
.modale-titre { font-weight: 600; font-size: 1.05rem; }
.modale-soustitre { color: var(--texte-3); font-size: .84rem; }

.modale-fermer {
  background: none;
  border: none;
  color: var(--texte-2);
  font-size: 1.6rem;
  line-height: 1;
  padding: 0 .25rem;
  cursor: pointer;
}
.modale-fermer:hover { color: var(--datis-orange); }

.modale-corps { padding: 1rem 1.1rem; overflow-y: auto; }

.modale-pied {
  display: flex;
  justify-content: flex-end;
  gap: .5rem;
  padding: .75rem 1.1rem;
  border-top: 1px solid var(--bordure);
}

/* ---------- rubriques repliables : <details> natif, sans JavaScript ---------- */
.rubrique {
  border: 1px solid var(--bordure);
  border-radius: 6px;
  background: var(--ground, #333);
  margin-bottom: .7rem;
  overflow: hidden;
}

.rubrique > summary {
  cursor: pointer;
  padding: .6rem .9rem;
  font-weight: 600;
  font-size: .88rem;
  letter-spacing: .01em;
  list-style: none;
  background: var(--surface-2);
  display: flex;
  align-items: center;
  gap: .5rem;
  user-select: none;
}
.rubrique > summary::-webkit-details-marker { display: none; }

/* Chevron pilote par l'attribut open : aucun script a maintenir. */
.rubrique > summary::before {
  content: "";
  width: 0; height: 0;
  border-left: 5px solid var(--datis-orange);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform .12s ease;
  flex: none;
}
.rubrique[open] > summary::before { transform: rotate(90deg); }
.rubrique > summary:hover { color: var(--datis-orange); }

.rubrique > *:not(summary) { padding: .85rem .9rem; }
.rubrique > .table-responsive { padding: 0; }

/* ---------- listes de paires cle / valeur ---------- */
.paires {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: .7rem 1.4rem;
  margin: 0;
}
.paires > div { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.paires dt {
  font-size: .68rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--texte-3);
  font-weight: 600;
}
.paires dd { margin: 0; font-size: .93rem; word-break: break-word; }

/* ---------- carte OpenStreetMap ---------- */
.carte {
  width: 100%;
  height: 260px;
  border: 1px solid var(--bordure);
  border-radius: 6px;
  display: block;
  background: var(--surface-2);
}

/* ---------- divers ---------- */
.ligne-courante { background: rgba(253, 126, 0, .10); }
.ligne-courante td:first-child { box-shadow: inset 3px 0 0 var(--datis-orange); }

@media (max-width: 640px) {
  .modale { width: calc(100vw - 1rem); max-height: calc(100vh - 1rem); }
  .paires { grid-template-columns: 1fr; }
}
/* Complement pour la grille de saisie : ajouter a la fin de belenos-extra.css */

.tableau-saisie .tete-lignee > td {
  background: var(--surface-2);
  border-top: 2px solid var(--bordure-forte);
  padding-top: .5rem;
  padding-bottom: .5rem;
  font-size: .88rem;
}
.tableau-saisie tbody tr:not(.tete-lignee) td:first-child { padding-left: 1.4rem; }
.tableau-saisie .tete-lignee:first-child > td { border-top: none; }

/* =========================================================================
   Page d'accueil
   Sobriete voulue : une marque, un nom, une phrase, une porte d'entree.
   La seule liberte prise est un halo orange tres discret derriere la marque,
   qui donne de la profondeur sans rien ajouter a lire.
   ========================================================================= */

.accueil {
  position: relative;
  min-height: calc(100vh - 8rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.15rem;
  text-align: center;
  padding: 3rem 1.5rem 4rem;
}

.accueil-halo {
  position: absolute;
  top: 22%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(560px, 90vw);
  aspect-ratio: 1;
  background: radial-gradient(circle, rgba(253, 126, 0, .14) 0%, rgba(253, 126, 0, 0) 68%);
  pointer-events: none;
  z-index: 0;
}

.accueil > *:not(.accueil-halo) { position: relative; z-index: 1; }

.accueil-marque {
  width: clamp(88px, 13vw, 132px);
  height: auto;
  opacity: 0;
  animation: accueil-entree .7s cubic-bezier(.2, .7, .3, 1) .05s forwards;
}

.accueil-nom {
  margin: .4rem 0 0;
  font-family: "Segoe UI", system-ui, sans-serif;
  font-weight: 300;
  font-size: clamp(2.6rem, 8vw, 4.4rem);
  /* L'interlettrage large est ce qui distingue un nom de marque d'un simple mot. */
  letter-spacing: .34em;
  text-indent: .34em;
  line-height: 1;
  color: var(--texte, #EDEDED);
  opacity: 0;
  animation: accueil-entree .7s cubic-bezier(.2, .7, .3, 1) .18s forwards;
}

.accueil-filet {
  width: 62px;
  height: 2px;
  background: var(--datis-orange, #FD7E00);
  border-radius: 1px;
  opacity: 0;
  animation: accueil-entree .6s ease .34s forwards;
}

.accueil-baseline {
  margin: 0;
  max-width: 34ch;
  color: var(--texte-2, #ADADAD);
  font-size: 1.02rem;
  line-height: 1.6;
  opacity: 0;
  animation: accueil-entree .6s ease .42s forwards;
}

.accueil-bouton {
  margin-top: .7rem;
  padding-inline: 2.1rem;
  letter-spacing: .04em;
  opacity: 0;
  animation: accueil-entree .6s ease .52s forwards;
}

.accueil-signature {
  margin-top: 2.6rem;
  height: 30px;
  width: auto;
  opacity: 0;
  animation: accueil-signature .8s ease .7s forwards;
}

@keyframes accueil-entree {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes accueil-signature {
  from { opacity: 0; }
  to   { opacity: .55; }
}

/* Une animation d'entree ne doit jamais s'imposer a qui ne la supporte pas. */
@media (prefers-reduced-motion: reduce) {
  .accueil-marque, .accueil-nom, .accueil-filet,
  .accueil-baseline, .accueil-bouton { opacity: 1; animation: none; }
  .accueil-signature { opacity: .55; animation: none; }
}

@media (max-width: 560px) {
  .accueil { min-height: calc(100vh - 6rem); }
  .accueil-nom { letter-spacing: .22em; text-indent: .22em; }
}

/* =========================================================================
   Page d'accueil - version 2
   La marque est desormais vectorielle : nette a toutes les tailles, et elle
   herite de la couleur du texte, ce qui evite un fichier par variante.
   ========================================================================= */

.accueil {
  position: relative;
  min-height: calc(100vh - 8rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .9rem;
  text-align: center;
  padding: 3rem 1.5rem 4rem;
}

.accueil-halo {
  position: absolute;
  top: 24%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(620px, 92vw);
  aspect-ratio: 1;
  background: radial-gradient(circle, rgba(253,126,0,.13) 0%, rgba(253,126,0,0) 66%);
  pointer-events: none;
  z-index: 0;
}
.accueil > *:not(.accueil-halo) { position: relative; z-index: 1; }

.accueil-marque {
  width: clamp(96px, 13vw, 138px);
  height: auto;
  color: var(--datis-orange, #FD7E00);
  opacity: 0;
  animation: accueil-entree .7s cubic-bezier(.2,.7,.3,1) .05s forwards;
}

.accueil-nom {
  margin: .5rem 0 0;
  font-weight: 300;
  font-size: clamp(2.5rem, 8vw, 4.2rem);
  /* L'interlettrage large est ce qui distingue un nom de marque d'un mot. */
  letter-spacing: .34em;
  text-indent: .34em;
  line-height: 1;
  color: var(--texte, #EDEDED);
  opacity: 0;
  animation: accueil-entree .7s cubic-bezier(.2,.7,.3,1) .16s forwards;
}

.accueil-filet {
  width: 58px; height: 2px;
  background: var(--datis-orange, #FD7E00);
  border-radius: 1px;
  opacity: 0;
  animation: accueil-entree .6s ease .3s forwards;
}

/* Le slogan porte l'identite : il merite le corps et la couleur, pas la
   discretion d'une legende. */
.accueil-slogan {
  margin: .25rem 0 0;
  font-size: clamp(1.15rem, 3.2vw, 1.5rem);
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--datis-orange, #FD7E00);
  opacity: 0;
  animation: accueil-entree .6s ease .38s forwards;
}

.accueil-baseline {
  margin: 0;
  max-width: 38ch;
  color: var(--texte-3, #8A8A8A);
  font-size: .95rem;
  line-height: 1.6;
  opacity: 0;
  animation: accueil-entree .6s ease .46s forwards;
}

.accueil-bouton {
  margin-top: 1rem;
  padding-inline: 2.2rem;
  letter-spacing: .04em;
  opacity: 0;
  animation: accueil-entree .6s ease .56s forwards;
}

.accueil-signature {
  margin-top: 2.8rem;
  height: 26px;
  width: auto;
  opacity: 0;
  animation: accueil-signature .8s ease .72s forwards;
}

@keyframes accueil-entree {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes accueil-signature { from { opacity: 0; } to { opacity: .5; } }

/* Une entree en scene ne doit jamais s'imposer a qui l'a desactivee. */
@media (prefers-reduced-motion: reduce) {
  .accueil-marque, .accueil-nom, .accueil-filet, .accueil-slogan,
  .accueil-baseline, .accueil-bouton { opacity: 1; animation: none; }
  .accueil-signature { opacity: .5; animation: none; }
}

@media (max-width: 560px) {
  .accueil { min-height: calc(100vh - 6rem); }
  .accueil-nom { letter-spacing: .2em; text-indent: .2em; }
}

/* =========================================================================
   Prospection : pastilles d'initiales et fil de commentaires
   ========================================================================= */

.pastille-initiales {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  height: 1.5rem;
  padding: 0 .35rem;
  border-radius: 4px;
  background: rgba(253, 126, 0, .16);
  color: var(--datis-orange, #FD7E00);
  font-family: "IBM Plex Mono", ui-monospace, Menlo, monospace;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .06em;
}

.fil { display: flex; flex-direction: column; gap: .85rem; max-height: 52vh; overflow-y: auto; }

.fil-item {
  border-left: 2px solid var(--bordure-forte, #5C5C5C);
  padding-left: .85rem;
}
.fil-item:first-child { border-left-color: var(--datis-orange, #FD7E00); }

.fil-tete {
  display: flex;
  align-items: center;
  gap: .55rem;
  margin-bottom: .35rem;
  color: var(--texte-3, #8A8A8A);
}

/* Le texte vient de courriels colles : on preserve les retours a la ligne
   sans imposer une police a chasse fixe, illisible sur un long paragraphe. */
.fil-texte {
  margin: 0;
  font-family: inherit;
  font-size: .88rem;
  line-height: 1.55;
  color: var(--texte-2, #ADADAD);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 22rem;
  overflow-y: auto;
}

/* =========================================================================
   Type de tiers
   Palette FROIDE et volontairement distincte : l'orange appartient a la
   marque, le rouge et le vert signalent un etat. Un type de tiers n'est ni
   l'un ni l'autre -- c'est une categorie, et elle merite son propre registre.
   ========================================================================= */
.tiers {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  font-family: "IBM Plex Mono", ui-monospace, Menlo, monospace;
  font-size: .63rem;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: .16rem .45rem;
  border-radius: 3px;
  white-space: nowrap;
}
.tiers::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

.tiers-client      { color: #7FC8F8; background: rgba(127, 200, 248, .13); }
.tiers-prospect    { color: #C9A0DC; background: rgba(201, 160, 220, .13); }
.tiers-fournisseur { color: #8FD3C7; background: rgba(143, 211, 199, .13); }
.tiers-autre       { color: #ADADAD; background: rgba(173, 173, 173, .12); }


/* ===== BELENOS liv6 ======================================================
   Ne pas dupliquer ce bloc : le script d'installation le detecte a ce marqueur.

   1. Le cadre orange autour du titre de page.
      Le gabarit Blazor place <FocusOnNavigate Selector="h1" /> dans Routes.razor :
      apres chaque navigation, le premier <h1> recoit le focus pour que les
      lecteurs d'ecran annoncent la nouvelle page. C'est une bonne chose et on
      la garde -- mais notre regle :focus-visible dessinait un contour orange
      de 2 px autour du titre, visible une seconde a chaque changement de page.
      On neutralise le contour UNIQUEMENT sur cette cible programmatique
      (tabindex="-1"), sans toucher au focus clavier, qui reste indispensable.
   ========================================================================= */

h1[tabindex="-1"]:focus,
h1[tabindex="-1"]:focus-visible,
[tabindex="-1"]:focus-visible {
  outline: none;
}

/* 2. Le survol d'un lien de marque ne doit pas non plus dessiner de cadre
      quand il est atteint a la souris. Le clavier, lui, garde le sien. */
.navbar-brand:focus:not(:focus-visible) { outline: none; box-shadow: none; }

/* 3. Les animations d'entree de l'accueil ne jouent qu'une fois et respectent
      le reglage systeme "reduire les animations". */
@media (prefers-reduced-motion: reduce) {
  .accueil-marque,
  .accueil-nom,
  .accueil-filet,
  .accueil-slogan,
  .accueil-baseline,
  .accueil-bouton,
  .accueil-signature {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}


/* ===== BELENOS liv39 =====================================================
   Ne pas dupliquer ce bloc : le script d'installation le detecte a ce
   marqueur, exactement comme celui de la livraison 6.

   Ce fichier n'est PAS livre en entier, et c'est delibere. Trois blocs y
   ont ete AJOUTES au fil des livraisons -- les pastilles du CRM en 4, la
   grille de saisie des montants, et la correction du cadre orange en 6 --
   sans qu'aucune ne le reemette au complet. Le reecrire depuis une vieille
   copie aurait efface les trois d'un coup : la colonne Client / Prospect /
   Fournisseur de la liste des tiers, les initiales des utilisateurs, les
   separateurs de la grille des montants, et le cadre orange serait revenu
   autour du titre a chaque changement de page.

   On ajoute a la fin. On ne remplace rien.
   ========================================================================= */

/* --- les actions d'une rubrique ------------------------------------------
   Elles vivent DANS l'entete, poussees a droite, et n'apparaissent que
   lorsque la rubrique est ouverte.

   Avant, chaque rubrique commencait par une ligne ne portant qu'un bouton :
   "Ajouter un contact", "Recalculer", "Modifier". Trois lignes de trente-six
   pixels sur une fiche qui en compte quatorze, soit une demi-page de boutons
   qu'on ne cherche qu'une fois sur dix. Dans l'entete, ils ne coutent rien :
   la place existe deja, et elle etait vide a droite du titre.

   Repliee, une rubrique n'affiche plus ses actions : agir sur un contenu
   qu'on ne voit pas est une facon assez sure de se tromper de rubrique.

   Le bouton doit porter @onclick:stopPropagation="true" ET
   @onclick:preventDefault="true" : sans eux, le clic est aussi une activation
   du <summary>, qui replie la rubrique dans le meme geste. Jamais
   preventDefault sur un <a> : cela annulerait sa navigation. */
.rubrique > summary .actions {
  margin-left: auto;
  display: none;
  align-items: center;
  gap: .4rem;
  font-weight: 400;
  letter-spacing: 0;
}

.rubrique[open] > summary .actions { display: flex; }

/* Le survol de l'entete tire le titre vers l'orange ; les boutons gardent
   leur propre couleur, sinon leur libelle disparaitrait sur leur fond.

   Et surtout : .btn-secondary a le meme fond que le <summary>. Pose la, un
   bouton secondaire devenait un mot gris flottant, sans forme ni bord -- on ne
   le voyait pas, donc on ne cliquait pas dessus. On lui redonne un relief a
   nous, en blanc translucide : il se detache quel que soit le fond derriere.
   L'override est reserve a .btn-secondary ; un .btn-primary pose dans une
   entete garde son orange. */
.rubrique > summary .actions .btn-secondary {
  color: var(--texte, #EDEDED);
  background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .38);
}

.rubrique > summary .actions .btn-secondary:hover {
  color: #fff;
  background: rgba(255, 255, 255, .22);
  border-color: var(--datis-orange, #FD7E00);
}

.rubrique > summary .actions .btn-secondary:disabled {
  opacity: .55;
  background: rgba(255, 255, 255, .05);
}

.rubrique > summary .actions .btn-sm {
  --bs-btn-padding-y: .08rem;
  --bs-btn-padding-x: .5rem;
  font-size: .76rem;
}

.rubrique > summary .actions .texte-faible { font-size: .72rem; }

/* ---------- pastille "preventif" ----------
   app.css ne porte que .etat-ok, .etat-neutre et .etat-alerte -- trois etats
   d'avancement. Le preventif n'en est pas un : c'est une NATURE
   d'intervention. Il lui faut donc une quatrieme famille, qui ne se confonde
   ni avec le gris de "non terminee" ni avec le vert de "rapport envoye".

   Elle est GLOBALE, ici, et non recopiee dans chaque .razor.css : deux copies
   isolees, c'est deux bleus qui divergent a la premiere retouche. */
.etat-info {
  background: rgba(126, 166, 240, .16);
  color: #9EBBF5;
}


/* ===== BELENOS liv41 =====================================================
   Ne pas dupliquer ce bloc : le script d'installation le detecte a ce
   marqueur, comme ceux des livraisons 6 et 39.

   Ce fichier n'est PAS livre en entier. Des blocs y ont ete empiles au fil
   des livraisons -- les pastilles du CRM en 4, la grille des montants, le
   cadre orange en 6, les actions de rubrique en 39. On ajoute a la fin.
   ========================================================================= */

/* --- l'erreur d'une fenetre, DANS la fenetre ------------------------------
   Elle etait posee en haut de la page, derriere la modale et hors de l'ecran.
   Le bouton paraissait ne rien faire ; l'explication attendait a deux ecrans
   de defilement, et personne ne pense a remonter. */
.modale-erreur {
  margin-bottom: 1rem;
  padding: .6rem .8rem;
  border-radius: .35rem;
  font-size: .87rem;
  line-height: 1.45;
  background: rgba(255, 138, 138, .13);
  border-left: 3px solid #FF8A8A;
  color: var(--texte, #EDEDED);
}

/* --- la date en clair, sous un champ date ---------------------------------
   <input type="date"> s'affiche dans la langue du NAVIGATEUR, pas dans celle
   de la page : sur un Windows anglais, Chrome ecrit 04/01/2026 pour le
   1er avril. Aucun attribut HTML ne change cela. On ne se bat pas contre le
   navigateur -- on redit la date dessous, en francais, sans ambiguite. */
.date-claire {
  display: block;
  margin-top: .15rem;
  font-size: .72rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--texte-3, #8A8A8A);
  font-variant-numeric: tabular-nums;
}

/* --- le cout moyen par objet, dans l'entete du perimetre ------------------
   Discret : c'est un reperage, pas un chiffre a lire en premier. Il vit a
   cote du compte d'objets, la ou l'oeil est deja. */
.cout-objet {
  font-size: .78rem;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--datis-orange, #FD7E00);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --- bascule liste / saisie libre sous un champ --------------------------- */
.lien-choix {
  align-self: flex-start;
  font-size: .72rem;
  text-transform: none;
  letter-spacing: 0;
  text-decoration: underline;
  color: var(--datis-orange, #FD7E00);
}

.aide-champ {
  display: block;
  margin-top: .15rem;
  font-size: .72rem;
  text-transform: none;
  letter-spacing: 0;
  line-height: 1.35;
}

/* --- l'entete d'une rubrique doit pouvoir passer a la ligne ---------------
   Depuis la 39 elle porte des actions a droite ; la 41 y ajoute le cout par
   objet. Titre + compteur + cout + boutons sur une seule ligne inflexible,
   dans un conteneur en overflow:hidden, cela finit par se faire rogner sur un
   portable. */
.rubrique > summary { flex-wrap: wrap; }


/* ===== BELENOS liv43 =====================================================
   Ne pas dupliquer ce bloc : le script d'installation le detecte a ce
   marqueur, comme ceux des livraisons 6, 39 et 41.

   Ce fichier n'est PAS livre en entier : des blocs y ont ete empiles depuis
   la livraison 2. On ajoute a la fin.
   ========================================================================= */

/* --- l'en-tete d'une page -------------------------------------------------
   Les boutons touchaient le bord haut de la zone de contenu.

   Ce n'est pas qu'ils manquent de marge : c'est que la LIGNE d'en-tete n'en a
   pas. Le titre, lui, a le jambage de sa police pour respirer ; un bouton n'a
   rien, il commence a son pixel zero. D'ou une classe, et non un correctif
   par page : le defaut est le meme partout, la solution doit l'etre aussi.

   align-items: flex-start et non center : quand le titre porte un
   sous-titre, centrer les boutons les fait descendre a mi-hauteur du bloc,
   loin du titre auquel ils se rapportent. */
.entete-page {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: .7rem 1.2rem;
  padding-top: .45rem;
  margin-bottom: 1rem;
}

/* Le groupe de boutons descend d'un cheveu : aligne au pixel sur la premiere
   ligne du titre, il parait plus haut que lui -- une majuscule commence sous
   le haut de sa boite. */
.entete-page .actions-page {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  padding-top: .15rem;
}


/* ===== BELENOS liv44 =====================================================
   Ne pas dupliquer ce bloc : le script d'installation le detecte a ce
   marqueur, comme ceux des livraisons 6, 39, 41 et 43.

   Ce fichier n'est PAS livre en entier : des blocs y ont ete empiles depuis
   la livraison 2. On ajoute a la fin.
   ========================================================================= */

/* --- le quatrieme etat : "a verifier" -------------------------------------

   app.css porte --ok et --alerte, et rien entre les deux. Or la page Sante
   distingue trois choses qui n'appellent pas le meme geste :

     - tout va bien             -> on referme la page ;
     - il y a un probleme       -> on s'arrete et on le traite ;
     - il y a un point A VOIR   -> on le note, on continue.

   Sans le troisieme, un objet a trier et une sauvegarde en echec seraient
   dessines de la meme couleur, et la couleur cesserait de vouloir dire
   quelque chose. Un ecran qui crie tout le temps ne crie plus.

   La variable est GLOBALE, ici, et non recopiee dans chaque .razor.css :
   deux copies isolees, c'est deux ambres qui divergent a la premiere
   retouche. C'est la lecon du .etat-info de la 39. */
:root {
  --attention: #E0A33C;
  --attention-fond: rgba(224, 163, 60, .15);
}

.etat-attention {
  background: var(--attention-fond);
  color: var(--attention);
}

/* --- le bouton Supprimer des trois fiches ---------------------------------

   .texte-alerte sur un .btn est une combinaison neuve dans le projet, et elle
   ne tient pas seule : Bootstrap pose .btn:hover { color: ... }, de
   specificite (0,2,0), contre (0,1,0) pour .texte-alerte. Le rouge disparait
   donc au survol -- au moment precis ou l'on vise le bouton.

   Le :hover est repete ici pour egaliser la specificite. Ce n'est pas une
   coquetterie : un bouton de suppression qui perd sa couleur quand on
   l'approche ressemble a n'importe quel autre bouton au dernier instant. */
.btn.texte-alerte,
.btn.texte-alerte:hover,
.btn.texte-alerte:focus { color: var(--alerte); }

/* --- l'erreur d'une fenetre reste visible meme apres defilement -----------

   La 41 l'a mise EN TETE du corps de la fenetre, pour la bonne raison : le
   corps defile, et une liste de trente machines aurait repousse un message de
   pied sous la ligne de flottaison.

   Il manquait la moitie du raisonnement. En tete d'un conteneur qui defile,
   le message sort par le HAUT des qu'on a fait defiler avant de cliquer -- et
   c'est exactement ce qu'on fait : on descend lire le tableau des contrats
   d'une licence, puis on clique sur Supprimer, qui vit dans le pied FIXE. Le
   refus s'affichait alors hors de vue, et le bouton paraissait ne rien faire.

   position: sticky le colle en haut de la zone visible du corps. Le fond
   devient opaque : translucide, le texte defilant se lirait au travers.

   Les marges negatives compensent le padding de .modale-corps pour que le
   bandeau aille d'un bord a l'autre -- sinon un liset de fond apparait de
   chaque cote au moment du collage. */
.modale-erreur {
  position: sticky;
  top: -1rem;
  z-index: 2;
  margin: -1rem -1.1rem 1rem;
  padding: .7rem 1.1rem;
  border-radius: 0;
  background: #4A2A2A;
  border-left: 3px solid #FF8A8A;
}

/* =============================================================================
   BELENOS liv50 -- le serveur de licences DATIS
   =============================================================================

   Ce bloc est AJOUTE a belenos-extra.css. Le marqueur ci-dessus sert a
   l'installateur : la 50 le posait, la 50.1 l'a REMPLACE, la 50.2 le remplace
   a nouveau. Un bloc de plus laisserait vivre les regles que la correction
   supprime -- pour toujours.

   CE QUI A ETE CORRIGE EN 50.1, ET POURQUOI
   -----------------------------------------
   La premiere version de ce bloc etait ecrite pour un FOND CLAIR : des
   transparences de NOIR pour les bordures, du blanc pour les surfaces, et deux
   teintes sombres pour les etats. BELENOS est sombre. Resultat a l'ecran :
   bordures invisibles, texte gris fonce sur fond gris fonce, cartes blanches.

   Rien ici ne pose plus une couleur absolue pour une surface : tout passe par
   les variables de la charte, comme le reste de belenos-extra.css. Les seules
   valeurs fixes sont les teintes d'etat, et ce sont celles que le projet a
   deja validees contre le fond de la charte a la livraison 49.

   Pourquoi ces classes sont ICI et non dans une feuille de page : Blazor isole
   le style d'un composant, et .clef-valeur sert a DEUX ecrans -- la fiche d'une
   licence, qui dicte une clef, et la fiche d'une application, qui affiche un
   secret. Deux copies isolees finiraient par diverger, et deux valeurs qu'on
   lit au telephone doivent se presenter exactement pareil.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   LA CASE A COCHER SOUS UNE RUBRIQUE.

   belenos-extra.css pose ".rubrique > *:not(summary) { padding: .85rem .9rem }",
   ce qui ECRASE le padding-left de 1.5em que Bootstrap donne a .form-check. Or
   .form-check-input porte "margin-left: -1.5em" : la case partait donc a gauche
   du cadre, et ".rubrique { overflow: hidden }" la coupait net.

   La regle porte sur .rubrique > .form-check, de specificite superieure, et
   rend au conteneur la place que la case occupe en negatif. Elle vaut pour
   toutes les rubriques du logiciel, pas seulement celles de la 50 : le meme
   piege attend la prochaine.
   -------------------------------------------------------------------------- */
.rubrique > .form-check {
    padding: .35rem .9rem .35rem calc(.9rem + 1.5em);
}

.rubrique > .form-check:first-of-type { padding-top: .85rem; }
.rubrique > .form-check:last-of-type  { padding-bottom: .85rem; }

/* La ligne de tableau cliquable en entier : la cible est la ligne, et non un
   lien de trois caracteres dans la premiere colonne. Le survol ECLAIRCIT --
   une transparence de noir ne se verrait pas sur un fond deja sombre. */
.ligne-cliquable {
    cursor: pointer;
}

.ligne-cliquable:hover {
    background: rgba(255, 255, 255, .05);
}

tr.ligne-cliquable.choisie {
    background: rgba(253, 126, 0, .10);
}

tr.ligne-cliquable.choisie td:first-child {
    box-shadow: inset 3px 0 0 var(--datis-orange, #FD7E00);
}

/* -----------------------------------------------------------------------------
   LE BLOC D'UNE VALEUR QU'ON DICTE AU TELEPHONE.

   Tout ce qui suit sert une seule chose : qu'une personne lise seize caracteres
   a voix haute sans se tromper, pendant qu'une autre les tape a l'autre bout de
   la France. La chasse fixe, la taille et l'espacement entre les caracteres ne
   sont pas decoratifs -- ils sont ce qui distingue un 0 d'un O a l'oral.
   -------------------------------------------------------------------------- */
.clef-bloc {
    border: 1px solid var(--bordure, #555);
    border-left: 3px solid var(--datis-orange, #FD7E00);
    border-radius: .5rem;
    padding: .7rem .9rem;
    margin-bottom: .9rem;
    background: var(--surface-2, #2f2f2f);
}

.clef-libelle {
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--texte-3, #9a9a9a);
    margin-bottom: .2rem;
}

.clef-valeur {
    font-family: ui-monospace, "Cascadia Mono", "Consolas", monospace;
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: .12em;
    line-height: 1.3;
    margin-bottom: .35rem;

    /* Selectionnable d'un double-clic, tirets compris. */
    user-select: all;
    word-break: break-all;
}

/* Le secret d'activation fait quarante-quatre caracteres de base64 : a la
   taille d'une clef il deborde de son cadre. Il n'est pas dicte, il est
   copie -- donc plus petit, et sans espacement de lecture. */
.clef-valeur.secret {
    font-size: .95rem;
    letter-spacing: .02em;
}

/* -----------------------------------------------------------------------------
   LE JOURNAL D'EVENEMENTS. Il sert a la fiche d'une licence, a celle d'une
   application et a la page des cles : trois pages, donc la feuille commune.
   -------------------------------------------------------------------------- */
.journal {
    list-style: none;
    padding: 0;
    margin: 0;
}

.journal li {
    display: grid;
    grid-template-columns: 9rem 9rem 1fr auto;
    gap: .5rem;
    align-items: baseline;
    padding: .3rem 0;
    border-bottom: 1px solid var(--bordure, #555);
    font-size: .84rem;
}

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

/* Sur un ecran etroit la grille de quatre colonnes ecrase le detail :
   on repasse en lignes plutot que de couper les mots. */
@media (max-width: 48rem) {
    .journal li {
        grid-template-columns: 1fr;
        gap: .1rem;
    }
}

/* -----------------------------------------------------------------------------
   L'AIDE D'UN CHAMP, POSEE DIRECTEMENT SOUS UNE RUBRIQUE.

   Le composant Aide porte son propre style isole. Ces deux regles-ci ne peuvent
   pas y vivre : elles decrivent le rapport entre l'aide et CE QUI L'ENTOURE, et
   l'isolation de Blazor s'arrete au composant.

   Sans elles, la regle ".rubrique > *:not(summary) { padding: .85rem .9rem }"
   pose presque un centimetre entre une case a cocher et l'aide qui l'explique.
   Les deux se liraient alors comme deux choses sans rapport.

   LE SELECTEUR NOMME L'ELEMENT, "details.aide-champ", et pas seulement la
   classe. Ce n'est pas du confort. La classe historique .aide existe deja sur
   trente-six paragraphes du logiciel, dont SEPT sont enfants directs d'une
   rubrique -- cinq sur la fiche d'un contrat, deux sur celle d'un document --
   et "aide-champ" elle-meme est deja portee une fois, par un <span> de
   ContratFiche. Tous sont des <p> ou des <span> ; ceci est un <details>. C'est
   l'element, et lui seul, qui garantit qu'aucun ecran existant ne bouge.
   -------------------------------------------------------------------------- */
.rubrique > details.aide-champ {
    padding: 0 .9rem .6rem;
}

/* Une aide qui suit immediatement un champ n'a pas besoin de s'en decoller :
   c'est le meme objet. */
.rubrique > .form-check + details.aide-champ {
    padding-top: 0;
    margin-top: -.2rem;
}

/* -----------------------------------------------------------------------------
   LE CHAMP QUI PREND TOUTE LA LARGEUR DE LA GRILLE.

   .paires est une grille "auto-fit, minmax(230px, 1fr)". Une adresse HTTP ou une
   cle publique en base64 tient mal dans 230 pixels, et .grandit -- que le projet
   ecrit depuis longtemps -- n'avait aucun effet DANS cette grille : il n'y etait
   defini que pour les rangees en flex des autres ecrans.

   Sur un ecran etroit la grille retombe a une seule colonne, et la regle devient
   sans objet d'elle-meme.
   -------------------------------------------------------------------------- */
.paires > .grandit {
    grid-column: 1 / -1;
}
