/*
 * KEneYa WorkFlow — feuille de style unique.
 *
 * Conception mobile/tablette d'abord : la plupart des postes sont des
 * tablettes. Zones tactiles d'au moins 44px, aucune interaction qui depende
 * du survol, contrastes eleves pour un usage en salle. Le survol enrichit,
 * il ne conditionne jamais.
 *
 * Servie telle quelle depuis public/ : pas de pipeline de build front, le
 * serveur peut n'avoir aucune connectivite internet.
 *
 * L'ordre du fichier : jetons, base, primitives partagees, puis les
 * composants metier. Un composant ne redefinit jamais une couleur ou un
 * espacement en dur : il pioche dans les jetons ci-dessous.
 */

:root {
    /* --- Couleurs -------------------------------------------------------
       Deux teintes portent la marque, et chacune a un role fixe :

         - le MARINE structure et agit — entree active de la barre laterale,
           bouton primaire, badge d'icone en tete de carte, filets de titre ;
         - la SARCELLE signe et met en valeur — monogramme, avatar, etats
           positifs, filets des documents imprimes.

       Les intervertir ferait perdre la lecture : sur un ecran, ce qui est
       marine se clique, ce qui est sarcelle se remarque. Le marine reste
       volontairement desature et sombre — c'est un ecran de service allume
       douze heures par jour, pas une page d'accueil.

       Les noms `--bleu*` sont conserves : deux mille lignes de regles s'y
       referent, et les renommer aurait noye le changement de palette dans un
       diff illisible. Seules les valeurs changent, et tout suit. */
    --bleu: #123f60;
    --bleu-vif: #1a5b86;
    --bleu-fonce: #0e3049;
    --bleu-nuit: #0a2439;
    --bleu-clair: #e6eef6;
    --bleu-pale: #f2f7fb;

    /* La sarcelle de la marque. `--vert` la reprend plutot que de garder un
       vert distinct : un bandeau de succes d'une teinte et un avatar d'une
       autre, a deux centimetres l'un de l'autre, se lisent comme une erreur
       d'impression. Une seule teinte pour « tout va bien » et pour « c'est
       nous ». */
    --sarcelle: #16806a;
    --sarcelle-vif: #1a9a7f;
    --sarcelle-fonce: #0f5f4e;
    --sarcelle-clair: #e6f4ef;

    --vert: var(--sarcelle);
    --vert-clair: var(--sarcelle-clair);
    --ambre: #9a5b00;
    --ambre-clair: #fdf1dd;
    --rouge: #9c1f22;
    --rouge-clair: #fbeaea;

    /* Fond de page : un bleu-gris tres clair, pas un gris neutre. C'est lui
       qui fait ressortir le blanc des cartes ; sur un gris neutre elles
       paraissent grises a leur tour. */
    --fond: #eef3f8;

    --gris-900: #14191d;
    --gris-800: #2a3339;
    --gris-700: #4a555d;
    --gris-500: #6f7a83;
    --gris-400: #97a2aa;
    --gris-300: #d3dbe0;
    --gris-200: #e6ebee;
    --gris-100: #f1f5f7;
    --gris-50: #f7fafb;
    --blanc: #ffffff;

    /* --- Typographie ----------------------------------------------------
       Base a 16px : le 17px d'origine faisait deborder les libelles sur
       telephone et gonflait chaque carte sans rien gagner en lisibilite. */
    --texte-xs: .75rem;
    --texte-sm: .8125rem;
    --texte-base: .9375rem;
    --texte-md: 1rem;
    --texte-lg: 1.125rem;
    --texte-xl: 1.375rem;
    --texte-2xl: 1.75rem;

    /* --- Espacement, sur une echelle de 4px ------------------------------ */
    --e1: .25rem;
    --e2: .5rem;
    --e3: .75rem;
    --e4: 1rem;
    --e5: 1.25rem;
    --e6: 1.5rem;
    --e8: 2rem;
    --e10: 2.5rem;

    /* --- Rayons ---------------------------------------------------------- */
    --rayon-sm: 6px;
    --rayon: 10px;
    --rayon-lg: 14px;
    --rayon-pilule: 999px;

    /* --- Elevation -------------------------------------------------------
       Deux ombres superposees : une courte pour poser l'objet, une longue et
       tres douce pour le detacher du fond. Une ombre unique fait toujours
       autocollant. */
    --ombre: 0 1px 2px rgba(11, 40, 60, .05), 0 1px 3px rgba(11, 40, 60, .04);
    --ombre-1: var(--ombre);
    --ombre-2: 0 2px 4px rgba(11, 40, 60, .06), 0 6px 16px rgba(11, 40, 60, .07);
    --ombre-3: 0 8px 16px rgba(11, 40, 60, .08), 0 20px 40px rgba(11, 40, 60, .12);
    --anneau: 0 0 0 3px rgba(26, 91, 134, .30);

    /* --- Mouvement -------------------------------------------------------
       Court et decelere : sur une tablette, une transition longue donne
       l'impression que l'application rame. */
    --duree: 140ms;
    --duree-lente: 240ms;
    --courbe: cubic-bezier(.4, 0, .2, 1);
    --transition: var(--duree) var(--courbe);

    --touch: 44px;
    --largeur-max: 1440px;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: var(--texte-md);
    line-height: 1.5;
    color: var(--gris-900);
    background: var(--fond);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Titres resserres : au-dela de 1.25 d'interligne, un titre court flotte. */
h1, h2, h3 { margin: 0; line-height: 1.2; letter-spacing: -.011em; }

::selection { background: var(--bleu-clair); color: var(--bleu-fonce); }

.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Chiffres de meme chasse : un numero de ticket ne doit pas danser d'une
   ligne a l'autre quand la file se rafraichit. */
.mono {
    font-variant-numeric: tabular-nums;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: .92em;
    letter-spacing: -.01em;
}

/* Un seul anneau de focus pour toute l'application, visible sur fond clair
   comme sur fond bleu nuit. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--bleu-vif);
    outline-offset: 2px;
    border-radius: var(--rayon-sm);
}

/* ---------- Barres de defilement ----------

   La barre disparait, le defilement reste. Molette, pave tactile, doigt,
   fleches, Page haut/bas et Espace continuent d'agir : seule la poignee
   visible s'en va. `overflow` n'est pas touche, et un test verrouille ce
   couple — masquer n'est pas supprimer.

   Les deux ecritures sont necessaires et aucune n'est de trop :
   `scrollbar-width` sert Firefox et Safari, `::-webkit-scrollbar` sert Chrome
   et Edge. En oublier une laisse la barre visible sur la moitie des
   navigateurs.

   Les tableaux larges gardent la leur, volontairement : un defilement
   horizontal ne se devine pas, et la barre y est souvent le seul indice
   qu'une colonne continue a droite.

   Ce qui se perd, et qu'il faut assumer : la barre disait aussi « il y a
   quelque chose dessous » et « vous en etes la ». Les moyens de defiler
   restent tous ; l'indice visuel, lui, n'est plus. */
html,
body,
.tabnav,
.tabnav--open,
.bell__panel {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

html::-webkit-scrollbar,
body::-webkit-scrollbar,
.tabnav::-webkit-scrollbar,
.tabnav--open::-webkit-scrollbar,
.bell__panel::-webkit-scrollbar {
    width: 0;
    height: 0;
}

/* ---------- En-tete ---------- */

.app-header {
    display: flex; flex-wrap: wrap; gap: var(--e2) var(--e4);
    align-items: center; justify-content: space-between;
    padding: var(--e2) var(--e4);
    /* Blanche, et non plus bleu nuit : la barre cesse d'etre un bandeau de
       marque pour devenir le bord haut de la page. Ce qui la separe du contenu
       n'est plus une couleur mais un simple filet — c'est ce qui laisse la
       place aux cartes et a la barre laterale. */
    background: var(--blanc);
    color: var(--gris-900);
    border-bottom: 1px solid var(--gris-200);
    box-shadow: var(--ombre-1);
    position: sticky; top: 0; z-index: 30;
}

.app-header__brand { display: flex; align-items: center; gap: var(--e3); min-width: 0; }

.app-header__identite {
    display: flex; flex-direction: column; line-height: 1.2; min-width: 0;
}
.app-header__hospital {
    font-weight: 700; font-size: var(--texte-md);
    letter-spacing: -.01em; text-transform: uppercase;
    color: var(--bleu-fonce);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.app-header__produit {
    font-size: var(--texte-sm); color: var(--gris-500);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.app-header__context { display: flex; align-items: center; gap: var(--e2); }

/* Nom du role, ou du service pour un medecin : la seule information de
   contexte a droite de la barre. */
/* La pastille translucide n'avait de sens que sur fond sombre. Sur fond
   blanc, deux lignes de texte alignees a droite suffisent, et disent plus :
   qui est connecte, et a quel titre. */
.app-header__qui {
    display: flex; flex-direction: column; align-items: flex-end;
    line-height: 1.25; min-width: 0; max-width: 40vw;
}
.app-header__nom {
    font-weight: 650; font-size: var(--texte-base); color: var(--gris-900);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.app-header__role {
    font-size: var(--texte-sm); color: var(--gris-500);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Sous 700px le bloc d'identite disparait : le nom complet et le role tiennent
   deja dans la carte de profil, que l'avatar ouvre d'un geste. */
@media (max-width: 700px) {
    .app-header__qui, .app-header__produit { display: none; }
}

/* Sur telephone, la marque prend sa ligne et le contexte la suivante : les
   entasser sur une seule donnait une barre de deux lignes mal alignees. */
@media (max-width: 600px) {
    .app-header { padding: var(--e2) var(--e3); gap: var(--e2); }
    .app-header__hospital { font-size: var(--texte-base); }
    .app-header__context { margin-left: auto; }
}

/* La largeur est fixee explicitement : dans une colonne flex, une marge
   horizontale automatique empeche l'etirement, et la page se reglerait alors
   sur la largeur de son contenu — etroite ici, large la. */
.app-main { width: 100%; max-width: var(--largeur-max); margin: 0 auto; padding: var(--e4); }
.app-main--narrow { max-width: 900px; }

@media (max-width: 600px) {
    .app-main { padding: var(--e3); }
}

.page-title { font-size: var(--texte-xl); margin-bottom: var(--e4); }

/* ---------- Mise en page ---------- */

.stack { display: flex; flex-direction: column; gap: var(--e4); }
.grid { display: grid; gap: var(--e4); margin-bottom: var(--e4); }
.grid--two { grid-template-columns: 1fr; }
.grid--main { grid-template-columns: 1fr; }

@media (min-width: 860px) {
    .grid--two { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 1100px) {
    .grid--main { grid-template-columns: minmax(0, 2fr) minmax(340px, 1fr); align-items: start; }
    .record-column { position: sticky; top: calc(var(--e4) + 64px); }
}

.service-head {
    display: flex; flex-wrap: wrap; align-items: flex-end;
    justify-content: space-between; gap: var(--e4); margin-bottom: var(--e4);
}

/* ---------- Cartes ---------- */

.card {
    background: var(--blanc);
    border: 1px solid var(--gris-200);
    border-radius: var(--rayon-lg);
    box-shadow: var(--ombre-1);
    padding: var(--e5);
}

@media (max-width: 600px) {
    .card { padding: var(--e4); border-radius: var(--rayon); }
}

.card__head {
    display: flex; flex-wrap: wrap; gap: var(--e3);
    align-items: center; justify-content: space-between; margin-bottom: var(--e4);
}

.card__title {
    font-size: var(--texte-lg); font-weight: 650;
    margin-bottom: var(--e4);
}
.card__head .card__title { margin-bottom: 0; }

/* Sous-titre en capitales fines : il separe deux blocs a l'interieur d'une
   carte sans entrer en concurrence avec son titre. */
.card__subtitle {
    font-size: var(--texte-xs); font-weight: 700;
    text-transform: uppercase; letter-spacing: .06em;
    color: var(--gris-500);
    margin: var(--e6) 0 var(--e2);
}

.card--accent { border-left: 3px solid var(--bleu-vif); }
.card--danger { border-color: var(--rouge); }

/* ---------- En-tete de carte : badge, titre, accroche ----------
   Le badge marine devant chaque titre est ce qui donne son rythme a une page
   longue : l'oeil saute de pastille en pastille et trouve le bloc qu'il
   cherche sans lire les titres. */
.card__heading { display: flex; align-items: flex-start; gap: var(--e3); min-width: 0; }

.card__badge {
    display: grid; place-items: center;
    flex: 0 0 auto;
    width: 34px; height: 34px;
    border-radius: var(--rayon-sm);
    background: var(--bleu);
    color: var(--blanc);
}

.card__intitule { min-width: 0; }

/* L'accroche explique ce que fait le bloc. Elle vit sous le titre et non a
   cote : mise en ligne, elle repousse les actions hors du cadre des que le
   texte depasse quelques mots. */
.card__accroche {
    margin: var(--e1) 0 0;
    font-size: var(--texte-base);
    color: var(--gris-700);
    line-height: 1.45;
}

.card__actions { display: flex; flex-wrap: wrap; gap: var(--e2); align-items: center; }

/* ---------- Bandeau d'information ----------
   Permanent, contrairement a `.alert` qui repond a une action et s'efface.
   Le liseré porte la couleur, le fond reste tres clair : un aplat sature a
   cote d'un formulaire attire l'oeil plus que le formulaire. */
.notice {
    display: flex; gap: var(--e3); align-items: flex-start;
    padding: var(--e3) var(--e4);
    border: 1px solid var(--sarcelle-clair);
    border-left: 3px solid var(--sarcelle);
    border-radius: var(--rayon);
    background: var(--sarcelle-clair);
    color: var(--gris-800);
}

.notice__icone { flex: 0 0 auto; color: var(--sarcelle); margin-top: 1px; }
.notice__titre { margin: 0 0 var(--e1); font-weight: 650; color: var(--sarcelle-fonce); }
.notice__texte { font-size: var(--texte-base); line-height: 1.5; }
.notice__texte p { margin: 0; }
.notice__texte p + p { margin-top: var(--e2); }

.notice--alerte {
    border-color: var(--ambre-clair); border-left-color: var(--ambre);
    background: var(--ambre-clair);
}
.notice--alerte .notice__icone, .notice--alerte .notice__titre { color: var(--ambre); }

.notice--blocage {
    border-color: var(--rouge-clair); border-left-color: var(--rouge);
    background: var(--rouge-clair);
}
.notice--blocage .notice__icone, .notice--blocage .notice__titre { color: var(--rouge); }

/* Un bandeau suivi d'une action, ou d'un formulaire, a besoin d'air : colles,
   ils se lisent comme un seul bloc et l'action parait faire partie du message. */
.notice + .btn-row,
.notice + .form,
.btn-row + .form { margin-top: var(--e4); }

/* ---------- En-tete de page : fil d'ariane, titre, sous-titre ---------- */
.page-header { margin-bottom: var(--e5); }

.fil__liste {
    list-style: none; margin: 0 0 var(--e2); padding: 0;
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--e1);
    font-size: var(--texte-sm); color: var(--gris-500);
}
.fil__etape { display: inline-flex; align-items: center; gap: var(--e1); }
.fil__separateur { color: var(--gris-400); }
.fil__etape--courante { color: var(--gris-800); font-weight: 600; }

.page-header__titre {
    font-size: var(--texte-2xl); font-weight: 700;
    color: var(--bleu-fonce);
}

.page-header__sous-titre {
    margin: var(--e2) 0 0;
    font-size: var(--texte-md);
    color: var(--gris-700);
    max-width: 68ch;
}

/* Empilement vertical d'une page : en-tete, puis les cartes, toutes espacees
   pareil. Sans lui chaque section reglait ses propres marges, et deux pages
   voisines n'avaient pas le meme rythme. */
.pile { display: flex; flex-direction: column; gap: var(--e4); }

/* Les actions d'un formulaire se rangent a droite, sous le dernier champ,
   separees par un filet : c'est la ou l'oeil arrive en fin de saisie. */
.btn-row--fin {
    justify-content: flex-end;
    margin-top: var(--e5);
    padding-top: var(--e4);
    border-top: 1px solid var(--gris-200);
}

/* Depot du tampon : la saisie a gauche, ce qu'il faut en savoir a droite.
   La colonne d'aide passe dessous des que la carte devient etroite — un
   bandeau d'information comprime sur trois mots par ligne ne se lit plus. */
.tampon { display: grid; gap: var(--e4); align-items: start; }

@media (min-width: 860px) {
    .tampon { grid-template-columns: minmax(0, 1fr) minmax(0, 20rem); }
}

.tampon__aide { display: flex; flex-direction: column; gap: var(--e3); }
.tampon__aide .hint { margin: 0; }

/* Champ court : un delai en minutes n'a pas besoin de toute la largeur d'une
   carte, et un champ trop large invite a y ecrire autre chose qu'un nombre. */
.input--court { max-width: 12rem; }

/* Renvois vers les reglages qui vivent dans une autre section. */
.renvois { margin: var(--e4) 0 0; display: flex; flex-direction: column; gap: 0; }
.renvois__ligne {
    display: flex; flex-wrap: wrap; gap: var(--e2) var(--e4);
    justify-content: space-between; align-items: baseline;
    padding: var(--e3) 0;
    border-bottom: 1px solid var(--gris-200);
}
.renvois__ligne:last-child { border-bottom: 0; }
.renvois dt { color: var(--gris-800); }
.renvois dd { margin: 0; color: var(--gris-700); font-size: var(--texte-base); }

/* Chiffres de constat : ce que contient l'installation. Les valeurs sont en
   chasse fixe pour qu'une colonne de nombres reste alignee. */
.chiffres {
    display: grid; gap: var(--e3);
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    margin-bottom: var(--e4);
}
.chiffres__bloc {
    display: flex; flex-direction: column; gap: var(--e1);
    padding: var(--e3) var(--e4);
    background: var(--bleu-pale);
    border: 1px solid var(--gris-200);
    border-radius: var(--rayon);
}
.chiffres__valeur { font-size: var(--texte-xl); font-weight: 700; color: var(--bleu-fonce); }
.chiffres__libelle { font-size: var(--texte-sm); color: var(--gris-700); line-height: 1.35; }

/* ---------- Jauge de note ----------
   La longueur encode la valeur, la couleur ne la juge pas. Peindre en rouge
   l'agent le moins bien note serait un verdict rendu par une feuille de style,
   sur des effectifs souvent minuscules ; le chiffre et son effectif sont a
   cote, c'est au lecteur de conclure.

   Elle est masquee aux lecteurs d'ecran (`aria-hidden` cote gabarit) : la note
   chiffree qui la suit dit deja la meme chose, en mieux. */
.jauge { display: inline-flex; align-items: center; gap: var(--e2); min-width: 8rem; }

.jauge__piste {
    flex: 1 1 auto;
    height: 6px;
    background: var(--gris-200);
    border-radius: var(--rayon-pilule);
    overflow: hidden;
}

/* Extremite arrondie et ancree a l'origine : une jauge qui flotte ne se compare
   plus d'une ligne a l'autre. */
.jauge__valeur {
    display: block;
    height: 100%;
    background: var(--sarcelle);
    border-radius: var(--rayon-pilule);
}

.jauge__note { flex: 0 0 auto; font-weight: 650; color: var(--gris-900); }

/* Bloc de commandes : il se lit, il se copie, il ne se modifie pas. */
.code-bloc {
    margin: var(--e4) 0;
    padding: var(--e3) var(--e4);
    overflow-x: auto;
    background: var(--bleu-nuit);
    color: #e6eef6;
    border-radius: var(--rayon);
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: var(--texte-sm);
    line-height: 1.7;
}

.empty {
    color: var(--gris-500);
    font-size: var(--texte-base);
    margin: var(--e2) 0;
}

/* ---------- Formulaires ---------- */

.form { display: flex; flex-direction: column; gap: var(--e4); }
.form--inline-wrap { flex-direction: row; flex-wrap: wrap; align-items: flex-end; gap: var(--e3) var(--e4); }
.form--inline-wrap .field { flex: 1 1 220px; }

.field { display: flex; flex-direction: column; gap: var(--e1); min-width: 0; }
.field--inline { flex-direction: row; align-items: center; gap: var(--e2); }
.field-row { display: flex; flex-wrap: wrap; gap: var(--e3) var(--e4); }
.field-row .field { flex: 1 1 150px; }
.field-row .field--wide { flex: 2 1 200px; }

.field label { font-weight: 600; font-size: var(--texte-base); color: var(--gris-800); }
.field__hint { font-weight: 400; color: var(--gris-500); font-size: var(--texte-sm); }
.field__error { color: var(--rouge); font-size: var(--texte-sm); font-weight: 500; margin: var(--e1) 0 0; }

input[type="text"], input[type="email"], input[type="password"], input[type="tel"],
input[type="number"], input[type="search"], input[type="date"], input[type="time"],
input[type="datetime-local"], select, textarea {
    min-height: var(--touch);
    padding: var(--e2) var(--e3);
    font: inherit;
    font-size: var(--texte-base);
    color: inherit;
    background: var(--blanc);
    border: 1px solid var(--gris-300);
    border-radius: var(--rayon-sm);
    width: 100%;
    transition: border-color var(--transition), box-shadow var(--transition);
}

input:hover:not(:disabled), select:hover:not(:disabled), textarea:hover:not(:disabled) {
    border-color: var(--gris-400);
}

/* L'anneau remplace le contour au clavier comme a la souris : un champ actif
   se reconnait a sa bordure bleue et a son halo, pas a un liseré systeme. */
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--bleu-vif);
    box-shadow: var(--anneau);
}

select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234a555d' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--e3) center;
    background-size: 1.1em;
    padding-right: var(--e8);
}

textarea { min-height: 5.5rem; resize: vertical; line-height: 1.5; }

input::placeholder, textarea::placeholder { color: var(--gris-400); }

input[type="checkbox"] {
    width: 1.2rem; height: 1.2rem;
    accent-color: var(--bleu-vif);
    cursor: pointer;
}

fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }

/* ---------- Boutons ---------- */

.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--e2);
    min-height: var(--touch); padding: var(--e2) var(--e5);
    font: inherit; font-size: var(--texte-base); font-weight: 600;
    line-height: 1.2;
    border: 1px solid transparent; border-radius: var(--rayon-sm);
    cursor: pointer; text-align: center; text-decoration: none;
    transition: background-color var(--transition), border-color var(--transition),
                color var(--transition), box-shadow var(--transition), transform var(--transition);
}

