/* ═══════════════════════════════════════════════════════════════════════════
   MISE EN PAGE COMMUNE — ce que le système de design n'a pas (encore), et rien
   d'autre. Aucun composant n'est dessiné ici : ils viennent tous du système.
   Jetons seulement. Chaque règle est une proposition à remonter dans le système
   (_design_system/dynamics-365) — elle n'a pas vocation à rester ici.
   ═══════════════════════════════════════════════════════════════════════════ */

/* `hidden` réaffirmé PARTOUT. Le système le réaffirme classe par classe (coquille.css :
   « tout ce qui pose un display ») ; les écrans que les scripts cachent et montrent portent
   des classes qui posent un display (.vide, .carte, .rang…) — sans cette ligne, ils restent
   visibles. */
[hidden] { display: none !important; }

/* L'application sans flanc (une fiche ouverte depuis le poste) : la carte flottante du système,
   sur une seule colonne. */
.app--seule { grid-template-columns: minmax(0, 1fr); }

/* Deux colonnes qui ne débordent jamais d'un téléphone. La `.grille-2` du système demande 22rem par
   colonne : sous 400 px elle dépasse la toile (qui rogne), et sur une tablette deux cartes de
   chiffres restaient l'une sous l'autre. 18rem : côte à côte dès 37rem de place. */
.deux {
  display: grid; gap: var(--e-4);
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
}
/* Trois et quatre cartes — sans orpheline : quatre de front, ou deux et deux ; trois de front, ou une
   par ligne (jamais « trois et une » ni « deux et une »). Les seuils suivent la largeur de la toile :
   sur les pages à flanc (poste, partenaire, mariés), le flanc en prend 20rem au-dessus de 60rem ;
   au-dessous, il se range en tiroir et la toile reprend toute la largeur. */