/* Le bouton se souleve d'un pixel au survol et se repose au clic. C'est le
   seul mouvement de l'interface : il suffit a rendre l'action tangible. */
.btn:hover:not([disabled]) { transform: translateY(-1px); }
.btn:active:not([disabled]) { transform: translateY(0); transition-duration: 60ms; }

.btn[disabled] { opacity: .55; cursor: not-allowed; transform: none; }

.btn--primary {
    background: var(--bleu); color: var(--blanc);
    box-shadow: var(--ombre-1);
}
.btn--primary:hover:not([disabled]) { background: var(--bleu-vif); box-shadow: var(--ombre-2); }

.btn--secondary {
    background: var(--bleu-clair); color: var(--bleu-fonce);
    border-color: transparent;
}
.btn--secondary:hover:not([disabled]) { background: var(--bleu-clair); border-color: var(--gris-300); }

/* Bordure discrete au repos, franche au survol : au repos le bouton fantome
   ne doit pas peser autant qu'une action principale. */
.btn--ghost {
    background: transparent; color: var(--gris-800);
    border-color: var(--gris-300);
}
.btn--ghost:hover:not([disabled]) { background: var(--gris-100); border-color: var(--gris-400); }

.btn--danger { background: var(--rouge); color: var(--blanc); }
.btn--danger:hover:not([disabled]) { background: #b52528; box-shadow: var(--ombre-2); }

.btn--close { background: var(--vert); color: var(--blanc); }
.btn--close:hover:not([disabled]) { background: var(--sarcelle-vif); box-shadow: var(--ombre-2); }

.btn--small { min-height: 36px; padding: var(--e1) var(--e3); font-size: var(--texte-sm); }
.btn--block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--e2); align-items: center; }
.btn-row--centered { justify-content: center; }

/* ---------- Alertes ---------- */

.alert {
    display: flex; align-items: flex-start; gap: var(--e3);
    width: 100%; max-width: var(--largeur-max); margin: var(--e4) auto 0;
    padding: var(--e3) var(--e4);
    border-radius: var(--rayon);
    border: 1px solid transparent;
    border-left-width: 3px;
    font-size: var(--texte-base); font-weight: 500;
    animation: alerte-entree var(--duree-lente) var(--courbe);
}

@keyframes alerte-entree {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}

.alert--error { background: var(--rouge-clair); border-color: var(--rouge); color: #7d191c; }
.alert--success { background: var(--vert-clair); border-color: var(--vert); color: var(--sarcelle-fonce); margin-bottom: var(--e4); }
.alert--warning { background: var(--ambre-clair); border-color: var(--ambre); color: #834e00; }

.alert__dismiss {
    margin-left: auto; flex: 0 0 auto;
    width: 28px; height: 28px;
    display: grid; place-items: center;
    background: transparent; border: 0; border-radius: var(--rayon-pilule);
    font-size: 1.25rem; line-height: 1; color: inherit; cursor: pointer;
    transition: background-color var(--transition);
}
.alert__dismiss:hover { background: rgba(0, 0, 0, .07); }

/* ---------- Tableaux ---------- */

.table-wrap {
    overflow-x: auto;
    border: 1px solid var(--gris-200);
    border-radius: var(--rayon);
    /* Ombre portee sur les bords quand le tableau deborde : sur tablette,
       rien n'indiquait qu'il restait des colonnes a droite. */
    background:
        linear-gradient(90deg, var(--blanc) 30%, rgba(255, 255, 255, 0)) left / 40px 100% no-repeat,
        linear-gradient(270deg, var(--blanc) 30%, rgba(255, 255, 255, 0)) right / 40px 100% no-repeat,
        radial-gradient(farthest-side at 0 50%, rgba(11, 40, 60, .12), transparent) left / 14px 100% no-repeat,
        radial-gradient(farthest-side at 100% 50%, rgba(11, 40, 60, .12), transparent) right / 14px 100% no-repeat,
        var(--blanc);
    background-attachment: local, local, scroll, scroll, local;
}

.table { width: 100%; border-collapse: collapse; min-width: 560px; }

.table th, .table td {
    padding: var(--e3);
    text-align: left;
    border-bottom: 1px solid var(--gris-200);
    font-size: var(--texte-base);
}

.table thead th {
    position: sticky; top: 0; z-index: 1;
    background: var(--gris-50);
    font-size: var(--texte-xs); font-weight: 700;
    text-transform: uppercase; letter-spacing: .06em;
    color: var(--gris-500);
    border-bottom-color: var(--gris-300);
}

.table tbody tr { transition: background-color var(--transition); }
.table tbody tr:hover { background: var(--bleu-pale); }
.table tbody tr:last-child td { border-bottom: 0; }

.table td .btn { min-height: 36px; padding: var(--e1) var(--e3); font-size: var(--texte-sm); }

/* ---------- Pastilles d'etat ---------- */

.badge {
    display: inline-flex; align-items: center;
    padding: var(--e1) var(--e2);
    border-radius: var(--rayon-sm);
    font-size: var(--texte-xs); font-weight: 700;
    text-transform: uppercase; letter-spacing: .04em;
    white-space: nowrap;
}
.badge--waiting { background: var(--ambre-clair); color: var(--ambre); }
.badge--called { background: var(--vert-clair); color: var(--vert); }
.badge--closed { background: var(--gris-200); color: var(--gris-700); }
.badge--neutral { background: var(--gris-100); color: var(--gris-700); }

/* ---------- Ticket imprime a l'ecran ---------- */

.ticket {
    margin-top: 1rem; padding: 1rem; text-align: center;
    background: var(--vert-clair); border: 2px dashed var(--vert); border-radius: var(--rayon);
}

.ticket--muted { background: var(--gris-100); border-color: var(--gris-500); }
.ticket__label { margin: 0; font-size: .85rem; text-transform: uppercase; letter-spacing: .05em; color: var(--gris-700); }
.ticket__code { margin: .2rem 0; font-size: 1.8rem; font-weight: 700; letter-spacing: .04em; }
.ticket__meta { margin: 0; color: var(--gris-700); }

/* ---------- File d'attente ---------- */

.queue { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e2); }

/* Grille explicite plutot qu'un flex qui se rabat : le nom du patient etait
   coupe en deux (« Aminata / Traore ») alors qu'il restait la moitie de la
   largeur libre a droite. Le jeton, l'identite, l'etat et les actions ont
   chacun leur colonne. */
.queue__item {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    align-items: center;
    gap: var(--e3);
    padding: var(--e2) var(--e3);
    background: var(--blanc);
    border: 1px solid var(--gris-200);
    border-left: 3px solid var(--ambre);
    border-radius: var(--rayon);
    transition: border-color var(--transition), box-shadow var(--transition);
}

.queue__item:hover {
    border-color: var(--gris-300);
    border-left-color: var(--ambre);
    box-shadow: var(--ombre-2);
}

.queue__item--called { border-left-color: var(--vert); background: var(--vert-clair); }
.queue__item--called:hover { border-left-color: var(--vert); }

/* Sur telephone, l'identite passe sous le jeton et les actions prennent
   toute la largeur : quatre colonnes sur 390px ne tiennent pas. */
@media (max-width: 700px) {
    .queue__item {
        grid-template-columns: auto minmax(0, 1fr);
        row-gap: var(--e2);
        align-items: start;
    }
    /* Le jeton garde sa taille : etire sur la hauteur de la rangee, il
       devenait un grand rectangle vide a cote du nom. */
    .queue__token { align-self: start; height: 2.75rem; }
    .queue__item > .badge { grid-column: 2; justify-self: start; }
    .queue__item > .btn,
    .queue__item > .btn-row { grid-column: 1 / -1; }
    .queue__item > .btn { width: 100%; }
}

/* Sur telephone, le titre d'une carte et son action prennent chacun leur
   ligne pleine largeur : cote a cote, ils se coupaient tous les deux. */
@media (max-width: 600px) {
    .card__head { flex-direction: column; align-items: stretch; gap: var(--e3); }
    .card__head .btn { width: 100%; }
}

.queue__patient {
    display: contents;
    background: none; border: 0; font: inherit; color: inherit;
    text-align: left; cursor: pointer;
}

.queue__token {
    display: grid; place-items: center;
    min-width: 2.75rem; min-height: 2.75rem; padding: 0 var(--e2);
    font-size: var(--texte-lg); font-weight: 700;
    background: var(--bleu-clair); color: var(--bleu-fonce);
    border-radius: var(--rayon-sm);
    font-variant-numeric: tabular-nums;
    transition: background-color var(--transition), color var(--transition);
}
.queue__patient:hover .queue__token { background: var(--bleu); color: var(--blanc); }
.queue__item--called .queue__token { background: var(--vert); color: var(--blanc); }

.queue__identity {
    display: flex; flex-direction: column; gap: 1px;
    font-size: var(--texte-sm); color: var(--gris-500);
    min-width: 0;
}
.queue__identity strong {
    font-size: var(--texte-md); font-weight: 600; color: var(--gris-900);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    transition: color var(--transition);
}
.queue__patient:hover .queue__identity strong { color: var(--bleu); }

.referral-form {
    list-style: none;
    padding: var(--e4);
    background: var(--bleu-pale);
    border: 1px solid var(--bleu-clair);
    border-radius: var(--rayon);
    animation: depliage var(--duree-lente) var(--courbe);
}
.referral-form__title { margin: 0 0 var(--e2); font-weight: 650; font-size: var(--texte-base); }

@keyframes depliage {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: none; }
}

/* ---------- Renvois ---------- */

.referrals { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .75rem; }

.referrals__item {
    padding: .75rem; border: 1px solid var(--gris-300); border-radius: var(--rayon);
    border-left: 6px solid var(--ambre);
}

.referrals__item--done { border-left-color: var(--vert); }

.referrals__patient {
    display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline;
    min-height: var(--touch); padding: .2rem 0;
    background: none; border: 0; font: inherit; color: inherit; cursor: pointer; text-align: left;
}

.referrals__patient .mono { color: var(--gris-500); font-size: .9rem; }
.referrals__meta { margin: .1rem 0; font-size: .9rem; color: var(--gris-700); }
.referrals__instructions { margin: .4rem 0; }
.referrals__result { margin: .4rem 0; padding: .6rem; background: var(--vert-clair); border-radius: var(--rayon); }

/* ---------- Dossier patient ---------- */