.trois  { display: grid; gap: var(--e-4); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.quatre { display: grid; gap: var(--e-4); grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 74.99rem) { .app:not(.app--seule) .quatre { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 64.99rem) { .app:not(.app--seule) .trois { grid-template-columns: minmax(0, 1fr); } }
@media (min-width: 47.5rem) and (max-width: 60rem) { .app:not(.app--seule) .trois { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 59.99rem) { .quatre { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 47.49rem) { .trois { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 30rem) { .quatre { grid-template-columns: minmax(0, 1fr); } }
/* … sauf quatre chiffres (une métrique par carte) : deux par ligne dès 360 px — l'un sous l'autre, quatre
   cartes presque vides faisaient mille pixels. Seul le plus étroit des téléphones (320) les empile. */
@media (min-width: 22.5rem) and (max-width: 30rem) { .quatre:has(> .carte .metrique) { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Deux tiers, un tiers — sur une seule colonne sous 68rem, le point de bascule de la
   mosaïque du système : en dessous, le tiers n'a plus la place d'une carte avec ses actions. */
.deux-tiers { display: grid; gap: var(--e-4); grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
@media (max-width: 68rem) { .deux-tiers { grid-template-columns: minmax(0, 1fr); } }
/* Deux champs côte à côte, l'un sous l'autre sur téléphone. */
.paire { display: grid; gap: var(--e-4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 48rem) { .paire { grid-template-columns: minmax(0, 1fr); } }
.deux > *, .trois > *, .quatre > *, .deux-tiers > *, .paire > * { min-width: 0; }

/* La boîte du tableau (.tbl-boite, celle du système) : un tableau trop large y GLISSE au lieu
   d'être rogné (« ce qui est trop large défile dans son propre conteneur » — SYSTEME.md ; la
   boîte du système coupe avec `overflow: hidden`). Sur téléphone, le système passe en cartes. */
.tbl-boite { overflow-x: auto; }

/* LE GLISSEMENT — jamais de barre de défilement (le porteur : pas de défilement, du glissement,
   avec les flèches gauche et droite en plus). Ce qui est plus large que sa place glisse au doigt,
   au pavé, à la souris qu'on tire ; deux flèches ← → l'avancent ; flèches et fondu ne paraissent
   que du côté où il reste quelque chose. C'est la règle des onglets du système (§144 : rail sans
   barre, .onglets__fleche, fondu du bord qui déborde), étendue aux tableaux et aux rails
   (glisse.js pose le cadre .glisse et ses deux flèches). */
.tbl-boite, .glisse__rail { scrollbar-width: none; overscroll-behavior-x: contain; }
.tbl-boite::-webkit-scrollbar, .glisse__rail::-webkit-scrollbar { display: none; }
.glisse { position: relative; min-width: 0; }
.glisse.deborde-avant > .glisse__rail, .glisse.deborde-apres > .glisse__rail { cursor: grab; }
.glisse__rail.est-tire, .onglets__rail.est-tire { cursor: grabbing; user-select: none; scroll-snap-type: none; }
/* le fondu du système sur le bord qui déborde — pas sur un tableau : sa boîte est une surface
   que le fondu effacerait ; ses flèches suffisent */
.glisse:not(.glisse--tableau).deborde-avant > .glisse__rail { mask-image: linear-gradient(90deg, transparent, #000 3rem); }
.glisse:not(.glisse--tableau).deborde-apres > .glisse__rail { mask-image: linear-gradient(90deg, #000 calc(100% - 3rem), transparent); }
.glisse:not(.glisse--tableau).deborde-avant.deborde-apres > .glisse__rail {
  mask-image: linear-gradient(90deg, transparent, #000 3rem, #000 calc(100% - 3rem), transparent);
}
/* les flèches : le dessin de .onglets__fleche ; autour, la cible pleine (--cible) */
.glisse__fleche {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 2rem; height: 2rem; display: grid; place-items: center;
  border: 0; border-radius: var(--r-puce);
  background: var(--surface); color: var(--encre-douce);
  box-shadow: var(--ombre-2); cursor: pointer;
  transition: background var(--duree) var(--courbe), color var(--duree) var(--courbe);
}
/* la cible pleine grandit vers l'intérieur du rail : posée au bord, elle ne dépasse jamais de lui */
.glisse__fleche::after, .onglets__fleche::after {
  content: ""; position: absolute; top: calc((2rem - var(--cible)) / 2); bottom: calc((2rem - var(--cible)) / 2);
}
.glisse__fleche--avant::after, .onglets__fleche--avant::after { left: 0; right: calc(2rem - var(--cible)); }
.glisse__fleche--apres::after, .onglets__fleche--apres::after { right: 0; left: calc(2rem - var(--cible)); }
.glisse__fleche:hover { background: var(--creuse); color: var(--encre); }
.glisse__fleche[hidden] { display: none; }
.glisse__fleche--avant { left: var(--e-2); }
.glisse__fleche--avant svg { transform: rotate(180deg); }
.glisse__fleche--apres { right: var(--e-2); }
/* sur un tableau, les flèches se posent sur la ligne d'en-tête (sa hauteur : glisse.js) */
.glisse--tableau > .glisse__fleche { top: calc(var(--glisse-tete, 2.75rem) / 2); }
/* Une cellule courte (une date, un pack, un état) ne s'enroule pas sur quatre lignes : le
   tableau garde sa largeur et défile dans sa boîte. Seule la première colonne, celle qui
   nomme la ligne, passe à la ligne. */
.tbl-boite > .tbl th, .tbl-boite > .tbl td:not(:first-child) { white-space: nowrap; }
.tbl-boite > .tbl td:first-child { min-width: 10rem; }
/* les actions d'une ligne restent sur une ligne (le tableau glisse) — une pile de quatre boutons dans
   une cellule étroite faisait des lignes de 190 px à moitié hors de la boîte */
.tbl-boite > .tbl td .rang { flex-wrap: nowrap; }
@media (max-width: 48rem) {
  .tbl-boite { overflow: visible; }
  .tbl-boite > .tbl td:not(:first-child) { white-space: normal; }
  .tbl-boite > .tbl td:first-child { min-width: 0; }
  .tbl-boite > .tbl td .rang { flex-wrap: wrap; }
}

/* La tête d'une carte passe à la ligne quand son titre et son action ne tiennent plus côte à côte
   (la tête du système est un flex sans retour) : le titre garde au moins 12rem, et c'est l'action
   (un lien, un badge) qui passe dessous — jamais le titre qui s'écrase sur trois lignes. */
.carte__tete { flex-wrap: wrap; }
.carte__tete > h3 { flex: 1 1 12rem; min-width: 0; }

/* Une cellule qui porte un badge ET une ligne de détail : en carte, le détail passe dessous au
   lieu de pousser la carte hors de l'écran. Une ligne de détail SEULE reste en face de son
   libellé (« Détail … »). */
@media (max-width: 48rem) {
  /* le libellé à gauche, et tout ce que porte la cellule groupé à droite (« opérateur Yassine ») —
     et non réparti sur la largeur, un badge flottant au milieu de la carte */
  .tbl td::before { margin-right: auto; }
  .tbl td { flex-wrap: wrap; }
  .tbl td > .tbl__second:not(:only-child), .tbl td > .rang:not(:only-child) { flex-basis: 100%; justify-content: flex-end; text-align: right; }
  /* … y compris sous une valeur écrite en texte nu (« 3 » puis « Benjelloun · Tazi · Berrada ») : pour CSS la
     ligne y est l'unique enfant — migrer.php et habilleur.js la marquent (--sous). Seule, elle est la valeur. */
  .tbl td > .tbl__second--sous { flex-basis: 100%; text-align: right; }
  /* Une cellule qui couvre toute la ligne (un détail, « aucun résultat ») n'est pas une paire libellé ·
     valeur : un paragraphe, sans libellé — en flex, sa phrase se défaisait en morceaux. */
  .tbl td[colspan] { display: block; text-align: left; }
  .tbl td[colspan]::before { content: none; }
  /* le libellé garde sa graisse quand la cellule est la principale (td.tbl__princ) : « Confié à » sortait gras */
  .tbl td::before { font-weight: var(--g-normal); }
  /* Trois actions et plus sur une ligne passée en carte (Aperçu, Modifier, Envoyer, Activer) : elles
     remplissent la carte, rangée par rangée — et non trois serrées à droite et la dernière seule dessous. */
  .tbl td > .rang:has(> .btn:nth-child(3)) { flex: 1 1 100%; }
  .tbl td > .rang:has(> .btn:nth-child(3)) > .btn { flex: 1 1 auto; }
}

/* Des champs posés l'un sous l'autre hors d'une pile (les formulaires des maquettes) : l'écart de
   la pile du système entre eux — le champ du système n'a pas de marge, c'est la pile qui espace. */
:is(.carte__corps, .tiroir__corps, .modale__corps, .dedans, form):not(.pile, .paire, .deux, .trois, .quatre, .rang)
  > :is(.champ, .paire, .deux, .metrique, .coche, .code-uu, .depot__zone, .rang, div:has(> .champ))
  + :is(.champ, .paire, .deux, .metrique, .coche, .code-uu, .depot__zone, .rang, .btn, .note, .alerte, p) { margin-top: var(--gap-pile); }

/* Un bandeau posé au-dessus du corps de la toile, hors de sa pile (« 5 crédits de mariage retrouvés ») :
   aligné sur le corps — même retrait, même largeur utile — à chaque largeur. */
.toile__defile > :is(.alerte, .bandeau) { margin: var(--e-4) var(--e-5) 0; max-width: calc(82rem - 2 * var(--e-5)); }
@media (max-width: 48rem) { .toile__defile > :is(.alerte, .bandeau) { margin-inline: var(--e-4); } }

/* Une alerte qui porte son action à droite (« Compris ») : sur un téléphone, l'action passe sous le
   texte, au bout de la ligne — le texte ne gardait que 116 px et s'étirait sur dix lignes. */
@media (max-width: 30rem) {
  .alerte:has(> .alerte__corps + .btn) { flex-wrap: wrap; }
  .alerte:has(> .alerte__corps + .btn) > .alerte__corps { flex-basis: calc(100% - 3rem); }
  .alerte > .alerte__corps + .btn { margin-left: auto; }
}

/* Sur un téléphone, le calendrier du système (441 px de haut) n'a de place ni sous son champ ni
   au-dessus : il sortait de l'écran par le bas. Il monte du bas, comme la modale du système (§115 :
   le pouce est en bas), et défile en lui-même si l'écran est plus bas que lui (téléphone couché). */
@media (max-width: 30rem), (max-height: 30rem) {
  .popover:has(> .dp) {
    left: 0 !important; right: 0 !important; top: auto !important; bottom: 0 !important;
    width: auto; max-width: none; max-height: 92vh; overflow-y: auto;
    border-radius: var(--r-carte) var(--r-carte) 0 0;
  }
  .popover > .dp { margin-inline: auto; }
}

/* Les titres se répartissent en lignes égales (« Ce que vous ne commanderez pas / pour rien » plutôt
   qu'un mot seul dessous) ; un paragraphe évite le mot seul en dernière ligne (« … que vous avez / reçu. »).
   Là où le navigateur sait le faire — ailleurs, rien ne change. */
h1, h2, h3, h4 { text-wrap: balance; }
p, .auth__note, .champ__aide, .metrique__note, .tbl__second, .alerte__corps { text-wrap: pretty; }

/* La tête d'un tiroir qui groupe son titre et une ligne dessous (le nom, puis le numéro) : le groupe
   prend la place libre comme le titre seul du système — le bouton Fermer va au bout de la ligne au lieu
   de coller au nom. */
.tiroir__tete > div:first-child { flex: 1; min-width: 0; }

/* La note des maquettes s'écartait toujours de ce qui la précède (1,1 rem). Devenue une carte creusée du
   système, sans marge, elle touchait le bloc du dessus partout où ce n'est pas une pile qui espace
   (« Ce n'est pas un réglage d'affichage » collée aux deux colonnes, le mot de la formule collé aux modèles). */
:not(.pile, .rang, .deux, .trois, .quatre, .deux-tiers, .paire) > * + .carte.note { margin-top: var(--gap-pile); }
/* `.note` est aussi, dans le système, la note en étoiles (motifs.css : inline-flex) : la carte-note des
   maquettes en héritait — une boîte en ligne, aussi large que son texte (« Les noms et les tarifs… » ne
   prenait que 714 px sur 909) et dont les marges ne fusionnent pas. Elle redevient un bloc. */
.carte.note { display: block; }

/* Des cartes empilées dans la colonne d'une grille (une colonne qui n'est pas une pile) : l'écart
   des grilles entre elles. */
:is(.deux, .deux-tiers, .trois, .quatre, .paire) > :not(.carte, .pile, .rang, .deux, .trois, .quatre, .deux-tiers, .paire)
  > .carte + .carte { margin-top: var(--e-4); }

/* Le titre d'une ligne de liste (la liste du système le coupe par des points de suspension) : une
   phrase entière vaut mieux qu'une phrase coupée — à toutes les largeurs. */
.liste__t strong { white-space: normal; }
/* De même le nom d'un fichier déposé : « recu-virement-cih.pdf » en entier, sur deux lignes s'il le faut
   (coupé à ses tirets, ou n'importe où pour un nom sans coupure), plutôt que « recu-virem… ». */
.depot__nom { white-space: normal; overflow-wrap: anywhere; text-overflow: clip; }

/* La légende d'une progression écrite en <span> (les maquettes) : celle du système, dont les
   entrées sont des <li> — la pastille à distance de son texte. */
.prog__legende > span { display: flex; align-items: center; gap: var(--e-2); }

/* Le rond flottant ne cache jamais la fin de la page : la toile garde sous son dernier bloc la
   place du rond et de sa marge. */
body:has(.rond--flottant) .toile__corps { padding-bottom: calc(var(--cible) + 2 * var(--e-5)); }

/* Une ligne « badge · texte · bouton » (ce qu'il reste à faire, un signal et son action) : sur un
   téléphone, le badge et le bouton se partagent la première ligne, le texte prend toute la largeur
   dessous — au lieu d'une colonne de texte de 150 px entre les deux. */
@media (max-width: 30rem) {
  :has(> .badge + div + .btn) { flex-wrap: wrap; }
  :has(> .badge + div + .btn) > div { order: 3; flex: 1 1 100% !important; }
  :has(> .badge + div + .btn) > .btn { margin-left: auto; }
}
/* Dans une rangée de cartes, l'action qui clôt une métrique (« Voir la liste », « Voir qui ») se pose au
   pied de sa carte : les boutons de la rangée s'alignent, quelle que soit la longueur de la note au-dessus
   (une note sur deux lignes décalait « Voir qui » de 36 px). La note garde un souffle avant l'action. */
:is(.deux, .trois, .quatre) > .carte:has(> .carte__corps > .metrique > .btn:last-child) { display: flex; flex-direction: column; }
:is(.deux, .trois, .quatre) > .carte > .carte__corps:has(> .metrique > .btn:last-child) { flex: 1; display: flex; flex-direction: column; }
:is(.deux, .trois, .quatre) > .carte > .carte__corps > .metrique:has(> .btn:last-child) { flex: 1; }
:is(.deux, .trois, .quatre) > .carte > .carte__corps > .metrique > .btn:last-child { margin-top: auto; }
.metrique > :not(.btn):has(+ .btn:last-child) { margin-bottom: var(--e-2); }

/* Ailleurs, les badges de ces lignes ont une même largeur : les titres partent du même bord (« à faire »,
   « bientôt », « à arbitrer » les décalaient de 16 px d'une ligne à l'autre). */
@media not all and (max-width: 30rem) {
  :has(> .badge + div + .btn) > .badge:first-child { min-width: 4.5rem; justify-content: center; }
}

/* Les actions d'une carte, sur un téléphone étroit : chaque bouton remplit sa ligne (plus d'escalier
   de boutons de largeurs différentes). */
/* (le !important l'emporte sur un « flex:1 » en ligne hérité d'une maquette : une base nulle donnait
   au bouton le plus long la part la plus étroite — « Valider et attribuer Premium » sur quatre lignes) */
/* (de même dans la tête d'une carte : « Coller une liste · Importer un fichier » puis « Ajouter » seul et
   étroit sous eux devient une rangée pleine, puis « Ajouter » en pleine largeur) */
@media (max-width: 30rem) {
  :is(.carte__corps, .carte__tete) > .rang > .btn:not(.btn--icone) { flex: 1 1 auto !important; }
  .carte__tete > .rang:has(> .btn + .btn) { flex: 1 1 100%; }
}

/* Un bouton au libellé long, sur un téléphone étroit : il passe à la ligne au lieu de pousser
   la carte hors de l'écran (le bouton du système ne s'enroule jamais — « pas de troncature
   muette », et pas de défilement de côté). */
@media (max-width: 30rem) {
  .btn:not(.btn--icone) {
    height: auto; min-height: var(--h-controle); padding-block: var(--e-2);
    line-height: var(--i-titre); white-space: normal; text-align: center;
  }
  .btn--sm:not(.btn--icone) { min-height: calc(var(--h-controle) - 0.375rem); padding-block: var(--e-1); }
}

/* L'heure : deux pas-à-pas du système (heures, minutes), chacun avec son unité ; côte à côte quand
   ils tiennent, l'un sous l'autre sur un téléphone étroit. */
.heure { display: flex; flex-wrap: wrap; gap: var(--e-2); }
.heure > .nombre { flex: 1 1 10rem; width: auto; }

/* Le curseur du système : même rail, même pouce, mais une surface de 2rem pour la souris — et la cible
   du système au doigt (44 px, « jamais moins »). `flex: none` : dans un champ, la règle `.champ input`
   (flex: 1 1 0%) écrasait la hauteur, le curseur retombait à 22 px. */
.curseur input[type="range"] { flex: none; height: 2rem; }
@media (max-width: 48rem), (pointer: coarse) { .curseur input[type="range"] { height: var(--cible); } }

/* Un intertitre dans le corps d'une carte (une section d'un long formulaire) : la voix de la
   tête de carte du système, posée dans le corps. */
.intertitre { margin: var(--e-5) 0 var(--e-3); font-family: var(--police-titre); font-size: var(--t-sous); font-weight: var(--g-moyen); }

/* Des onglets posés en tête de carte : alignés sur les cellules de la carte. */
.carte > .onglets { padding: var(--e-2) var(--e-3) 0; margin-bottom: 0; }

/* Ce que la recherche vient d'amener (palette.js) : l'anneau de la désignation du système
   (.est-designe, sans son voile), le temps de le repérer. Une ligne de tableau se lave. */
.est-trouve {
  box-shadow: 0 0 0 3px var(--accent); border-radius: var(--r-controle);
  transition: box-shadow var(--duree-long) var(--courbe), background var(--duree-long) var(--courbe);
}
tr.est-trouve { box-shadow: none; }
tr.est-trouve > td { background: var(--lavis-accent); }

/* Une saisie de recherche (la palette, la recherche d'un combo) : ni la croix ni le dessin du
   navigateur — Échap efface et referme, comme dans le système. */
input[type="search"] { appearance: none; -webkit-appearance: none; }
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration { appearance: none; -webkit-appearance: none; display: none; }

/* Un item de menu qui envoie un formulaire (« Se déconnecter ») : l'item du système, porté par
   un bouton — un lien ne doit jamais pouvoir déconnecter. */
.menu form { margin: 0; }
button.menu__item { width: 100%; border: 0; background: none; font: inherit; text-align: left; cursor: pointer; }

/* L'en-tête sur téléphone, dans l'ordre où on le lit : le titre, ce qui le qualifie (le chapeau,
   la méta), puis les actions. Le système pose les actions à côté du titre et le chapeau dessous :
   à cette largeur, les actions passaient ENTRE le titre et sa phrase. */
@media (max-width: 48rem) {
  .toile .entete { display: flex; flex-direction: column; }
  .toile .entete__haut { display: contents; }
  .toile .entete__titre { order: 1; }
  .toile .entete > :not(.entete__haut) { order: 2; }
  .toile .entete__actions { order: 3; margin-top: var(--e-4); }
}
/* sur un téléphone étroit, les actions de l'en-tête remplissent leur ligne (deux par ligne, ou une
   seule pleine largeur) au lieu de s'aligner en escalier */
@media (max-width: 30rem) { .toile .entete__actions > .btn { flex: 1 1 auto; } }

/* Le fil de la barre : quand la barre d'un téléphone n'a plus la place de le lire, il se tait
   (le titre de la page est juste dessous) plutôt que de finir en « Compt… ». Un fil qui mène
   quelque part (la fiche → « Mariages ») reste, en retour : le système cache sa racine sur
   téléphone, et c'était le seul chemin vers la liste. */
.barre .fil { container-type: inline-size; }
@container (max-width: 8rem) { .fil__feuille { display: none; } }
@media (max-width: 48rem) {
  .fil a.fil__racine { display: inline-flex; align-items: center; gap: var(--e-1); font-size: var(--t-corps); color: var(--encre); }
  .fil a.fil__racine::before {
    content: ""; width: 1rem; height: 1rem; flex: none; background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 6-6 6 6 6'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 6-6 6 6 6'/%3E%3C/svg%3E") center / contain no-repeat;
  }
  .fil:has(a.fil__racine) .fil__feuille { display: none; }
}
/* Le retour (« ← Professionnels ») ne passe jamais sous les boutons de la barre : quand la place manque, la
   flèche seule reste — son nom reste lu, et le titre de la page est juste dessous. */
@container (max-width: 8.5rem) {
  .fil a.fil__racine { gap: 0; }
  .fil a.fil__racine .fil__mot { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
/* Sur le plus étroit des téléphones (320 px), une barre qui porte une action de page (la commande de
   démonstration « Voir la salle d'attente ») resserre ses écarts et laisse tomber le fil, déjà muet à
   cette largeur : l'action tient sur une ligne au lieu de s'enrouler en pastille de deux lignes. */
@media (max-width: 22.5rem) {
  .barre:has(> .rang) { gap: var(--e-1); padding-inline: var(--e-3); }
  .barre:has(> .rang) > .fil:not(:has(a.fil__racine)) { display: none; }
  .barre:has(> .rang) > .recherche { flex: none; }
  .barre > .rang > .btn { padding-inline: var(--e-2); white-space: nowrap; }
  /* l'avatar n'a pas de fond : sa boîte se resserre sur lui (36 px), sa cible reste de 44 px (le calque
     ::after, comme le système agrandit ses cibles, §141.6.1) */
  .barre:has(> .rang) > .rond--avatar { width: 2.25rem; }
  .barre:has(> .rang) > .rond--avatar::after { content: ""; position: absolute; inset: 0 -0.25rem; }
}

/* Une barre de progression dans une cellule garde une longueur lisible — y compris quand
   le système passe la ligne en carte (la cellule devient un flex qui l'écraserait à zéro). */
.tbl .prog__rail { min-width: 6rem; }
/* Un identifiant sous le nom d'une ligne (« zineb-mehdi-22-08-2026 ») reste d'un tenant dans le tableau :
   coupé à ses tirets il se lisait « zineb-mehdi-22-08- » / « 2026 ». (En carte, sur téléphone, il a sa
   ligne entière.) La phrase d'une ligne, elle, se replie comme avant. */
@media not all and (max-width: 48rem) { .tbl .sans-coupure { white-space: nowrap; } }
@media (max-width: 48rem) { .tbl td .prog__rail { width: 8rem; } }

/* LA CIBLE (système, §141.6.1) : la boîte visible d'un lien peut rester petite, la surface
   cliquable ne descend jamais sous --cible. Le système l'applique au fil d'Ariane ; les liens
   des têtes de carte (« Modifier », « Tout voir ») en ont le même besoin. Le calque ne peint rien. */
.lien { position: relative; }
.lien::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: max(100%, var(--cible)); height: max(100%, var(--cible));
  transform: translate(-50%, -50%);
}

/* Le pied du flanc : le nom sur sa ligne, ce qui le qualifie dessous. */
.flanc__pied b { display: block; color: var(--encre); font-size: var(--t-corps); }
.flanc__pied { font-size: var(--t-menu); color: var(--encre-douce); }

/* Un rond du système posé en bas à droite de l'écran (l'aide de la visite guidée) — au-dessus du contenu
   et de la barre (20), sous la liste ouverte d'un champ (40 : il en cachait le coin) et sous tous les
   voiles du système (tiroir du flanc 50/60, menus, palette, modales). */
.rond--flottant {
  position: fixed; right: var(--e-5); bottom: var(--e-5); z-index: 30;
  box-shadow: var(--ombre-3); font-weight: var(--g-fort);
}
/* Sur un téléphone, une tablette, un écran tactile il s’efface quand on descend et revient quand on remonte (flottant.js) : posé en
   permanence dans le coin, il cachait ce qui passait dessous. */
.rond--flottant { transition: transform var(--duree) var(--courbe), opacity var(--duree) var(--courbe), background var(--duree) var(--courbe), color var(--duree) var(--courbe); }
.rond--flottant.est-efface { transform: translateY(calc(100% + var(--e-5))); opacity: 0; pointer-events: none; }

/* Une référence, une empreinte, un numéro : la voix des données. */
.mono { font-family: var(--police-chiffre); font-variant-numeric: tabular-nums; }

/* Un onglet qui est un lien (dans l'application, un onglet est une adresse : la fiche mariage) se dessine
   exactement comme l'onglet-bouton du système. */
a.onglet { display: inline-flex; align-items: center; gap: var(--e-2); text-decoration: none; }

/* ── La lisibilité (phase 7) ───────────────────────────────────────────────────────────────────────────────
   Le système réserve --encre-faible au décor : « décoratif SEULEMENT, jamais du texte » (tokens.css, 2,9:1).
   Ses composants l'emploient pourtant pour de courts textes — l'aide d'un champ, le second niveau d'une cellule,
   le fil, les familles du menu, la méta d'un en-tête, l'étiquette d'une cellule en carte… — à 2,4–2,6:1, sous le
   seuil de 4,5:1 (WCAG AA). Ces TEXTES prennent ici l'encre douce du système (4,95:1, « mesuré ») ; le décor
   (icônes, puces, jauges, flèches) garde l'encre faible. Chaque sélecteur est celui du système, tel quel : même
   poids, posé après — les états du système (survol, actif, coché) restent les siens. Le bord d'une case et le rail
   d'un interrupteur font voir la commande : 3:1 au moins, l'encre douce aussi. */
.nav__famille, .nav__num, .nav__vide, .fil__racine, .fil__sep, .recherche, .entete__meta, .cellule__nom,
.palette__groupe, .palette__res, .palette__vide, .menu__titre, .metrique__note, .champ__suffixe, .champ__aide,
.champ__option, .coche__aide, .pagination__info, .pagination__ell, .tbl__second, .graphe__grille i, .graphe__x,
.graphe__axe, .jeton__val, .ac-nom, .nombre__unite, .zone__compteur, .combo__valeur.est-vide, .opt__txt span,
.combo__vide, .depot__zone > span:last-child, .depot__poids, .chrono__q, .liste__t span,
.date-champ.est-vide .date-champ__lib, .ix-onglets small, .ix-compte,
.champ input::placeholder, .champ textarea::placeholder, .zone textarea::placeholder { color: var(--encre-douce); }
.tbl td::before { color: var(--encre-douce); }            /* l'étiquette d'une cellule, quand le tableau passe en cartes */
.coche__boite { box-shadow: inset 0 0 0 1.5px var(--encre-douce); }
.bascule__rail { background: var(--encre-douce); }