.record__identity {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: var(--e3) var(--e4);
    margin: 0 0 var(--e4);
    padding-bottom: var(--e4);
    border-bottom: 1px solid var(--gris-200);
}
.record__identity div { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.record__identity dt {
    font-size: var(--texte-xs); font-weight: 700;
    text-transform: uppercase; letter-spacing: .05em; color: var(--gris-500);
}
.record__identity dd { margin: 0; font-weight: 600; font-size: var(--texte-base); overflow-wrap: anywhere; }

/* La frise : un filet vertical et une pastille par evenement. La pastille
   grossit au survol de son entree, ce qui aide a suivre une ligne du regard
   sur un dossier charge. */
.timeline {
    list-style: none; margin: 0;
    padding: 0 0 0 var(--e4);
    border-left: 1px solid var(--gris-300);
}

.timeline__item {
    position: relative;
    padding: 0 0 var(--e5) var(--e3);
    transition: color var(--transition);
}
.timeline__item:last-child { padding-bottom: 0; }

.timeline__item::before {
    content: ""; position: absolute; left: calc(-1 * var(--e4) - 5px); top: .4rem;
    width: 9px; height: 9px; border-radius: 50%;
    background: var(--gris-400);
    box-shadow: 0 0 0 3px var(--blanc);
    transition: transform var(--transition), background-color var(--transition);
}
.timeline__item:hover::before { transform: scale(1.35); }

.timeline__item--registration::before { background: var(--bleu-vif); }
.timeline__item--consultation::before { background: var(--vert); }
.timeline__item--referral_sent::before { background: var(--ambre); }
.timeline__item--referral_result::before { background: var(--vert); }

.timeline__head {
    display: flex; flex-wrap: wrap; gap: var(--e2);
    align-items: baseline; justify-content: space-between; margin: 0;
}
.timeline__type { font-weight: 650; font-size: var(--texte-base); }
.timeline__head time { color: var(--gris-500); font-size: var(--texte-sm); font-variant-numeric: tabular-nums; }
.timeline__body { margin: var(--e1) 0; font-size: var(--texte-base); }
.timeline__meta { margin: 0; font-size: var(--texte-sm); color: var(--gris-500); }

/* ---------- Selecteur de service ---------- */

.service-selector { min-width: 240px; }
.service-selector__single { margin: 0; font-weight: 700; font-size: 1.1rem; color: var(--bleu-fonce); }

/* ---------- Ecran de salle d'attente ---------- */

.board__grid { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }

.board__service {
    padding: .85rem; text-align: center;
    background: var(--gris-100); border: 1px solid var(--gris-300); border-radius: var(--rayon);
}

.board__service-name { font-size: 1rem; color: var(--gris-700); }
.board__current-label, .board__next-label {
    margin: .4rem 0 0; font-size: .75rem; text-transform: uppercase;
    letter-spacing: .06em; color: var(--gris-500);
}
.board__current { margin: 0; font-size: 2.6rem; font-weight: 800; color: var(--bleu-fonce); font-variant-numeric: tabular-nums; }
.board__next { display: flex; gap: .4rem; justify-content: center; margin: .2rem 0 0; flex-wrap: wrap; }
.board__next-token {
    padding: .15rem .55rem; border-radius: 999px; font-weight: 700;
    background: var(--blanc); border: 1px solid var(--gris-300); font-variant-numeric: tabular-nums;
}
.board__next-token--empty { color: var(--gris-500); }

/* Moniteur mural : contraste maximal et grands caracteres, lisibles de loin. */
.board-body { background: var(--gris-900); color: var(--blanc); min-height: 100vh; }

.board--fullscreen { padding: 1.5rem; }
.board--fullscreen .board__header { text-align: center; margin-bottom: 1.5rem; }
.board__logo { display: block; width: min(420px, 70%); height: auto; margin: 0 auto; }
.board--fullscreen .board__header p { margin: .5rem 0 0; opacity: .8; font-size: 1.1rem; }
.board--fullscreen .board__grid { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; }
/* Le moniteur reste sombre : il est lu de loin, dans un couloir eclaire au
   neon, et un ecran clair y devient un projecteur. Ce sont donc les teintes
   qui s'accordent a la marque, pas le fond.

   Le numero appele passe du bleu ciel a une sarcelle claire : c'est la teinte
   de la marque portee au niveau de luminosite qu'exige un fond sombre — la
   sarcelle nominale (#16806a) serait illisible a cinq metres. */
.board--fullscreen .board__service { background: #1f2c31; border-color: #35474e; }
.board--fullscreen .board__service-name { color: #cfd8dd; font-size: 1.3rem; }
.board--fullscreen .board__current { color: #5fe3bd; font-size: 4.5rem; }
.board--fullscreen .board__next-token { background: #16211f; border-color: #35474e; color: var(--blanc); }

/* =========================================================================
   Addendum v2 / v3 — episodes, cloture, caisse, audit, planning
   ========================================================================= */

/* ---------- Barre de marque ---------- */

/* Logo et nom de l'etablissement cote a cote, a gauche de la barre. */
.app-header__brand { display: flex; align-items: center; gap: .7rem; min-width: 0; }
.app-header__logo { flex: 0 0 auto; height: 40px; width: auto; }
.app-header__hospital {
    font-size: 1.05rem; font-weight: 700; line-height: 1.2;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------- Indications et alertes ---------- */

.hint { margin: .25rem 0 .75rem; font-size: .9rem; color: var(--gris-700); }
.hint--blocking { color: var(--ambre); font-weight: 600; }

.alert--warning { background: var(--ambre-clair); border-color: var(--ambre); color: var(--ambre); margin: .75rem 0; }

.card--accent { border-left: 6px solid var(--bleu); }

/* ---------- Boutons de cloture ---------- */

.btn--close { background: var(--vert); color: var(--blanc); }

/* ---------- Recherche de dossier existant ---------- */

.lookup { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }

.lookup__item {
    display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; justify-content: space-between;
    padding: .7rem; border: 1px solid var(--gris-300); border-radius: var(--rayon);
}

.lookup__identity { display: flex; flex-direction: column; font-size: .9rem; color: var(--gris-700); }
.lookup__identity strong { font-size: 1.05rem; color: var(--gris-900); }

.lookup__confirm { margin-top: 1rem; padding: 1rem; background: var(--bleu-clair); border-radius: var(--rayon); }

/* ---------- Accompagnateurs ---------- */

/* Meme cadre que les autres groupes du formulaire : trois encadres de styles
   differents sur le meme ecran donnaient une page mal assemblee. */
.companions-fieldset {
    border: 1px solid var(--gris-200);
    background: var(--gris-50);
    border-radius: var(--rayon);
    padding: var(--e4);
}
.companions-fieldset legend {
    font-weight: 700; padding: 0 var(--e2);
    font-size: var(--texte-xs); text-transform: uppercase; letter-spacing: .06em;
    color: var(--gris-500);
}
.companions-fieldset input { background: var(--blanc); }
.companions-fieldset__row { align-items: flex-end; margin-bottom: var(--e3); }

.companions { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-direction: column; gap: .3rem; }
.companions li { display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline; font-size: .95rem; }
.companions .mono { color: var(--gris-500); }

/* ---------- Episodes ---------- */

.episode { margin-bottom: 1.25rem; border: 1px solid var(--gris-300); border-radius: var(--rayon); padding: .75rem; }

.episode__head {
    display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
    margin-bottom: .6rem; padding-bottom: .5rem; border-bottom: 1px solid var(--gris-300);
}

.episode__service { font-weight: 700; }
.episode__head time { margin-left: auto; color: var(--gris-500); font-size: .9rem; }

.badge--closed { background: var(--gris-100); color: var(--gris-700); }
.badge--scheduled { background: var(--bleu-clair); color: var(--bleu-fonce); }
.badge--checked_in { background: var(--vert-clair); color: var(--vert); }
.badge--no_show { background: var(--ambre-clair); color: var(--ambre); }
.badge--cancelled { background: var(--rouge-clair); color: var(--rouge); }
.badge--paid { background: var(--vert-clair); color: var(--vert); }
.badge--pending { background: var(--ambre-clair); color: var(--ambre); }

.timeline__item--referral_closed::before { background: var(--bleu-fonce); }
.timeline__item--dossier_closed::before { background: var(--gris-700); }
.timeline__item--prescription::before { background: var(--bleu); }

/* ---------- Pieces jointes ---------- */

.attachments { list-style: none; margin: .5rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }

.attachments__link {
    display: inline-flex; align-items: center; gap: .4rem;
    min-height: 40px; padding: .3rem .7rem;
    background: var(--bleu-clair); color: var(--bleu-fonce);
    border-radius: var(--rayon); text-decoration: none; font-size: .9rem; font-weight: 600;
}

.attachments__size { font-weight: 400; opacity: .8; }

/* ---------- Mes patients ---------- */

.my-patients { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .6rem; }

.my-patients__item { padding: .7rem; border: 1px solid var(--gris-300); border-radius: var(--rayon); }

.my-patients__identity {
    display: flex; flex-wrap: wrap; gap: .6rem; align-items: baseline;
    min-height: var(--touch); padding: .2rem 0;
    background: none; border: 0; font: inherit; color: inherit; cursor: pointer; text-align: left; width: 100%;
}

.my-patients__identity .mono { color: var(--gris-500); font-size: .9rem; }

.my-patients__visits { list-style: none; margin: .4rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .25rem; }
.my-patients__visits li { display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline; font-size: .9rem; color: var(--gris-700); }

/* ---------- Onglets internes ---------- */

.tabs {
    display: flex; flex-wrap: wrap; gap: var(--e1);
    margin: var(--e3) 0 var(--e4);
    border-bottom: 1px solid var(--gris-300);
}

.tabs__tab {
    position: relative;
    min-height: var(--touch); padding: var(--e2) var(--e4);
    background: none; border: 0;
    font: inherit; font-size: var(--texte-base); font-weight: 600;
    color: var(--gris-500); cursor: pointer;
    transition: color var(--transition);
}
.tabs__tab:hover { color: var(--gris-900); }

/* Le soulignement grandit depuis le centre : il rend le changement d'onglet
   lisible sans deplacer le texte. */
.tabs__tab::after {
    content: ""; position: absolute; left: 50%; right: 50%; bottom: -1px;
    height: 2px; background: var(--bleu-vif); border-radius: 2px 2px 0 0;
    transition: left var(--duree-lente) var(--courbe), right var(--duree-lente) var(--courbe);
}
.tabs__tab--active { color: var(--bleu-fonce); }
.tabs__tab--active::after { left: var(--e3); right: var(--e3); }

/* ---------- Caisse ---------- */

.cash-total { font-size: .95rem; color: var(--gris-700); }
.cash-total strong { color: var(--vert); }

.payments { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .35rem; }
.payments li { display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline; padding: .35rem 0; border-bottom: 1px solid var(--gris-300); }
.payments time { margin-left: auto; color: var(--gris-500); font-size: .9rem; }

/* ---------- Planning ---------- */

.schedule--today { background: var(--bleu-clair); }

/* =========================================================================
   Refonte navigation — bouton icone et barre laterale en onglets
   ========================================================================= */

/* ---------- Bouton icone ---------- */

.icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: var(--touch); height: var(--touch);
    padding: 0; color: inherit;
    background: transparent;
    border: 1px solid currentColor; border-radius: 50%;
    cursor: pointer;
    transition: background-color var(--transition), transform var(--transition), border-color var(--transition);
}

/* Le survol blanc translucide ne se voyait que sur la barre bleu nuit. Sur
   fond clair il faut au contraire assombrir. */
.icon-btn:hover { background: var(--gris-100); transform: scale(1.06); }
.icon-btn:active { transform: scale(.97); transition-duration: 60ms; }

/* Sur fond clair, l'aplat blanc du survol ne se voit pas : on assombrit. */
.icon-btn--danger { color: var(--rouge); border-color: var(--gris-300); }
.icon-btn--danger:hover { background: var(--rouge-clair); border-color: var(--rouge); }

/* Icone de suppression dans un tableau : discrete au repos, franche au
   survol, jamais masquee. */
.btn--icon {
    width: var(--touch); height: var(--touch);
    min-height: var(--touch); padding: 0;
    border-radius: var(--rayon-sm);
}
.btn--icon-danger { color: var(--rouge); border-color: var(--gris-300); }
.btn--icon-danger:hover { background: var(--rouge-clair); border-color: var(--rouge); color: var(--rouge); }

/* ---------- Espace de travail : barre laterale + panneau ---------- */

.workspace { display: grid; gap: var(--e4); align-items: start; }

/* Bouton d'ouverture du tiroir : uniquement sur petit format. */
.workspace__toggle {
    display: flex; align-items: center; gap: var(--e2);
    width: 100%; min-height: var(--touch); padding: var(--e2) var(--e3);
    font: inherit; font-size: var(--texte-base); font-weight: 600; text-align: left;
    color: var(--bleu-fonce); background: var(--blanc);
    border: 1px solid var(--gris-200); border-radius: var(--rayon);
    box-shadow: var(--ombre-1); cursor: pointer;
    transition: border-color var(--transition), box-shadow var(--transition);
}
.workspace__toggle:hover { border-color: var(--gris-300); box-shadow: var(--ombre-2); }

.workspace__toggle-current {
    margin-left: auto; font-weight: 400; color: var(--gris-500); font-size: var(--texte-sm);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* La barre laterale est un tiroir replie par defaut sur tablette et mobile :
   sur un petit ecran, une colonne fixe mangerait trop de largeur. */
.tabnav {
    display: none;
    background: var(--blanc); border: 1px solid var(--gris-200);
    border-radius: var(--rayon-lg); box-shadow: var(--ombre-1);
    padding: var(--e2) var(--e2) var(--e4);
}

/* Ouvert sur petit ecran, le tiroir defile lui aussi pour son compte : sans
   plafond de hauteur, treize entrees repoussaient le contenu de la page a
   plusieurs ecrans de defilement sous la barre. 60 % de la hauteur visible
   laisse voir qu'il y a quelque chose dessous. */
.tabnav--open {
    display: block;
    animation: depliage var(--duree-lente) var(--courbe);
    max-height: 60dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.tabnav__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.tabnav__list--nested {
    margin: 2px 0 var(--e1) var(--e3);
    padding-left: var(--e2);
    border-left: 1px solid var(--gris-200);
}

.tabnav__item { display: flex; flex-direction: column; }

.tabnav__link,
.tabnav__group {
    position: relative;
    display: flex; align-items: center; gap: var(--e2);
    width: 100%; min-height: var(--touch); padding: var(--e2) var(--e3);
    font: inherit; font-size: var(--texte-base); text-align: left; color: var(--gris-800);
    background: transparent; border: 0; border-radius: var(--rayon-sm); cursor: pointer;
    transition: background-color var(--transition), color var(--transition);
}

.tabnav__group { font-weight: 600; }
.tabnav__link:hover, .tabnav__group:hover { background: var(--gris-100); color: var(--gris-900); }

/* Intitule de famille : pas un element cliquable, seulement le nom du bloc
   qui commence. Retire du flux d'accessibilite cote gabarit — un lecteur
   d'ecran annoncerait un titre la ou il n'y a qu'un reperage visuel. */
.tabnav__famille {
    padding: var(--e4) var(--e3) var(--e1);
    font-size: var(--texte-xs);
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--gris-400);
}
.tabnav__famille:first-child { padding-top: var(--e2); }

/* L'icone ne porte jamais sa couleur : elle suit celle du libelle, y compris
   quand l'entree devient active et passe en blanc sur marine. */
.tabnav__icone { flex: 0 0 auto; opacity: .82; }

/* L'entree active est une pastille pleine, et non une teinte pale barree d'un
   trait : sur une barre de treize entrees, une nuance claire ne se distingue
   plus d'un survol. */
.tabnav__link--active {
    background: var(--bleu); color: var(--blanc); font-weight: 600;
}
.tabnav__link--active:hover { background: var(--bleu-fonce); color: var(--blanc); }
.tabnav__link--active .tabnav__icone { opacity: 1; }

/* Le chevron du groupe part a droite : il annonce le depliage, pas l'entree —
   celle-ci a deja son icone a gauche. */
.tabnav__chevron {
    flex: 0 0 auto; margin-left: auto;
    color: var(--gris-400);
    transition: transform var(--duree-lente) var(--courbe);
}
.tabnav__chevron--open { transform: rotate(90deg); }

/* Le panneau actif : une seule section a la fois, plus de defilement a
   travers toutes les sections empilees. */
.workspace__panel { min-width: 0; display: flex; flex-direction: column; gap: var(--e4); }
.workspace__panel .page-title { margin-bottom: 0; }

/* A partir de la tablette en paysage, la barre laterale devient une colonne
   permanente et le bouton de tiroir disparait. */
@media (min-width: 900px) {
    .workspace {
        grid-template-columns: minmax(200px, 232px) minmax(0, 1fr);
        gap: var(--e5);
        transition: grid-template-columns var(--duree-lente) var(--courbe);
    }
    .workspace__toggle { display: none; }

    /* La barre defile pour son propre compte, et non avec la page : treize
       entrees plus trois intitules de famille depassent la hauteur d'un ecran
       de portable, et il fallait alors faire descendre tout le contenu pour
       atteindre la derniere section. `overscroll-behavior` empeche le
       defilement de se propager a la page une fois la barre en butee. */
    .tabnav {
        display: block;
        position: sticky;
        top: calc(var(--e4) + 64px);
        max-height: calc(100dvh - 64px - var(--e8));
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    /* Repliee, la barre garde ses icones : masquee, elle obligerait a la
       rouvrir pour savoir ou l'on est. C'est une colonne de reperes, pas un
       panneau a cacher. */
    .workspace--replie { grid-template-columns: 66px minmax(0, 1fr); }

    .workspace--replie .tabnav__link span,
    .workspace--replie .tabnav__group span,
    .workspace--replie .tabnav__chevron,
    .workspace--replie .tabnav__famille { display: none; }

    .workspace--replie .tabnav__link,
    .workspace--replie .tabnav__group { justify-content: center; padding-inline: 0; }

    /* Les sous-sections n'ont pas d'icone : repliees, elles ne seraient que des
       lignes vides. Le groupe reste cliquable et les rouvre en depliant. */
    .workspace--replie .tabnav__list--nested { display: none; }

    .workspace--replie .tabnav__icone { opacity: 1; }
}

/* Bouton de repli. Il vit dans la barre, aligne a droite quand elle est
   depliee et centre quand elle ne l'est plus — c'est la meme cible au meme
   endroit dans les deux etats, ce qui evite de la chercher. */
.tabnav__replier {
    display: none;
    margin: 0 0 var(--e1) auto;
    width: 30px; height: 30px;
    align-items: center; justify-content: center;
    color: var(--gris-500);
    background: transparent;
    border: 1px solid var(--gris-200); border-radius: var(--rayon-sm);
    cursor: pointer;
    transition: background-color var(--transition), color var(--transition);
}
.tabnav__replier:hover { background: var(--gris-100); color: var(--gris-900); }
.tabnav__replier-icone { transform: rotate(180deg); transition: transform var(--duree-lente) var(--courbe); }
.workspace--replie .tabnav__replier { margin-inline: auto; }
.workspace--replie .tabnav__replier-icone { transform: rotate(0deg); }

@media (min-width: 900px) {
    .tabnav__replier { display: flex; }
}

/* Dans /service, le dossier patient occupe une troisieme colonne. */
@media (min-width: 1100px) {
    .grid--main > .workspace { grid-column: 1; }
}

/* =========================================================================
   v3.2 — caisse, portail patient, planning groupe, suppression de dossier
   ========================================================================= */

/* ---------- Planning groupe : choix des jours de la semaine ---------- */
.weekdays { border: 1px solid var(--gris-300); border-radius: var(--rayon); padding: .85rem; }
.weekdays legend { font-weight: 600; padding: 0 .4rem; }

.weekdays__row { display: flex; flex-wrap: wrap; gap: .4rem; }

/* Chaque jour est une pastille cliquable : cible tactile pleine, pas de
   dependance a la precision du pointeur. */
.weekdays__day {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-height: var(--touch);
    padding: 0 .8rem;
    border: 1px solid var(--gris-300);
    border-radius: var(--rayon);
    background: var(--blanc);
    cursor: pointer;
    user-select: none;
}
.weekdays__day:has(input:checked) {
    border-color: var(--bleu);
    background: var(--bleu-clair);
    color: var(--bleu-fonce);
    font-weight: 600;
}
/* Repli pour les navigateurs sans :has() — la case reste visible et lisible. */
.weekdays__day input { width: 20px; height: 20px; accent-color: var(--bleu); }

/* ---------- Zone dangereuse : suppression definitive de dossier ---------- */
.card--danger { border-left: 4px solid var(--rouge); }
.card--danger .card__title { color: var(--rouge); }

.btn--danger { background: var(--rouge); color: var(--blanc); }
.btn--danger:hover { background: #8a1b1b; }

.deletion__confirm {
    margin-top: 1rem;
    padding: 1rem;
    background: var(--rouge-clair);
    border-radius: var(--rayon);
}
.deletion__confirm .card__subtitle { margin-top: 0; }

/* ---------- Portail patient ---------- */
/* Page publique consultee au telephone : une seule colonne etroite, centree,
   sans navigation. */
.app-main--narrow { max-width: 640px; }

.portal { display: flex; flex-direction: column; gap: 1rem; }

.portal__gate { max-width: 420px; margin: 0 auto; }

/* Le code a quatre chiffres : saisie large, espacee, lisible d'un coup d'oeil. */
.portal__code {
    font-family: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;
    font-size: 2rem;
    letter-spacing: .5em;
    text-align: center;
    text-indent: .5em;
}

/* ---------- Tableau d'affichage : visiteurs rattaches ---------- */
.board__visitors {
    list-style: none;
    margin: .35rem 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .4rem .9rem;
    font-size: .9rem;
    color: var(--gris-700);
}
.board__visitors li { display: flex; gap: .4rem; align-items: baseline; }

/* ---------- Formulaires depliants dans « Mes patients » ---------- */
.my-patients__form {
    margin-top: .6rem;
    padding: .75rem;
    background: var(--gris-100);
    border-radius: var(--rayon);
}

/* ---------- Patient deja choisi dans une recherche ---------- */
.lookup__chosen {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: center;
    margin: 0;
    padding: .6rem .75rem;
    background: var(--bleu-clair);
    border-radius: var(--rayon);
}
.lookup__chosen .btn { margin-left: auto; }

/* ---------- Rangee de boutons centree (apres impression d'un ticket) ---------- */
.btn-row--centered { justify-content: center; }

/* ---------- Actions d'impression dans la frise ---------- */
/* Discretes : elles ne doivent pas concurrencer la lecture de l'evenement. */
.btn--small {
    min-height: 34px;
    padding: 0 .6rem;
    font-size: .85rem;
}

.timeline__actions { margin: .35rem 0 0; }

.attachments li { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center; }

/* =========================================================================
   Addendum v3.2.6 — ecran de connexion
   =========================================================================

   L'ecran reprend la maquette public/images/keneya-workflow-login.svg :
   la photographie occupe toute la page, et la carte de connexion se pose
   exactement sur celle qui y est dessinee.

   Le cadrage n'est pas fait par « background-size: cover » mais par un
   element au meme rapport que l'image (1402 x 1122), dimensionne pour la
   couvrir. La carte, placee en pourcentages de cet element, retombe donc au
   pixel pres sur la carte dessinee, quelle que soit la taille de la fenetre —
   ce qu'un fond en « cover » ne permet pas, puisqu'il recadre sans que la
   page sache de combien.

   Toutes les dimensions de la carte sont exprimees en unites de conteneur
   (cqw) : elles suivent l'echelle de l'image au lieu de s'en detacher. Sous
   1024 px, ou ce cadrage n'aurait plus de sens, la mise en page bascule sur
   une carte centree classique et les memes variables passent en rem.
   ========================================================================= */

.login-page {
    min-height: 100vh;
    min-height: 100dvh;
    margin: 0;
    background: #f4f6f8;
}

/* La photographie porte le discours de la maquette : logo, accroche et barre
   d'atouts y sont peints, tous dans sa moitie gauche.

   Elle a ete elargie au format 2,32:1 en etirant la baie vitree de droite, ou
   il n'y a rien a lire. Elle est ainsi plus large que toutes les fenetres
   courantes : « cover » la cale donc sur la hauteur, et ce qui se fait couper
   est le vide de droite, jamais le haut ni le bas de la scene. */
.login-stage {
    position: fixed;
    inset: 0;
    overflow: hidden;
    background: var(--fond) url('../images/login-scene.jpg') left center / cover no-repeat;
}

.login-stage__scene {
    position: absolute;
    inset: 0;
}

/* ---------- La carte de connexion ---------- */

.login-card {
    position: absolute;
    top: 50%;

    /* L'image etant calee sur la hauteur, le dessin s'arrete toujours a la
       meme distance du bord gauche : 103,6 % de la hauteur de la fenetre. La
       carte se pose au milieu de ce qui reste — le vide de la scene — sans
       jamais sortir de la fenetre si ce vide se reduit. */
    left: clamp(calc(2vw + var(--carte-l) / 2),
                calc(51.8vh + 50vw),
                calc(98vw - var(--carte-l) / 2));
    transform: translate(-50%, -50%);

    /* Elle arrive par la droite, une seule fois, au chargement. */
    animation: kw-carte-entre 620ms cubic-bezier(.22, .61, .36, 1) both;

    /* Sa largeur est bornee par la hauteur disponible : la carte est deux
       fois plus haute que large, c'est donc la hauteur qui commande, sans quoi
       elle deborderait et defilerait. */
    --carte-l: clamp(18rem, min(36vw, 58vh), 44rem);
    width: var(--carte-l);
    max-height: 95vh;
    box-sizing: border-box;
    overflow: auto;

    background: #fff;
    border-radius: 2.2cqw;
    box-shadow: 0 4.68cqw 12.29cqw rgba(4, 28, 46, .16);

    /* Les dimensions internes suivent la largeur de la carte, pas celle de la
       fenetre : les proportions de la maquette sont donc tenues a toute
       taille, sans jeu de tailles a maintenir. Le remplissage vit dans
       l'enveloppe : un conteneur ne peut pas s'exprimer dans ses propres
       unites. */
    container-type: inline-size;

    /* La carte de connexion avait sa propre palette, un cyan repris d'une
       maquette anterieure. Elle pointe desormais sur les tokens de la marque :
       c'est le premier ecran que voit un agent, il ne peut pas etre le seul a
       ne pas parler la meme langue que le reste du produit. */
    --or-teal: var(--sarcelle);
    --or-teal-fonce: var(--sarcelle-fonce);
    --or-nuit: var(--bleu-fonce);
    --or-gris: var(--gris-500);
    --or-bord: var(--gris-200);
}

.login-card__inner {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    box-sizing: border-box;
    padding: 5.2cqw 8.6cqw 0;
}

/* Le bloc de marque est repris tel quel de la maquette : meme composition,
   memes graisses, sans avoir a charger une police web — l'application
   fonctionne sur un reseau d'hopital, parfois sans acces exterieur. */
.login-card__marque {
    display: block;
    width: 44%;
    height: auto;
    margin: 0 auto;
}

.login-card__head { text-align: center; margin: 3.6cqw 0 0; }

.login-card__title {
    margin: 0;
    font-size: 6.26cqw;
    line-height: 1.2;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--or-nuit);
}

.login-card__subtitle {
    margin: 1.5cqw 0 0;
    font-size: 3.25cqw;
    line-height: 1.4;
    color: var(--or-gris);
}

.login-card__site {
    display: inline-flex;
    align-items: center;
    gap: 1.6cqw;
    margin: 2.6cqw 0 0;
    padding: 1.4cqw 3.2cqw;
    font-size: 2.8cqw;
    font-weight: 600;
    color: var(--sarcelle-fonce);
    background: var(--sarcelle-clair);
    border-radius: var(--rayon-pilule);
}

.login-card__site svg { width: 3.4cqw; height: 3.4cqw; }

.login-form {
    display: flex;
    flex-direction: column;
    gap: 5cqw;
    margin-top: 5.6cqw;
}

/* La session persistante existe cote serveur depuis toujours ; il ne manquait
   que la case pour la demander. Elle se place sous les champs, avant le
   bouton, la ou l'utilisateur decide. */
.login-remember {
    display: flex;
    align-items: center;
    gap: 2.4cqw;
    margin: -4cqw 0 -2cqw;
    font-size: 2.9cqw;
    color: var(--or-gris);
    cursor: pointer;
}

.login-remember input {
    width: 4.2cqw;
    height: 4.2cqw;
    margin: 0;
    accent-color: var(--or-teal);
    cursor: pointer;
}

.login-remember input:focus-visible { outline: 2px solid var(--or-teal); outline-offset: 2px; }

.login-form .field { display: flex; flex-direction: column; gap: 2.2cqw; margin: 0; }

.login-form label {
    font-size: 2.93cqw;
    font-weight: 700;
    color: var(--or-nuit);
    letter-spacing: .005em;
}

.login-control { position: relative; display: flex; align-items: center; }

.login-control__icon {
    position: absolute;
    left: 3.95cqw;
    width: 4.39cqw;
    height: 4.39cqw;
    color: #9aa8bb;
    pointer-events: none;
}

.login-control input {
    width: 100%;
    height: 11.4cqw;
    box-sizing: border-box;
    padding: 0 3.51cqw 0 11.71cqw;
    font-family: inherit;
    font-size: 3.13cqw;
    color: var(--or-nuit);
    background: #fff;
    border: 1px solid var(--or-bord);
    border-radius: 2.28cqw;
    transition: border-color 160ms ease, box-shadow 160ms ease;
}

.login-control input::placeholder { color: #a4b0c0; }

.login-control input:focus {
    outline: none;
    border-color: var(--or-teal);
    box-shadow: 0 0 0 .82cqw rgba(5, 163, 157, .18);
}

.login-control input:focus-visible { outline: 2px solid var(--or-teal); outline-offset: 2px; }
.login-control input[aria-invalid="true"] { border-color: #c0392b; }
.login-control input.login-control__input--pw { padding-right: 11.71cqw; }

.login-peek {
    position: absolute;
    right: 2.63cqw;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 7.03cqw;
    height: 7.03cqw;
    padding: 0;
    color: #8d9bad;
    background: none;
    border: 0;
    border-radius: 1.46cqw;
    cursor: pointer;
}

.login-peek:hover, .login-peek[aria-pressed="true"] { color: var(--or-teal); }
.login-peek svg { width: 4.39cqw; height: 4.39cqw; display: block; }
.login-peek [data-icon="off"] { display: none; }
.login-peek[aria-pressed="true"] [data-icon="on"] { display: none; }
.login-peek[aria-pressed="true"] [data-icon="off"] { display: block; }

.login-submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 2.49cqw;
    width: 100%;
    height: 11.8cqw;
    margin-top: .85cqw;
    padding: 0;
    font-family: inherit;
    font-size: 3.54cqw;
    font-weight: 700;
    color: #fff;
    background: var(--or-teal);
    border: 0;
    border-radius: 2.28cqw;
    cursor: pointer;
    transition: background-color 160ms ease;
}

.login-submit:hover:not([disabled]) { background: var(--or-teal-fonce); }
.login-submit:focus-visible { outline: 3px solid var(--or-nuit); outline-offset: 3px; }
.login-submit[disabled] { opacity: .8; cursor: default; }
.login-submit svg { width: 4.39cqw; height: 4.39cqw; flex: 0 0 auto; }

.login-spinner {
    width: 3.51cqw;
    height: 3.51cqw;
    border: .5cqw solid rgba(255, 255, 255, .45);
    border-top-color: #fff;
    border-radius: 50%;
    animation: kw-tourne 700ms linear infinite;
}

@keyframes kw-tourne { to { transform: rotate(360deg); } }

/* L'etat d'arrivee n'est pas decrit : c'est celui de la carte elle-meme, donc
   la regle de centrage reste la seule source de sa position. Le reglage
   « animations reduites » du systeme la pose directement en place. */
@keyframes kw-carte-entre {
    from {
        opacity: 0;
        transform: translate(calc(-50% + 6rem), -50%);
    }
}

/* Les messages du serveur n'existent pas sur la maquette : ils s'inserent
   au-dessus du formulaire, dans le meme vocabulaire graphique. */
.login-alert {
    display: flex;
    gap: 2.49cqw;
    margin-top: 6.26cqw;
    padding: 2.93cqw 3.51cqw;
    font-size: 2.99cqw;
    line-height: 1.4;
    color: #8a2b21;
    background: #fdecea;
    border: 1px solid #f3c6c0;
    border-radius: 2.28cqw;
}

.login-alert svg { width: 3.81cqw; height: 3.81cqw; flex: 0 0 auto; margin-top: .4cqw; }

.login-card__foot {
    margin-top: 3.8cqw;
    text-align: center;
}

.login-card__foot::before {
    content: "";
    display: block;
    height: 1px;
    margin-bottom: 4.2cqw;
    background: var(--or-bord);
}

.login-card__secure {
    display: inline-flex;
    align-items: center;
    gap: 1.76cqw;
    font-size: 3.13cqw;
    font-weight: 600;
    color: var(--or-nuit);
}

.login-card__secure svg { width: 4.68cqw; height: 4.68cqw; color: var(--or-teal); }

/* La mention d'editeur ferme la carte. Elle est sortie du pied pour passer,
   sur mobile, sous la rangee des atouts — l'ordre du document suffit, aucun
   reordonnancement visuel n'est necessaire. */
.login-card__rights {
    margin: 2.8cqw 0 0;
    padding-bottom: 5.6cqw;
    font-size: 2.72cqw;
    color: var(--or-gris);
    text-align: center;
}

.login-card__rights a { color: var(--or-teal); font-weight: 600; text-decoration: none; }
.login-card__rights a:hover { text-decoration: underline; }

/* ---------- Ecrans etroits ----------
   La maquette responsive change de composition, elle ne se contente pas de
   retrecir : la photographie devient un bandeau en haut, la carte passe
   dessous et remonte sur lui par ses angles arrondis, et la marque quitte la
   carte pour se poser sur le bandeau. Sur mobile s'ajoute la rangee des
   quatre atouts, qui sur grand ecran est deja dans l'image.

   Les selecteurs restent ceux du grand ecran : seules les unites passent de
   cqw a rem, l'echelle n'ayant plus a suivre l'image. */

.login-band__marque { display: none; }
.login-atouts { display: none; }

@media (max-width: 64rem) {
    .login-page { display: block; }

    /* Le discours de la scene n'a pas sa place sur un petit ecran : on y vient
       pour se connecter, pas pour lire une accroche. */
    .login-stage { position: static; overflow: visible; }

    .login-stage { background: var(--fond); }

    .login-stage__scene {
        position: relative;
        inset: auto;
        transform: none;
        width: 100%;
        height: auto;
        min-height: 100dvh;
        aspect-ratio: auto;
        background: var(--fond);
        container-type: normal;
        display: flex;
        flex-direction: column;
    }

    /* Le bandeau est decoupe dans la scene sans aucun texte peint : le
       soignant, sa mallette et l'ecran au centre, et au-dessus d'eux la bande
       de mur clair ou vient se poser la marque. */
    .login-stage__scene::before {
        content: "";
        display: block;
        height: 44dvh;
        background: url('../images/login-scene-mobile.jpg') center top / cover no-repeat;
    }

    .login-band__marque {
        display: block;
        position: absolute;
        top: .95rem;
        left: 1.15rem;
        width: min(60vw, 18.5rem);
        height: auto;
        filter: drop-shadow(0 0 6px rgba(255, 255, 255, .95))
                drop-shadow(0 0 14px rgba(255, 255, 255, .75));
    }

    .login-card {
        position: relative;
        z-index: 1;
        left: auto;
        top: auto;
        right: auto;
        transform: none;
        max-height: none;
        container-type: normal;
        flex: 1;
        width: 100%;
        height: auto;
        margin: -1.75rem 0 0;
        border-radius: 22px 22px 0 0;
        box-shadow: 0 -.5rem 1.6rem rgba(6, 33, 74, .14);
        overflow: visible;
    }

    .login-card__inner { padding: 1.9rem 1.5rem 1.6rem; }

    /* La marque est sur le bandeau : la repeter dans la carte ferait double. */
    .login-card__marque { display: none; }

    .login-card__head { margin-top: 0; }
    .login-card__title { font-size: 1.62rem; }
    .login-card__subtitle { font-size: .95rem; margin-top: .35rem; }

    .login-card__site {
        gap: .4rem;
        margin-top: .7rem;
        padding: .3rem .8rem;
        font-size: .82rem;
    }

    .login-card__site svg { width: .95rem; height: .95rem; }

    .login-form { gap: 1.15rem; margin-top: 1.2rem; }

    .login-remember { gap: .55rem; margin: -.5rem 0 -.25rem; font-size: .88rem; }
    .login-remember input { width: 1.05rem; height: 1.05rem; }
    .login-form .field { gap: .45rem; }
    .login-form label { font-size: .9rem; }

    .login-control__icon { left: .9rem; width: 1.2rem; height: 1.2rem; }
    .login-control input { height: 3.1rem; padding: 0 1rem 0 2.8rem; font-size: 1rem; border-radius: 10px; }
    .login-control input.login-control__input--pw { padding-right: 3rem; }
    .login-control input:focus { box-shadow: 0 0 0 3px rgba(5, 163, 157, .18); }

    .login-peek { right: .5rem; width: 2.2rem; height: 2.2rem; border-radius: 8px; }
    .login-peek svg { width: 1.25rem; height: 1.25rem; }

    .login-submit { height: 3.25rem; margin-top: .25rem; font-size: 1.05rem; border-radius: 10px; gap: .55rem; }
    .login-submit svg { width: 1.2rem; height: 1.2rem; }
    .login-spinner { width: 1rem; height: 1rem; border-width: 2px; }

    .login-alert { gap: .55rem; margin-top: 1.1rem; padding: .75rem .9rem; font-size: .92rem; border-radius: 10px; }
    .login-alert svg { width: 1.05rem; height: 1.05rem; margin-top: .1rem; }

    .login-card__foot { margin-top: 1.5rem; }
    .login-card__foot::before { margin-bottom: 1.1rem; }
    .login-card__secure { font-size: .97rem; gap: .45rem; }
    .login-card__secure svg { width: 1.2rem; height: 1.2rem; }
    .login-card__rights { margin-top: 1rem; padding-bottom: .6rem; font-size: .86rem; }
}

/* Tablette : la carte s'elargit avec l'ecran, mais le formulaire garde une
   largeur de lecture confortable. */
@media (min-width: 48rem) and (max-width: 64rem) {
    .login-stage__scene::before {
        height: 45dvh;
        /* Meme scene, cadre plus large : le bandeau d'une tablette est bien
           plus etale que celui d'un telephone. */
        background-image: url('../images/login-scene-tablette.jpg');
        background-position: center top;
    }

    .login-card__inner { padding: 2.2rem 2rem 1.8rem; }

    .login-card__head,
    .login-form,
    .login-card__foot,
    .login-alert {
        width: 100%;
        max-width: 32rem;
        margin-left: auto;
        margin-right: auto;
    }

    .login-card__title { font-size: 1.8rem; }
}

/* Mobile : la rangee des atouts ferme la carte, comme sur la maquette. */
@media (max-width: 47.99rem) {
    .login-atouts {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: .4rem;
        margin: 1.2rem 0 0;
        padding: 1.1rem 0 0;
        list-style: none;
        border-top: 1px solid var(--or-bord);
    }

    /* La mention d'editeur passe sous les icones : c'est la derniere ligne de
       la page, apres les atouts. */
    .login-card__rights { margin-top: 1.1rem; }

    .login-atouts li {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: .4rem;
        font-size: .6rem;
        font-weight: 700;
        letter-spacing: .07em;
        text-transform: uppercase;
        color: var(--or-nuit);
        text-align: center;
    }

    .login-atouts svg { width: 1.45rem; height: 1.45rem; color: var(--or-teal); }
}

/* ---------- Animations reduites ---------- */

/* Chaque animation ne decrit que son point de depart : les couper affiche donc
   la scene dans son etat final, mallette ouverte et elements en place. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        /* Sans cette ligne, le delai reste actif : avec un remplissage « both »
           l'element garde son etat de depart, donc invisible, pendant deux
           secondes. La scene doit etre complete des le premier rendu. */
        animation-delay: 0s !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }

    /* Aucun deplacement au survol : c'est ce que le reglage demande. */
    .btn:hover:not([disabled]),
    .icon-btn:hover,
    .timeline__item:hover::before { transform: none !important; }
}

/* =========================================================================
   v3.2.1 — catalogues administrables, interfaces generiques, hospitalisation
   ========================================================================= */

/* Case a cocher alignee sur la ligne de champs, sans casser le rythme du
   formulaire en colonnes. */
.field--check { justify-content: flex-end; }
.field--check label {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    min-height: var(--touch);
    font-weight: 500;
    cursor: pointer;
}
.field--check input { width: 20px; height: 20px; accent-color: var(--bleu); }

.badge--neutral { background: var(--gris-100); color: var(--gris-700); }

/* Cases a cocher des capacites d'un type de personnel : meme pastille tactile
   que les jours de la semaine, sur une grille qui tient sur tablette. */
.capabilities {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: .4rem;
}

/* Apercu des sections generees : l'admin voit ce qu'il vient de creer. */
.preview {
    padding: .85rem 1rem;
    background: var(--bleu-clair);
    border-radius: var(--rayon);
}
.preview .card__subtitle { margin-top: 0; }
.preview__list { margin: 0; padding-left: 1.1rem; color: var(--bleu-fonce); }
.preview__list li { margin: .2rem 0; }

/* Empilement simple de cartes dans une meme section. */
.stack { display: flex; flex-direction: column; gap: 1rem; }

/* Soin en retard : l'heure est passee sans qu'il ait ete marque. C'est un
   signal visuel, pas une bascule de statut — cette version ne depend d'aucun
   scheduler. */
.care--late { border-left: 4px solid var(--ambre); }
.care--late .care__time { color: var(--ambre); font-weight: 600; }
.care--assigned { border-left: 4px solid var(--bleu); }

/* Cellule d'actions d'un tableau : le bouton et son icone restent sur la meme
   ligne, meme quand le libelle est long (« Modifier / reaffecter »). La
   colonne peut s'elargir, la ligne ne doit pas se casser en deux. */
.table .btn-row {
    flex-wrap: nowrap;
    align-items: center;
    justify-content: flex-end;
}
.table td:last-child { white-space: nowrap; }

/* Capacite imposee par un role : cochee, verrouillee, et visiblement pas au
   meme titre que les autres — sans quoi l'admin croirait pouvoir la retirer. */
.weekdays__day--locked {
    background: var(--gris-100);
    border-style: dashed;
    color: var(--gris-700);
    cursor: not-allowed;
}
.weekdays__day--locked input { cursor: not-allowed; }

.capability__lock {
    margin-left: auto;
    padding: 1px var(--e2);
    border-radius: var(--rayon-pilule);
    background: var(--gris-200);
    color: var(--gris-700);
    font-size: var(--texte-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
}

/* Soin annule (v3.2.3, point 4) : la ligne reste lisible mais visiblement
   hors jeu. Elle n'est ni masquee ni supprimee — le dossier d'un patient ne
   se reecrit pas — et le gris seul ne suffirait pas a distinguer un soin
   annule d'un soin simplement passe. */
.table tr.is-cancelled td { color: var(--gris-700); }
.table tr.is-cancelled td:nth-child(2) { text-decoration: line-through; }

/* Cloche de notification (v3.2.3, point 2).
   Le panneau est ancre sous la cloche, en position absolue : la barre de
   marque est de hauteur fixe et ne doit pas s'etirer quand on l'ouvre. */
.bell { position: relative; display: inline-flex; }
.bell__button { position: relative; }

/* Le badge chevauche l'icone plutot que de la pousser : la barre garde la
   meme largeur, qu'il y ait des notifications ou non. */
.bell__badge {
    position: absolute;
    top: -.15rem;
    right: -.15rem;
    min-width: 1.1rem;
    padding: 0 .25rem;
    border-radius: 999px;
    background: var(--rouge, #c0392b);
    color: #fff;
    font-size: .68rem;
    font-weight: 700;
    line-height: 1.1rem;
    text-align: center;
}

.bell__panel {
    position: absolute;
    top: calc(100% + .5rem);
    right: 0;
    z-index: 40;
    width: min(22rem, calc(100vw - 2rem));
    max-height: 70vh;
    overflow-y: auto;
    background: #fff;
    color: var(--gris-900);
    border: 1px solid var(--gris-300);
    border-radius: var(--rayon);
    box-shadow: 0 12px 32px rgba(0, 0, 0, .18);
}

.bell__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .6rem .8rem;
    border-bottom: 1px solid var(--gris-300);
}

.bell__item {
    display: grid;
    gap: .1rem;
    padding: .6rem .8rem;
    border-bottom: 1px solid var(--gris-100);
    color: inherit;
    text-decoration: none;
}
.bell__item:hover { background: var(--gris-100); }
.bell__item:last-child { border-bottom: 0; }

/* Une notification non lue se distingue par un liseré, pas par une couleur de
   fond : le panneau reste lisible quand tout est neuf. */
.bell__item--unread { border-left: 3px solid var(--bleu); }

.bell__type {
    font-size: .7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--gris-700);
}
.bell__title { font-size: .92rem; }
.bell__time { font-size: .75rem; color: var(--gris-700); }

/* Carte de profil (v3.2.3, point 3). Meme ancrage que la cloche : le panneau
   flotte sous l'avatar, la barre de marque garde sa hauteur. */
.profil { position: relative; display: inline-flex; }

/* Avatar generique : les initiales, pas de photo a stocker ni a redimensionner. */
.profil__avatar {
    display: grid;
    place-items: center;
    width: 2.1rem;
    height: 2.1rem;
    border: 0;
    border-radius: 999px;
    /* Sarcelle plein : sur la barre blanche, le fond translucide d'avant
       n'existait plus. C'est aussi la seule tache de couleur de marque de la
       barre — l'endroit ou l'on se reconnait. */
    background: var(--sarcelle);
    color: #fff;
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .02em;
    cursor: pointer;
}
.profil__avatar:hover { background: var(--sarcelle-vif); }

.profil__panel {
    position: absolute;
    top: calc(100% + .5rem);
    right: 0;
    z-index: 40;
    width: min(23rem, calc(100vw - 2rem));
    background: #fff;
    color: var(--gris-900);
    border: 1px solid var(--gris-300);
    border-radius: var(--rayon);
    box-shadow: 0 12px 32px rgba(0, 0, 0, .18);
}

/* En-tete de la carte : avatar, nom, fonction. La fonction monte a cote du
   nom — c'est ce qu'on lit en premier, pas une ligne de liste parmi d'autres. */
.profil__head {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .7rem .8rem;
    border-bottom: 1px solid var(--gris-300);
}
.profil__who { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.profil__who strong { overflow-wrap: anywhere; }
.profil__role { font-size: .82rem; color: var(--gris-700); }
.profil__head .alert__dismiss { margin-left: auto; }

/* L'avatar de la carte est plus grand que celui de la barre, et sur fond
   clair : la barre est bleu nuit, la carte est blanche. */
.profil__avatar--large {
    width: 2.6rem;
    height: 2.6rem;
    flex: 0 0 auto;
    background: var(--bleu);
    color: #fff;
    font-size: .92rem;
    cursor: default;
}
.profil__avatar--large:hover { background: var(--bleu); }

.profil__identity { margin: 0; padding: .7rem .8rem; display: grid; gap: .55rem; }
.profil__identity dt {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--gris-700);
}
.profil__identity dd { margin: .1rem 0 0; font-size: .92rem; overflow-wrap: anywhere; }

.profil__actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .7rem .8rem;
    border-top: 1px solid var(--gris-300);
}
/* Les actions du compte occupent la largeur, la deconnexion reste une icone au
   bout : les deux ne sont pas de meme poids. */
.profil__links {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    flex: 1 1 auto;
    min-width: 0;
}

/* En colonne, chaque action dispose de toute la largeur de la carte : le
   libelle tient sur une ligne sans que rien ne deborde, et une troisieme
   action s'ajouterait sans retoucher la mise en page. Cote a cote — la mise en
   page d'avant la v3.2.9, quand il n'y avait qu'une seule action — deux
   libelles en `nowrap` ne pouvaient plus retrecir et sortaient du cadre. */
.profil__links .btn { width: 100%; white-space: nowrap; padding-inline: .75rem; }

/* Utilise par les rangees Enregistrer / Annuler des formulaires de la carte,
   ou deux boutons courts se partagent bien une ligne. */
.profil__grow { flex: 1 1 auto; white-space: nowrap; padding-inline: .75rem; }
.profil__actions form { display: flex; flex: 0 0 auto; }

.icon-btn--danger { color: var(--rouge); }
.icon-btn--danger:hover { background: var(--rouge-clair); }
.profil__form { padding: .7rem .8rem; border-top: 1px solid var(--gris-300); }

/* Notes de releve (v3.2.3, point 4). Un liseré plutot qu'un cadre : la liste
   se lit d'un coup d'oeil au moment de la releve, sans decoration. */
.handoff__note {
    margin-top: .6rem;
    padding: .5rem .7rem;
    border-left: 3px solid var(--bleu-clair);
    background: var(--gris-100);
    border-radius: 0 var(--rayon) var(--rayon) 0;
}
.handoff__meta {
    display: flex;
    justify-content: space-between;
    gap: .5rem;
    font-size: .78rem;
    color: var(--gris-700);
}
.handoff__note p { margin: .2rem 0 0; }

/* Barre d'actions groupees (v3.2.4). Elle n'existe que quand une ligne est
   cochee : une barre toujours presente mais inactive n'apprend rien et vole
   de la place sur tablette. */
.bulkbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--e2);
    margin: var(--e3) 0;
    padding: var(--e2) var(--e3);
    border-radius: var(--rayon);
    background: var(--bleu-clair);
    border: 1px solid var(--bleu-vif);
    font-size: var(--texte-base);
    animation: depliage var(--duree-lente) var(--courbe);
}
.bulkbar span { font-weight: 650; margin-right: auto; }

/* La colonne des cases reste etroite : c'est une poignee, pas une donnee. */
.table__check { width: 2.4rem; text-align: center; }
.table__check input { margin: 0; }

/* Groupes du formulaire d'enregistrement (v3.2.5). Le meme cadre que les
   accompagnateurs : l'ecran se lit alors comme trois blocs courts plutot que
   comme une colonne de neuf champs qu'il faut derouler en entier. */
.formset {
    border: 1px solid var(--gris-200);
    background: var(--gris-50);
    border-radius: var(--rayon);
    padding: var(--e4);
    display: flex;
    flex-direction: column;
    gap: var(--e4);
}
.formset legend {
    font-weight: 700; padding: 0 var(--e2);
    font-size: var(--texte-xs); text-transform: uppercase; letter-spacing: .06em;
    color: var(--gris-500);
}
.formset input, .formset select, .formset textarea { background: var(--blanc); }

/* Un champ qui merite plus de place que ses voisins sur la meme ligne —
   « Profession » a cote de « Age » et « Sexe ». */
.field-row .field--wide { flex: 2 1 200px; }

/* Note laissee par l'accueil sur un dossier (v3.2.5). Un liseré ambre : elle
   n'est ni une alerte ni une donnee medicale, mais elle doit se voir. */
.record__note {
    margin: 0 0 var(--e4);
    padding: var(--e3);
    font-size: var(--texte-base);
    border-left: 3px solid var(--ambre);
    background: var(--ambre-clair);
    border-radius: 0 var(--rayon-sm) var(--rayon-sm) 0;
}

/* Ordonnance ligne a ligne (v3.2.6). Le rang est un reperage, pas une donnee
   a saisir : il reste hors des champs, dans sa propre colonne. */
.ordo { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e2); }

.ordo__line {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    gap: var(--e3);
    padding: var(--e3);
    background: var(--gris-50);
    border: 1px solid var(--gris-200);
    border-radius: var(--rayon);
    transition: border-color var(--transition), box-shadow var(--transition);
}
.ordo__line:focus-within { border-color: var(--bleu-vif); box-shadow: var(--anneau); }

.ordo__rank {
    display: grid; place-items: center;
    width: 1.75rem; height: 1.75rem;
    margin-top: 1.6rem;
    background: var(--bleu-clair); color: var(--bleu-fonce);
    border-radius: var(--rayon-pilule);
    font-size: var(--texte-sm); font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Grille explicite plutot qu'un flex qui se rabat : avec le flex, « Duree »
   retombait seule sur une deuxieme ligne alors que la place restait. */
.ordo__fields {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.2fr) minmax(0, .8fr);
    gap: var(--e2) var(--e3);
    min-width: 0;
}

@media (max-width: 820px) {
    .ordo__fields { grid-template-columns: minmax(0, 1fr); }
}

.ordo__remove { margin-top: 1.5rem; }

/* L'ajout d'une ligne est l'action attendue apres avoir rempli la precedente :
   elle porte son icone et reste a gauche du bouton d'enregistrement. */
.ordo__add { gap: var(--e1); }

@media (max-width: 600px) {
    .ordo__line { grid-template-columns: auto minmax(0, 1fr); }
    .ordo__rank { margin-top: 1.5rem; }
    .ordo__remove { grid-column: 2; justify-self: end; margin-top: 0; }
}

/* Ordonnance en lecture : les lignes gardent leur numerotation, c'est ce qui
   fait qu'on s'y retrouve au comptoir. */
.ordo-lu { margin: var(--e1) 0 0; padding-left: var(--e5); }
.ordo-lu li { margin: 0 0 var(--e1); }

/* ---------- Pied de page de l'editeur ----------
   Present sur toutes les interfaces via les gabarits : une page ajoutee plus
   tard en herite sans intervention. Discret par construction — il informe, il
   ne doit pas concurrencer le travail affiche au-dessus. */

/* Il se cale en bas de la fenetre par symetrie avec la barre de marque, qui
   se cale en haut : sur une page courte, la marge automatique l'y pousse ; sur
   une page longue, « sticky » l'y retient pendant le defilement. */
.app-body,
.board-body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
}

.app-footer {
    /* `margin-top: auto` suffit a le coller en bas d'une page courte : le corps
       est une colonne flex de la hauteur de l'ecran. Il etait en plus `sticky`,
       ce qui n'ajoutait rien sur une page courte et recouvrait le bas du
       contenu a chaque position de defilement sur une page longue — la
       signature du produit mangeait la derniere ligne d'un tableau. */
    margin-top: auto;
    background: var(--fond);

    /* Les deux mentions se rangent sur une seule ligne quand la largeur le
       permet, et se replient l'une sous l'autre sinon. */
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: .1rem 1.1rem;

    padding: .45rem var(--e4, 1.2rem);
    text-align: center;
    font-size: .78rem;
    line-height: 1.35;
    color: var(--gris-500, #6d7880);
    border-top: 1px solid var(--gris-200, #e6ebee);
}

.app-footer p { margin: 0; }
.app-footer__produit strong { font-weight: 600; color: var(--gris-700, #454f56); }
.app-footer__rights { opacity: .85; }

.app-footer a {
    color: inherit;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: .15em;
}

.app-footer a:hover { color: var(--bleu); }

/* Sur le mur de la salle d'attente, l'ecran est lu de loin : le pied de page
   se fait plus discret encore, et ne prend pas de place sur les tickets. */
.app-footer--board {
    /* Le pied tenant desormais le bas de l'ecran, il passe au-dessus des
       cartes : sa discretion vient de la couleur du texte, plus d'une
       transparence qui laisserait defiler la file au travers. */
    background: var(--gris-900, #14191d);
    color: #78848c;
    padding: .3rem .5rem;
    font-size: .72rem;
    border-top: 0;
}

.app-footer--board .app-footer__produit strong { color: #97a3ab; }

/* ---------- Section « SMS » de l'administration (v3.2.8) ---------- */

.badge--queued { background: var(--gris-100); color: var(--gris-700); }
.badge--sent { background: var(--bleu-clair); color: var(--bleu-fonce); }
.badge--delivered { background: var(--vert-clair); color: var(--vert); }
.badge--failed { background: var(--rouge-clair); color: var(--rouge); }

/* Le compteur d'echecs, en tete de section : c'est lui qui doit se voir sans
   ouvrir la liste, sans quoi une passerelle en panne reste invisible. */
.sms-tally {
    display: flex; align-items: center; gap: var(--e3); flex-wrap: wrap;
    margin: var(--e3) 0 var(--e4);
    padding: var(--e3) var(--e4);
    border-radius: var(--rayon);
    border: 1px solid transparent; border-left-width: 3px;
    font-weight: 600;
}
.sms-tally--calme { background: var(--vert-clair); border-color: var(--vert); color: var(--sarcelle-fonce); }
.sms-tally--alerte { background: var(--rouge-clair); border-color: var(--rouge); color: #7d191c; }
.sms-tally__nombre { font-size: 1.5rem; font-weight: 800; line-height: 1; }
.sms-tally .btn { margin-left: auto; }

.sms-body { max-width: 42ch; color: var(--gris-700); font-size: var(--texte-sm); }
.sms-reason { color: var(--rouge); font-size: var(--texte-sm); }

/* ---------- Doublon probable a l'enregistrement (v3.2.8) ---------- */

/* Volontairement proche d'une alerte : la creation est interrompue, ce n'est
   pas un simple message d'information que l'on peut lire en diagonale. */
.doublon {
    margin: var(--e4) 0;
    padding: var(--e4);
    border-radius: var(--rayon);
    border: 1px solid var(--ambre); border-left-width: 3px;
    background: var(--ambre-clair); color: #834e00;
}
.doublon__titre { margin: 0 0 var(--e2); font-size: var(--texte-lg); font-weight: 700; }
.doublon__liste { list-style: none; margin: var(--e3) 0; padding: 0; display: grid; gap: var(--e2); }
.doublon__dossier {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--e3); flex-wrap: wrap;
    padding: var(--e3); border-radius: var(--rayon-sm);
    background: rgba(255, 255, 255, .7);
}
.doublon__nom { margin: 0; font-weight: 700; display: flex; gap: var(--e2); align-items: baseline; flex-wrap: wrap; }
.doublon__detail { margin: var(--e1) 0 0; font-size: var(--texte-sm); }
.doublon .hint { color: inherit; opacity: .85; }

/* ---------- Catalogue de tarifs a la caisse (v3.2.8) ---------- */

.queue__acte { display: inline-flex; gap: var(--e2); align-items: baseline; font-size: var(--texte-sm); color: var(--gris-700); }
.queue__acte strong { color: var(--bleu-fonce); }

/* L'acte facture, en tete du formulaire d'encaissement : c'est la reponse a
   « qu'est-ce que je paie ? », que le caissier devait demander. */
.acte-facture {
    display: flex; align-items: baseline; gap: var(--e2); flex-wrap: wrap;
    margin: 0 0 var(--e3); padding: var(--e3);
    border-radius: var(--rayon-sm); background: var(--bleu-clair); color: var(--bleu-fonce);
}
.acte-facture > span:first-child { font-size: var(--texte-xs); text-transform: uppercase; letter-spacing: .08em; }
.acte-facture strong { font-size: var(--texte-lg); }
.acte-facture__tarif { margin-left: auto; font-weight: 800; }

.field--check label { display: flex; align-items: center; gap: var(--e2); font-weight: 500; }

/* ---------- Retours et incidents (v3.2.8) ---------- */

.retour {
    margin: var(--e3) 0;
    padding: var(--e3) var(--e4);
    border: 1px solid var(--gris-200); border-radius: var(--rayon);
    background: #fff;
}
.retour__head { display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap; }
.retour__head time { margin-left: auto; color: var(--gris-500); font-size: var(--texte-sm); }
.retour__contexte { display: flex; gap: var(--e2); flex-wrap: wrap; margin: var(--e2) 0 0; font-size: var(--texte-sm); color: var(--gris-700); }
.retour__notes { margin: var(--e2) 0 0; font-size: var(--texte-sm); }
.retour__contenu { margin: var(--e2) 0 0; white-space: pre-line; }
.retour__resolution { margin: var(--e3) 0 0; padding: var(--e2) var(--e3); border-left: 3px solid var(--vert); background: var(--vert-clair); border-radius: var(--rayon-sm); }

/* ---------- Etiquette de version (v3.2.8) ---------- */

/* Discrete a dessein : elle doit pouvoir se lire quand on la cherche, sans
   entrer en concurrence avec la signature de l'editeur. */
.app-footer__version {
    margin-left: var(--e2);
    font-size: var(--texte-xs);
    color: var(--gris-500);
    font-variant-numeric: tabular-nums;
}

/* ---------- Envoi groupe de SMS (v3.2.9) ---------- */

.diffusion__resultats { list-style: none; margin: 0 0 var(--e3); padding: 0; display: grid; gap: var(--e2); }
.diffusion__resultats li {
    display: flex; align-items: center; justify-content: space-between; gap: var(--e3);
    padding: var(--e2) var(--e3); border-radius: var(--rayon-sm); background: var(--gris-100);
}
.diffusion__resultats .hint { margin-left: var(--e2); }

/* Le texte exact qui partira, relu une derniere fois avant confirmation. */
.diffusion__apercu {
    margin: 0 0 var(--e3); padding: var(--e3) var(--e4);
    border-left: 3px solid var(--bleu-fonce); border-radius: var(--rayon-sm);
    background: var(--bleu-clair); color: var(--bleu-fonce);
    white-space: pre-line;
}

/* ---------- Sondage par etape du parcours (v3.2.9) ---------- */

/* Chaque poste rencontre forme un bloc : la note et sa precision se lisent
   ensemble, sans confusion possible avec l'etape suivante. */
.etape {
    margin: 0 0 var(--e3);
    padding: var(--e3);
    border-left: 3px solid var(--bleu-clair);
    border-radius: var(--rayon-sm);
    background: var(--gris-100);
}
.etape .field:last-child { margin-bottom: 0; }

/* Le detail des notes par poste, dans la section « Retours et incidents ». */
.retour__etapes { list-style: none; margin: var(--e2) 0 0; padding: 0; display: grid; gap: var(--e1); }
.retour__etapes li { display: flex; gap: var(--e2); align-items: baseline; flex-wrap: wrap; font-size: var(--texte-sm); }
.retour__etapes .mono { font-weight: 700; color: var(--bleu-fonce); }
