/* =======================================================================
   Feuille de style de l'application.

   Charte reprise de l'ecosysteme : bleu de marque, encre, accent ambre,
   en-tete en degrade avec motif geometrique discret, pastilles numerotees.

   Une seule feuille pour les deux sens d'ecriture : aucune propriete
   left/right, uniquement des proprietes logiques. Une feuille rtl.css
   parallele finit toujours par diverger de l'originale.
   ======================================================================= */

:root {
    /* Marque. Ces quatre tokens sont les seuls a changer pour habiller
       l'application aux couleurs d'un client : tout le reste en decoule. */
    --marque: #0778ac;
    --marque-sombre: #055f88;
    --encre: #04405c;
    --accent: #e37400;

    --succes: #137333;
    --alerte: #b3261e;
    --attention: #9a6700;

    --page: #eef2f5;
    --surface: #ffffff;
    --surface-2: #f6f9fb;
    --surface-3: #eaf2f7;
    --bordure: #e3eaef;
    --bordure-forte: #cdd9e1;

    --texte: #10222c;
    --texte-faible: #5c7280;
    --texte-tenu: #90a4b0;

    --rayon: 12px;
    --rayon-petit: 8px;
    --ombre: 0 1px 2px rgba(4, 64, 92, .06), 0 8px 24px -12px rgba(4, 64, 92, .22);
    --ombre-forte: 0 10px 40px -12px rgba(4, 64, 92, .28);

    --barre: 252px;
    --police: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
}

/* Pile de polices couvrant l'arabe. Une pile latine seule rend l'arabe en repli
   systeme : le texte s'affiche mais la police change sans prevenir, et le PDF
   embarque une police qui peut manquer sur le serveur. Voir views/libs/libs.fonts.

   Deux fichiers statiques, et non un seul fichier variable : le moteur d'impression
   ne sait pas embarquer une instance de police variable dans un PDF, il en dessine
   les contours en Type3. Le document reste lisible mais alourdi, et la table des
   polices du PDF devient vide - donc incontrolable. Verifie le 27/08, voir
   tools/controle_police_pdf.py.

   font-display: block et non swap : a l'impression, swap fige le repli systeme si la
   police n'est pas encore chargee, et l'ordonnance sort dans la mauvaise police sans
   qu'aucune erreur ne le signale. */
@font-face {
    font-family: "AppArabe";
    src: url("/libs.fonts/NotoSansArabic-400.woff2") format("woff2");
    font-weight: 400;
    font-display: block;
    unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}

@font-face {
    font-family: "AppArabe";
    src: url("/libs.fonts/NotoSansArabic-700.woff2") format("woff2");
    font-weight: 700;
    font-display: block;
    unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--page);
    color: var(--texte);
    font-family: "AppArabe", var(--police);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

/* Les chiffres restent en ecriture latine, y compris en arabe : c'est l'usage
   en Tunisie et cela evite une erreur de lecture sur une posologie. */
[dir="rtl"] { font-feature-settings: "lnum" 1; }

/* Une chaine en ecriture latine posee dans un flux arabe est reordonnee
   visuellement par l'algorithme bidirectionnel : O+ s'affiche +O. Sur une
   ordonnance, un groupe sanguin inverse est une erreur medicale. */
bdi, .latin { unicode-bidi: isolate; }

a { color: var(--marque); text-decoration: none; }
a:hover { text-decoration: underline; }

/* 🔴 LA TAILLE PAR DEFAUT EST OBLIGATOIRE, PAS UN CONFORT.
 *
 * Les icones d'icone.ejs ne portent qu'un viewBox, jamais de width/height : leur taille
 * vient toujours d'une regle de contexte (.bouton svg, .onglets button svg, etc.). Dans
 * un contexte qui n'en a pas, le SVG prend toute la place disponible - un globe de 900
 * pixels au milieu d'une carte, constate le 23/09 sur "Moteurs disponibles", ou .cle
 * existe mais hors de .indicateur, dont la regle le dimensionnait.
 *
 * Ce defaut ferme le piege pour de bon : les regles de contexte sont toutes plus
 * specifiques, elles continuent donc de gagner. */
svg { flex-shrink: 0; width: 16px; height: 16px; }

/* ---------- Motif de marque, partage par l'ecran de connexion et la barre ---------- */
.motif::after {
    background-size: 190px 190px;
    content: "";
    position: absolute; inset: 0;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cg fill='none' stroke='%23ffffff' stroke-opacity='0.06' stroke-width='2'%3E%3Cpath d='M0 60 L30 30 L60 60 L90 30 L120 60'/%3E%3Cpath d='M0 90 L30 60 L60 90 L90 60 L120 90'/%3E%3Ccircle cx='30' cy='30' r='4'/%3E%3Ccircle cx='90' cy='30' r='4'/%3E%3C/g%3E%3C/svg%3E");
    pointer-events: none;
}
.motif > * { position: relative; z-index: 1; }

/* =======================================================================
   Coquille : barre laterale + zone de contenu
   ======================================================================= */

.coquille { display: flex; min-height: 100vh; }

.barre {
    position: relative;
    width: var(--barre);
    flex-shrink: 0;
    background: linear-gradient(168deg, var(--encre) 0%, #062b3e 60%, #04202f 100%);
    color: #dceaf2;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.barre .marque-bloc {
    display: flex; align-items: center; gap: 11px;
    padding: 20px 20px 18px;
    border-block-end: 1px solid rgba(255,255,255,.09);
}
.barre .marque-bloc .nom { font-size: 1.02rem; font-weight: 700; letter-spacing: -.01em; color: #fff; }
.barre .marque-bloc .slogan {
    font-size: .64rem; text-transform: uppercase; letter-spacing: .1em;
    color: #8fb6cb; margin-block-start: 1px;
}

.barre nav { padding: 14px 12px; overflow-y: auto; flex: 1; }

.barre .groupe {
    font-size: .63rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .14em; color: #6f96ab;
    padding: 14px 10px 6px;
}
.barre .groupe:first-child { padding-block-start: 2px; }

.barre nav a {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 10px;
    margin-block-end: 2px;
    border-radius: var(--rayon-petit);
    color: #c3d9e5;
    font-size: .88rem;
    border-inline-start: 3px solid transparent;
    transition: background .12s, color .12s;
}
.barre nav a:hover { background: rgba(255,255,255,.07); color: #fff; text-decoration: none; }
.barre nav a.actif {
    background: rgba(255,255,255,.11);
    color: #fff;
    font-weight: 600;
    border-inline-start-color: var(--accent);
}
.barre nav a svg { width: 17px; height: 17px; opacity: .85; }
.barre nav a.actif svg { opacity: 1; }

.barre .pied {
    padding: 14px 20px;
    border-block-start: 1px solid rgba(255,255,255,.09);
    font-size: .72rem;
    color: #7ea3b8;
}
.barre .pied .noeud { font-family: ui-monospace, Consolas, monospace; font-size: .68rem; opacity: .8; }

.zone { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* ---------- Barre du haut ---------- */
.haut {
    display: flex; align-items: center; gap: 16px;
    padding: 0 26px;
    height: 60px;
    background: var(--surface);
    border-block-end: 1px solid var(--bordure);
}
.haut .fil { font-size: .68rem; text-transform: uppercase; letter-spacing: .12em; color: var(--texte-tenu); }
.haut .titre { font-size: 1.02rem; font-weight: 700; color: var(--encre); letter-spacing: -.01em; line-height: 1.2; }
.haut .pousse { margin-inline-start: auto; display: flex; align-items: center; gap: 10px; }

.site-actif {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 5px 12px; border-radius: 999px;
    background: var(--surface-3); color: var(--encre);
    font-size: .8rem; font-weight: 600;
    border: 1px solid #d3e5ef;
}
.site-actif svg { width: 14px; height: 14px; color: var(--marque); }
.site-actif.aucun { background: #fff6e8; border-color: #f2ddbe; color: var(--attention); font-weight: 500; }

.langues { display: inline-flex; border: 1px solid var(--bordure-forte); border-radius: 999px; overflow: hidden; }
.langues a {
    padding: 4px 11px; font-size: .72rem; font-weight: 600; letter-spacing: .04em;
    color: var(--texte-faible); background: var(--surface);
}
.langues a:hover { background: var(--surface-2); text-decoration: none; }
.langues a.actif { background: var(--marque); color: #fff; }

.utilisateur { display: flex; align-items: center; gap: 9px; }
.utilisateur .pastille {
    width: 32px; height: 32px; border-radius: 50%;
    background: linear-gradient(140deg, var(--marque), var(--encre));
    color: #fff; font-size: .78rem; font-weight: 700;
    display: flex; align-items: center; justify-content: center;
}
.utilisateur .nom { font-size: .82rem; font-weight: 600; line-height: 1.15; }
.utilisateur .role { font-size: .68rem; color: var(--texte-tenu); }
.utilisateur .sortie { color: var(--texte-tenu); display: flex; padding: 6px; border-radius: var(--rayon-petit); }
.utilisateur .sortie:hover { background: var(--surface-2); color: var(--alerte); }
.utilisateur .sortie svg { width: 17px; height: 17px; }

/* ---------- Contenu ---------- */
/* La largeur utile. Un tableau de huit colonnes - la matrice des droits, le journal du
   stock, le fichier des patients - etouffe a 1180 px sur un ecran large, et les
   colonnes se replient les unes sur les autres.

   Une borne demeure : une ligne de texte qui traverse un ecran de 2500 px ne se lit
   plus. C'est la raison de la marge laterale, et c'est pour cela qu'on elargit sans
   retirer la borne. */
main { padding: 26px 30px; flex: 1; }
.contenu { max-width: 1480px; margin-inline: auto; }

.entete-page { margin-block-end: 22px; }
.entete-page .eyebrow { font-size: .68rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--marque); }
.entete-page h1 { margin: 3px 0 0; font-size: 1.55rem; font-weight: 700; letter-spacing: -.02em; color: var(--encre); }
.entete-page .sous { color: var(--texte-faible); margin: 5px 0 0; font-size: .92rem; }
.entete-page .filet { width: 44px; height: 3px; background: var(--accent); border-radius: 2px; margin-block-start: 14px; }

/* =======================================================================
   Composants
   ======================================================================= */

.carte {
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    margin-block-end: 18px;
    overflow: hidden;
}
.carte > .tete-carte {
    display: flex; align-items: center; gap: 12px;
    padding: 15px 18px;
    border-block-end: 1px solid var(--bordure);
    background: var(--surface-2);
}
.carte > .tete-carte h2 {
    margin: 0; font-size: .98rem; font-weight: 700; color: var(--encre);
    display: flex; align-items: center; gap: 10px; letter-spacing: -.01em;
}
.carte > .tete-carte .num {
    width: 24px; height: 24px; border-radius: 7px; flex-shrink: 0;
    background: var(--marque); color: #fff;
    font-size: .76rem; font-weight: 700;
    display: inline-flex; align-items: center; justify-content: center;
}
/* La tete d'une carte porte souvent un compteur ET le bouton qui ouvre la modale
   de saisie : le bloc est une rangee a lui seul, sinon les deux se collent. */
.carte > .tete-carte .pousse { margin-inline-start: auto; display: flex; align-items: center; gap: 10px; }

/* Bouton icone seule, generique (en-tete de carte - ex: la loupe qui affiche/masque
   une barre de filtres - ou dans une cellule de tableau, ex: modifier une ligne) -
   meme langage visuel que .tete-modale .fermer. */
.bouton-icone {
    display: inline-flex; padding: 7px; border: 0; background: transparent;
    border-radius: var(--rayon-petit); color: var(--texte-faible); cursor: pointer;
    vertical-align: middle;
}
.bouton-icone:hover { background: var(--surface-3); color: var(--texte); }
.bouton-icone:focus-visible { outline: 2px solid var(--marque); outline-offset: 1px; }
.bouton-icone svg { width: 17px; height: 17px; }
.bouton-icone.actif { background: var(--surface-3); color: var(--marque); }
.carte > .corps-carte { padding: 18px; }
.carte > .corps-carte.serre { padding: 0; }

/* ---------- Indicateurs ---------- */
.indicateurs { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; margin-block-end: 20px; }

.indicateur {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    padding: 16px 18px;
    overflow: hidden;
}
.indicateur::before {
    content: ""; position: absolute; inset-block-start: 0; inset-inline-start: 0;
    width: 3px; height: 100%; background: var(--marque);
}
.indicateur.accent::before { background: var(--accent); }
.indicateur.succes::before { background: var(--succes); }
.indicateur.attention::before { background: var(--attention); }
.indicateur.alerte::before { background: var(--alerte); }

/* Une constante hors norme se voit au premier coup d'oeil : le chiffre change de couleur,
   pas seulement le liseré. Une fièvre à 38,9 ne doit pas se lire comme un poids. */
.indicateur.alerte .valeur { color: var(--alerte); }
.indicateur.attention .valeur { color: var(--attention); }
.indicateur .cle {
    display: flex; align-items: center; gap: 7px;
    font-size: .7rem; font-weight: 600; text-transform: uppercase; letter-spacing: .1em;
    color: var(--texte-faible);
}
.indicateur .cle svg { width: 14px; height: 14px; color: var(--texte-tenu); }
.indicateur .valeur {
    font-size: 1.9rem; font-weight: 700; color: var(--encre);
    line-height: 1.15; margin-block-start: 6px;
    font-variant-numeric: tabular-nums;
}
.indicateur .note { font-size: .76rem; color: var(--texte-tenu); margin-block-start: 2px; }

/* ---------- Grille de cartes cliquables (sites) ---------- */
.vignettes { display: grid; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); gap: 14px; }

.vignette {
    display: block;
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    padding: 16px 17px;
    color: inherit;
    transition: border-color .12s, box-shadow .12s, transform .12s;
}
.vignette:hover {
    text-decoration: none;
    border-color: var(--marque);
    box-shadow: var(--ombre-forte);
    transform: translateY(-1px);
}
.vignette.choisi { border-color: var(--marque); background: linear-gradient(180deg, var(--surface-3), var(--surface)); }
.vignette .haut-vignette { display: flex; align-items: flex-start; gap: 10px; }
.vignette .nom { font-weight: 700; color: var(--encre); letter-spacing: -.01em; }
.vignette .lieu { font-size: .8rem; color: var(--texte-faible); }
.vignette .pousse { margin-inline-start: auto; }
.vignette .chiffres { display: flex; gap: 18px; margin-block-start: 13px; padding-block-start: 12px; border-block-start: 1px solid var(--bordure); }
.vignette .chiffres div { font-size: .74rem; color: var(--texte-tenu); text-transform: uppercase; letter-spacing: .06em; }
.vignette .chiffres b { display: block; font-size: 1.05rem; color: var(--texte); font-variant-numeric: tabular-nums; letter-spacing: 0; }

/* ---------- Tableaux ---------- */
.tableau-enveloppe { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: .88rem; }
thead th {
    position: sticky; inset-block-start: 0;
    background: var(--surface-2);
    padding: 10px 14px;
    text-align: start;
    font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .09em;
    color: var(--texte-faible);
    border-block-end: 1px solid var(--bordure);
    white-space: nowrap;
}
tbody td {
    padding: 11px 14px;
    border-block-end: 1px solid var(--bordure);
    vertical-align: middle;
}
tbody tr:last-child td { border-block-end: none; }
tbody tr:hover { background: var(--surface-2); }
td.nombre, th.nombre { text-align: end; font-variant-numeric: tabular-nums; }
td.faible { color: var(--texte-tenu); font-size: .82rem; }
td.mono, .mono { font-family: ui-monospace, Consolas, "Courier New", monospace; font-size: .8rem; }

/* ---------- Formulaires ---------- */
.grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 14px; }

.champ { display: flex; flex-direction: column; gap: 5px; }
.champ label { font-size: .74rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--texte-faible); }

/* L'etoile des champs obligatoires.
   aria-hidden : un lecteur d'ecran qui annonce "asterisque" apres chaque libelle est
   pire que rien. C'est aria-required, pose sur le champ lui-meme, qui porte
   l'information aux outils d'assistance ; l'etoile ne parle qu'a l'oeil. */
.champ label .requis { color: var(--alerte); margin-inline-start: 2px; font-weight: 700; }
.champ .aide { font-size: .74rem; color: var(--texte-tenu); }

input, select, textarea {
    padding: 9px 11px;
    border: 1px solid var(--bordure-forte);
    border-radius: var(--rayon-petit);
    font: inherit; font-size: .9rem;
    color: inherit;
    background: var(--surface);
    text-align: start;
    width: 100%;
    transition: border-color .12s, box-shadow .12s;
}
input:hover, select:hover, textarea:hover { border-color: #b6c7d2; }
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--marque);
    box-shadow: 0 0 0 3px rgba(7, 120, 172, .16);
}

/* Champ portant une action a l'interieur. Le bouton se pose du cote de la fin de
   ligne, donc a gauche en arabe : d'ou inset-inline-end et non right. */
.champ-bascule { position: relative; display: flex; }
/* Un mot de passe est une chaine technique, jamais du texte arabe. Revele dans un
   ecran en arabe, "MotDePasse2026!" se lit "!MotDePasse2026" : la ponctuation migre
   du cote oppose, et le champ affiche alors autre chose que ce qui a ete tape.
   L'isolation bidi remet la valeur dans son ordre sans toucher au sens du champ,
   qui reste celui de la page : c'est lui qui place la reserve du bouton. */
.champ-bascule input { padding-inline-end: 38px; unicode-bidi: plaintext; }

/* Meme raison pour l'identifiant : c'est une adresse ou un numero, donc du latin dans un
   ecran arabe. Son indice de saisie en porte une aussi. */
#username { unicode-bidi: plaintext; }

/* L'indice reste un indice : il ne doit pas se lire comme une valeur deja saisie. */
input::placeholder { color: #9aa5b1; opacity: 1; }
.champ-bascule .bascule {
    position: absolute; inset-inline-end: 5px; top: 50%; transform: translateY(-50%);
    display: flex; align-items: center; justify-content: center;
    width: 28px; height: 28px;
    padding: 0;
    border: none; border-radius: var(--rayon-petit);
    background: transparent;
    color: var(--texte-faible);
    cursor: pointer;
}
.champ-bascule .bascule:hover { background: var(--surface-3); color: var(--texte); }
.champ-bascule .bascule:focus-visible { outline: 2px solid var(--marque); outline-offset: 1px; }
.champ-bascule .bascule svg { width: 17px; height: 17px; }

/* Edge pose sa propre icone de revelation dans un champ mot de passe : sans cela,
   deux yeux cote a cote, dont un que l'application ne pilote pas. */
input::-ms-reveal { display: none; }

/* ---------- Zone de depot d'un fichier (glisser-deposer) ----------
 *
 * Un <input type="file"> qui RECOUVRE toute la zone (opacite nulle, inset:0) : le
 * depot d'un fichier dessus declenche le "change" natif du navigateur, exactement
 * comme un choix au clic - aucun script de depot a ecrire, la logique d'import
 * existante (onchange="...fichierChoisi()") continue de s'appliquer telle quelle.
 * La classe "survol" est purement visuelle, posee par un petit script partage
 * (voir shared-contents/app.js) pendant qu'un fichier passe au-dessus.
 */
.zone-depot {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 6px;
    padding: 28px 16px;
    border: 2px dashed var(--bordure-forte);
    border-radius: var(--rayon);
    background: var(--surface-2);
    text-align: center;
    cursor: pointer;
    transition: border-color .12s, background-color .12s;
}
.zone-depot:hover, .zone-depot.survol { border-color: var(--marque); background: var(--surface-3); }
.zone-depot input[type="file"] {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0; cursor: pointer; padding: 0; border: none;
}
.zone-depot .zone-depot-icone { color: var(--texte-tenu); }
.zone-depot .zone-depot-icone svg { width: 30px; height: 30px; }
.zone-depot.survol .zone-depot-icone { color: var(--marque); }
.zone-depot .zone-depot-titre { font-weight: 600; color: var(--texte); font-size: .92rem; }
.zone-depot .zone-depot-titre .lien { color: var(--marque); text-decoration: underline; }
.zone-depot .zone-depot-formats { font-size: .74rem; color: var(--texte-tenu); }

/* Le fichier retenu, une fois choisi : son nom, sa taille, et de quoi le retirer -
   plutot que le "aucun fichier choisi" illisible que rend l'input natif. */
.fichier-choisi {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 14px;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-petit);
    background: var(--surface);
}
.fichier-choisi .fichier-icone { color: var(--marque); flex-shrink: 0; }
.fichier-choisi .fichier-icone svg { width: 22px; height: 22px; }
.fichier-choisi .fichier-infos { flex: 1; min-width: 0; }
.fichier-choisi .fichier-nom { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; unicode-bidi: plaintext; }
.fichier-choisi .fichier-taille { font-size: .74rem; color: var(--texte-faible); }
.fichier-choisi .retirer {
    flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    width: 28px; height: 28px;
    padding: 0;
    border: none; border-radius: var(--rayon-petit);
    background: transparent;
    color: var(--texte-faible);
    cursor: pointer;
}
.fichier-choisi .retirer:hover { background: var(--surface-3); color: var(--alerte); }
.fichier-choisi .retirer svg { width: 16px; height: 16px; }

/* Les boutons d'un formulaire se rangent a la FIN de la ligne - a droite en francais,
   a gauche en arabe, sans rien ecrire de specifique : flex-end suit le sens d'ecriture.
   Meme regle que .pied-modale, qui la tenait deja de son cote ; sans justify-content ils
   restaient colles au debut, et l'oeil qui a lu les champs de haut en bas ne les
   trouvait pas la ou il les cherche. */
.actions { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-block-start: 18px; padding-block-start: 16px; border-block-start: 1px solid var(--bordure); }

/* Un texte d'aide pose a cote des boutons reste au DEBUT de la ligne : il se lit avant
   d'agir, et sa marge automatique est ce qui pousse les boutons jusqu'au bout. */
.actions .aide { order: -1; margin-inline-end: auto; }

.bouton {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 9px 17px;
    border: 1px solid var(--marque);
    border-radius: var(--rayon-petit);
    background: var(--marque);
    color: #fff;
    font: inherit; font-size: .88rem; font-weight: 600;
    cursor: pointer;
    transition: background .12s, box-shadow .12s;
}
.bouton:hover { background: var(--marque-sombre); border-color: var(--marque-sombre); text-decoration: none; }
.bouton:disabled { opacity: .55; cursor: default; }
.bouton svg { width: 16px; height: 16px; }
.bouton.secondaire { background: var(--surface); color: var(--marque); }
.bouton.secondaire:hover { background: var(--surface-3); }
.bouton.discret { background: transparent; border-color: transparent; color: var(--texte-faible); }
.bouton.discret:hover { background: var(--surface-2); color: var(--texte); }
.bouton.petit { padding: 6px 11px; font-size: .82rem; }

/* Une valeur qui ne se modifie plus s'affiche comme du texte, pas comme un champ.
   Un champ desactive qui ressemble a un champ actif se fait cliquer, puis taper dedans,
   et l'utilisateur conclut que le logiciel a perdu sa saisie. */
.fige { color: var(--texte); font-size: .9rem; padding: 2px 0; min-height: 1.2em; }
.fige.bloc { white-space: pre-wrap; padding: 10px 12px; background: var(--surface-2); border-radius: var(--rayon-petit); min-height: 3.4em; }

input:disabled, select:disabled, textarea:disabled {
    background: var(--surface-2);
    color: var(--texte-faible);
    border-style: dashed;
    cursor: not-allowed;
}

/* Rapport mensuel : un indicateur cle et sa ligne de commentaire. Le chiffre vient des
   faits et ne se saisit pas ; le commentaire est la seule zone que le medecin remplit. */
.indicateur-rapport { display: grid; grid-template-columns: minmax(180px, 240px) 1fr; gap: 14px; align-items: center; padding: 12px 0; border-block-end: 1px solid var(--bordure); }
.indicateur-rapport:last-child { border-block-end: none; }
.indicateur-rapport .chiffre { display: flex; align-items: baseline; gap: 10px; }
.indicateur-rapport .chiffre .valeur { font-size: 1.5rem; font-weight: 700; color: var(--encre); }
.indicateur-rapport .chiffre .nom { font-size: .86rem; color: var(--texte-faible); }
.indicateur-rapport input { width: 100%; }

@media (max-width: 780px) {
    .indicateur-rapport { grid-template-columns: 1fr; gap: 6px; }
}

/* ---------- Etiquettes ---------- */
.etiquette {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 9px; border-radius: 999px;
    font-size: .74rem; font-weight: 600; letter-spacing: .01em;
    background: var(--surface-3); color: var(--encre);
    border: 1px solid #d3e5ef;
}
.etiquette.alerte { background: #fdeceb; border-color: #f7d3d0; color: var(--alerte); }
.etiquette.succes { background: #e6f4ea; border-color: #cbe6d3; color: var(--succes); }
.etiquette.attention { background: #fff6e8; border-color: #f2ddbe; color: var(--attention); }
.etiquette.neutre { background: var(--surface-2); border-color: var(--bordure); color: var(--texte-faible); }
.etiquette .pastille { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* ---------- Messages ---------- */
.message {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 12px 14px;
    border-radius: var(--rayon-petit);
    margin-block-end: 16px;
    font-size: .88rem;
    border: 1px solid transparent;
}
.message svg { width: 17px; height: 17px; margin-block-start: 1px; }
.message.alerte { background: #fdeceb; border-color: #f7d3d0; color: var(--alerte); }
.message.succes { background: #e6f4ea; border-color: #cbe6d3; color: var(--succes); }
.message.info { background: var(--surface-3); border-color: #d3e5ef; color: var(--encre); }

/* ---------- Onglets ---------- */
.onglets {
    display: flex; gap: 2px;
    border-block-end: 1px solid var(--bordure);
    margin-block-end: 18px;
    overflow-x: auto;
}
.onglets button {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 11px 16px;
    border: none;
    background: transparent;
    border-block-end: 2px solid transparent;
    color: var(--texte-faible);
    font: inherit; font-size: .88rem; font-weight: 600;
    cursor: pointer; white-space: nowrap;
}
.onglets button:hover { color: var(--texte); }
.onglets button.actif { color: var(--marque); border-block-end-color: var(--marque); }
.onglets button svg { width: 16px; height: 16px; }
.onglets .compte {
    background: var(--surface-3); color: var(--encre);
    border-radius: 999px; padding: 1px 7px; font-size: .72rem;
}
.onglets button.actif .compte { background: var(--marque); color: #fff; }

/* LES ACTIONS DE L'OBJET ENTIER, a cote des onglets mais HORS de leur defilement.
 *
 * Valider un rapport ou l'imprimer vaut depuis n'importe quel panneau : ces gestes ne
 * peuvent donc pas vivre DANS un onglet. Leur donner une carte a eux occupait un bloc
 * entier de l'ecran pour, sur un rapport deja transmis, le seul bouton "Imprimer".
 *
 * 🔴 ET ILS NE PEUVENT PAS VIVRE DANS `.onglets` NON PLUS. Cette barre defile
 * (`overflow-x: auto`) : six onglets plus quatre boutons la faisaient deborder, une
 * barre de defilement apparaissait SOUS les onglets et le dernier bouton se trouvait
 * coupe. `margin-inline-start: auto` n'y pouvait rien - il n'y a plus d'espace a
 * distribuer quand le contenu depasse deja.
 *
 * D'ou ce conteneur : les onglets defilent DANS leur zone, les actions restent a
 * cote, jamais coupees. `min-width: 0` sur la zone des onglets est ce qui l'autorise
 * a retrecir - sans lui, un enfant flex refuse de passer sous la taille de son
 * contenu et le debordement revient. */
.barre-outils {
    display: flex; align-items: stretch; gap: 12px;
    border-block-end: 1px solid var(--bordure);
    margin-block-end: 18px;
}
.barre-outils .onglets {
    flex: 1; min-width: 0;
    margin-block-end: 0;
    border-block-end: none;
}
.actions-objet {
    flex: none;
    display: inline-flex; align-items: center; gap: 6px;
    padding-inline-start: 4px;
}

/* Les actions se serrent : c'est une barre, pas un pied de formulaire. Le libelle
   reste - un bouton a icone seule sur un geste aussi engageant que "Valider" se
   devine, et un geste qui se devine se clique par erreur. */
.actions-objet .bouton { padding: 7px 11px; font-size: .82rem; }
.actions-objet .bouton svg { width: 15px; height: 15px; }

/* Sous 860px les actions passent sous les onglets plutot que de les etrangler. */
@media (max-width: 860px) {
    .barre-outils { flex-wrap: wrap; }
    .barre-outils .onglets { flex-basis: 100%; }
    .actions-objet { padding-block: 0 10px; }
}

/* Un dossier imprime doit sortir en entier : les onglets sont une commodite d'ecran,
   pas un decoupage de la piece. */
@media print {
    .dossier .onglets { display: none; }
    .dossier .ng-hide { display: block !important; }
}

/* ---------- Etat vide ---------- */
.vide { text-align: center; padding: 44px 24px; color: var(--texte-faible); }
.vide .rond {
    width: 52px; height: 52px; border-radius: 50%;
    background: var(--surface-3);
    display: inline-flex; align-items: center; justify-content: center;
    margin-block-end: 14px;
}
.vide .rond svg { width: 24px; height: 24px; color: var(--marque); }
.vide h3 { margin: 0 0 5px; font-size: .98rem; color: var(--encre); font-weight: 700; }
.vide p { margin: 0; font-size: .88rem; max-width: 40ch; margin-inline: auto; }

/* =======================================================================
   Ecran de connexion
   ======================================================================= */

.connexion { display: flex; min-height: 100vh; }

.connexion .panneau {
    position: relative;
    flex: 1;
    background: linear-gradient(150deg, var(--marque) 0%, var(--encre) 100%);
    color: #fff;
    padding: 52px 54px;
    display: flex; flex-direction: column; justify-content: center;
    overflow: hidden;
}
.connexion .panneau .marque-bloc { display: flex; align-items: center; gap: 13px; margin-block-end: 40px; }
.connexion .panneau .nom { font-size: 1.24rem; font-weight: 700; letter-spacing: -.02em; }
.connexion .panneau .slogan { font-size: .68rem; text-transform: uppercase; letter-spacing: .13em; opacity: .82; }
.connexion .panneau h1 { margin: 0; font-size: 1.9rem; font-weight: 700; line-height: 1.25; letter-spacing: -.02em; max-width: 14em; }
.connexion .panneau .filet { width: 44px; height: 3px; background: var(--accent); border-radius: 2px; margin: 18px 0 26px; }
.connexion .panneau ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 13px; max-width: 34em; }
.connexion .panneau li { display: flex; align-items: flex-start; gap: 11px; font-size: .92rem; color: #d6ecf7; }
.connexion .panneau li svg { width: 17px; height: 17px; margin-block-start: 3px; color: var(--accent); }

.connexion .formulaire {
    width: 440px; flex-shrink: 0;
    background: var(--surface);
    padding: 52px 48px;
    display: flex; flex-direction: column; justify-content: center;
}
.connexion .formulaire h2 { margin: 0 0 4px; font-size: 1.3rem; font-weight: 700; color: var(--encre); letter-spacing: -.02em; }
.connexion .formulaire .sous { color: var(--texte-faible); font-size: .9rem; margin: 0 0 26px; }
.connexion .formulaire .champ { margin-block-end: 15px; }
.connexion .formulaire .bouton { width: 100%; justify-content: center; padding: 11px; font-size: .92rem; }
.connexion .formulaire .bas { margin-block-start: 26px; display: flex; align-items: center; }
.connexion .formulaire .bas .langues { margin-inline-start: auto; }

.case { display: flex; align-items: center; gap: 8px; font-size: .86rem; color: var(--texte-faible); }
.case input { width: auto; }

/* Une rangee de cases a cocher dans un champ de formulaire. Ecrite en proprietes logiques :
   la rangee se retourne d'elle-meme en arabe, sans seconde regle a maintenir. */
.cases { display: flex; flex-wrap: wrap; gap: 6px 18px; padding-block-start: 8px; }

/* Un tableau dont une cellule porte le geste "traduire" : le geste allonge la cellule, et
   l'intitulé se retrouve centré donc SOUS sa propre valeur. Aligner en haut remet les deux
   sur la meme ligne. Classe a part, pour ne pas changer l'alignement des autres tableaux. */
.aligne-haut th, .aligne-haut td { vertical-align: top; }

/* La comparaison des moteurs de traduction. Bloc transitoire : rien n'est enregistre,
   il disparait des qu'on retient une sortie. Proprietes logiques, pour qu'il se retourne
   de lui-meme en arabe. */
.comparaison { margin-block-start: 12px; border: 1px solid var(--bordure); border-radius: var(--rayon-petit); overflow: hidden; }
.comparaison-tete { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    padding: 9px 12px; background: var(--page); border-block-end: 1px solid var(--bordure); }
.comparaison-tete .note { color: var(--texte-tenu); font-size: .78rem; }
.comparaison-ligne { padding: 10px 12px; border-block-end: 1px solid var(--bordure); }
.comparaison-ligne:last-child { border-block-end: 0; }
.comparaison-entete { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-block-end: 6px; }
.comparaison-entete .note { color: var(--texte-tenu); font-size: .78rem; }
.comparaison-ligne p { margin: 0; font-size: .9rem; }
.comparaison-ligne p.motif { color: var(--texte-faible); font-style: italic; }

@media (max-width: 900px) {
    .connexion .panneau { display: none; }
    .connexion .formulaire { width: 100%; }
    .barre { display: none; }
}

/* ---------------------------------------------------------------- pagination
   Proprietes LOGIQUES uniquement : la barre doit se retourner d'elle-meme en
   arabe, comme le reste de l'interface. Aucune regle left/right ici. */
.pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 16px;
    border-block-start: 1px solid var(--bordure);
    font-size: .86rem;
    color: var(--texte-faible);
}
.pagination-compte { white-space: nowrap; }
.pagination-rangs,
.pagination-taille { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.pagination-taille > span:first-child { margin-inline-end: 4px; }
.pagination-lien {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 30px;
    padding: 0 8px;
    border: 1px solid var(--bordure);
    border-radius: 4px;
    background: var(--surface);
    color: var(--texte);
    text-decoration: none;
    font-variant-numeric: tabular-nums;
}
.pagination-lien:hover { border-color: var(--marque); color: var(--marque); }
.pagination-lien.courant {
    background: var(--marque);
    border-color: var(--marque);
    color: #fff;
    font-weight: 600;
}
.pagination-lien.inactif { opacity: .4; pointer-events: none; }

@media print { .pagination { display: none; } }

/* Actions au fil d'une ligne de tableau. Sans .actions-ligne les boutons
   retombaient a la ligne les uns sous les autres et cassaient la hauteur des
   lignes ; sans .danger, "Confirmer" rendait en bouton principal pleine taille. */
.actions-ligne { white-space: nowrap; }
.actions-ligne .bouton { margin-inline-end: 4px; }
.actions-ligne .bouton:last-child { margin-inline-end: 0; }

.bouton.danger { background: var(--alerte); border-color: var(--alerte); color: #fff; }
.bouton.danger:hover { background: #8f1e17; border-color: #8f1e17; }
.bouton.discret.danger { background: transparent; border-color: transparent; color: var(--alerte); }
.bouton.discret.danger:hover { background: #fdecea; color: var(--alerte); }

/* --- Le geste "traduire ce texte", pose a cote d'un champ -----------------------
 *
 * Propriétés LOGIQUES uniquement : la meme feuille sert aux trois langues, et un
 * margin-left ferait passer le liseré du mauvais cote en arabe.
 *
 * Le panneau est nettement detache du champ qu'il commente : une traduction ne doit
 * jamais pouvoir se lire comme le texte du soignant. C'est une annotation, et elle
 * en a l'air.
 */
.traduire { margin-block-start: 8px; }

.traduire-panneau {
    margin-block-start: 10px;
    padding: 12px 14px;
    background: var(--surface-2);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-petit);
    border-inline-start: 3px solid var(--marque);
}

.traduire-panneau .grille { gap: 10px; }
.traduire-panneau .actions { margin-block-start: 10px; }
.traduire-panneau .vide { padding: 12px 0; }
.traduire-panneau .vide p { margin: 0; color: var(--texte-faible); font-size: .85rem; }

.traduction-ligne {
    margin-block-start: 12px;
    padding-block-start: 12px;
    border-block-start: 1px solid var(--bordure);
}

.traduction-ligne:first-of-type { border-block-start: 0; }

.traduction-tete {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-block-end: 6px;
}

.traduction-tete .note { margin: 0; }

/* Le texte traduit peut etre d'une autre langue que la page : il se remet dans son
   ordre propre sans qu'on touche au sens d'ecriture du champ, qui reste celui de la
   page. direction: ltr retournerait aussi ses proprietes logiques (regle 12). */
.traduction-ligne textarea { unicode-bidi: plaintext; }

@media print {
    /* Une proposition de traduction n'est pas le dossier : elle ne s'imprime pas avec
       lui. Ce qui fait foi est le texte du soignant. */
    .traduire { display: none; }
}


/* ======================================================================= modales

   Un formulaire de saisie s'ouvre PAR-DESSUS l'ecran au lieu de pousser la liste
   vers le bas. L'ecran s'ouvre donc sur ce qu'il porte - les comptes, les patients,
   le stock - et non sur un formulaire vide.

   Le voile est pose par ng-if et non par ng-show : masquee, une modale resterait
   dans le document, ses champs atteignables au clavier et lus par un lecteur
   d'ecran, et un ng-model continuerait d'y vivre.

   Aucune propriete left/right : la modale se retourne avec la page en arabe, comme
   le reste de la feuille.
   ======================================================================= */

.voile {
    position: fixed;
    inset: 0;
    z-index: 90;
    background: rgba(4, 64, 92, .48);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 6vh 18px 24px;
    overflow-y: auto;
}

/* Le defilement de la page dessous est bloque : sans cela, la molette fait glisser
   la liste derriere le voile et l'on perd l'endroit ou l'on etait. */
body.modale-ouverte { overflow: hidden; }

.modale {
    width: 100%;
    max-width: 720px;
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    box-shadow: var(--ombre-forte);
}

.modale.large { max-width: 1040px; }
.modale.etroite { max-width: 440px; }

.tete-modale {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 15px 18px;
    background: var(--surface-2);
    border-block-end: 1px solid var(--bordure);
    border-start-start-radius: var(--rayon);
    border-start-end-radius: var(--rayon);
}

.tete-modale h2 {
    margin: 0;
    font-size: 1.02rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--encre);
}

.tete-modale .sous {
    margin: 2px 0 0;
    font-size: .8rem;
    color: var(--texte-faible);
}

.tete-modale .fermer {
    margin-inline-start: auto;
    display: flex;
    padding: 7px;
    border: 0;
    background: transparent;
    border-radius: var(--rayon-petit);
    color: var(--texte-faible);
    cursor: pointer;
}

.tete-modale .fermer:hover { background: var(--surface-3); color: var(--texte); }
.tete-modale .fermer:focus-visible { outline: 2px solid var(--marque); outline-offset: 1px; }
.tete-modale .fermer svg { width: 17px; height: 17px; }

/* Le corps defile seul : la tete et le pied restent en place, donc le bouton
   d'enregistrement reste visible sur un formulaire long. */
.corps-modale {
    padding: 18px;
    overflow-y: auto;
}

/* Dans une modale, les boutons vivent au pied : le filet de .actions ferait un
   second trait juste au-dessus de celui du pied. */
.corps-modale > .actions:last-child { margin-block-start: 0; padding-block-start: 0; border-block-start: 0; }

/* Les actions se rangent a la FIN de la barre, et non au debut comme dans les
   cartes de la page : dans une boite de dialogue, c'est la que l'oeil termine sa
   lecture et c'est la que la main les cherche.

   flex-end et non "a droite" : la propriete est logique, donc en arabe les boutons
   passent a gauche d'eux-memes. Une regle ecrite en droite/gauche aurait demande sa
   jumelle, et les deux auraient fini par diverger. */
.pied-modale {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 14px 18px;
    background: var(--surface-2);
    border-block-start: 1px solid var(--bordure);
    border-end-start-radius: var(--rayon);
    border-end-end-radius: var(--rayon);
}

/* Une action qui n'est pas du meme ordre - supprimer, par exemple - se range au
   debut, a l'oppose du bouton qui enregistre : on ne pose pas une action
   destructrice sous le doigt qui valide. */
.pied-modale .a-part { margin-inline-end: auto; }

/* Sur un telephone, une modale a demi-hauteur est moins lisible qu'une page : elle
   prend tout l'ecran. */
@media (max-width: 640px) {
    .voile { padding: 0; }
    .modale, .modale.large, .modale.etroite {
        max-width: none;
        min-height: 100vh;
        max-height: none;
        border-radius: 0;
        border: 0;
    }
    .tete-modale, .pied-modale { border-radius: 0; }
}

/* Une modale ouverte n'est pas le document : elle ne s'imprime jamais avec lui. */
@media print { .voile { display: none; } }

/* Rattachement d'un compte aux sites. Des cases, pas une liste a selection multiple :
   un Ctrl+clic rate y efface tout sans le dire. */
/* minmax(0, ...) et non minmax(210px, ...) : une piste dont le minimum est fixe ne
   peut pas retrecir sous 210 px, donc elle DEBORDE son conteneur au lieu de se
   reorganiser. Dans une modale etroite, cela donnait une barre de defilement
   horizontale et des libelles ecrases a un mot par ligne. */
.cases-sites{ display:grid; grid-template-columns:repeat(auto-fill,minmax(min(210px,100%),1fr));
              gap:6px; margin-block-start:4px; inline-size:100%; }
.case-site{ display:flex; align-items:center; gap:8px; padding:7px 10px;
            border:1px solid var(--bordure); border-radius:7px; font-size:.86rem;
            cursor:pointer; background:var(--surface); min-inline-size:0; }
.case-site:hover{ border-color:var(--marque); }
/* L'etat "tous les clients" : coche, mais pas un choix. Il se voit comme un constat -
   pas de survol, pas de curseur de clic, un fond retenu. */
.case-site.figee{ cursor:default; opacity:.72; background:var(--surface-2); }
.case-site.figee:hover{ border-color:var(--bordure); }
/* La regle globale `input, select, textarea { width:100% }` s'applique aussi a une case
   a cocher : elle occupait les 218 px de la vignette, et il ne restait RIEN pour le nom
   du site - mesure : span de 0 px, texte rendu une lettre par ligne. La feuille porte
   deja `.case input { width:auto }` pour la meme raison ailleurs.

   On retire aussi le rembourrage et la bordure heritee : une case a cocher n'est pas un
   champ de saisie, et 9 px de rembourrage la decalent de son libelle. */
.case-site input{ flex:none; margin:0; inline-size:auto; width:auto;
                  padding:0; border:0; background:none; }

/* `.champ label` met les libelles en majuscules espacees : c'est juste pour un intitule
   de champ, faux pour une VALEUR. "SITE TUNISIEN (RECETTE)" en capitales espacees ne se
   lit pas, et prend deux fois la place. */
/* `.champ label` (0,1,1) l'emportait sur `.case-site` (0,1,0) : les noms de site
   restaient en capitales espacees. On qualifie par le conteneur plutot que d'ajouter
   un !important, qui gagnerait ici et surprendrait ailleurs. */
.cases-sites label.case-site{ text-transform:none; letter-spacing:normal; font-weight:400;
                              color:var(--texte); font-size:.86rem; }
/* Sans min-inline-size:0, un element flex refuse de passer sous la largeur de son
   contenu : le nom du site poussait la case hors du cadre. */
.case-site > span{ min-inline-size:0; overflow-wrap:anywhere; }

/* ===================================================================== ATTENDRE
   UN TRAITEMENT QUI DURE DOIT SE VOIR.

   Il n'existait aucun indicateur d'attente dans le produit : un lot de traduction
   annoncait son travail par un mot gris, a cote d'un bouton grise. Sur huit a douze
   secondes d'appel a un moteur distant, on ne sait pas si l'on a clique. Et ce qu'on
   fait alors, c'est recliquer.

   Le rouet tourne ; sous "mouvement reduit" il cesse de tourner et se contente de
   respirer. Une animation qu'on ne peut pas arreter n'est pas un detail pour tout le
   monde. */
.rouet{ display:inline-block; inline-size:14px; block-size:14px; flex:none;
        border:2px solid var(--bordure-forte);
        border:2px solid color-mix(in srgb, var(--marque) 28%, transparent);
        border-block-start-color:var(--marque); border-radius:50%;
        animation:rouet-tourne .7s linear infinite; vertical-align:-2px; }
.bouton .rouet{ border-color:rgba(255,255,255,.45);
                border-color:color-mix(in srgb, currentColor 34%, transparent);
                border-block-start-color:currentColor; margin-inline-end:7px; }

@keyframes rouet-tourne{ to{ transform:rotate(360deg); } }
@keyframes rouet-respire{ 50%{ opacity:.3; } }

@media (prefers-reduced-motion: reduce){
    .rouet{ animation:rouet-respire 1.4s ease-in-out infinite; }
}

/* Le bandeau d'attente : il prend la place du resultat, la ou l'oeil ira le chercher. */
.attente{ display:flex; align-items:center; gap:10px; padding:11px 14px;
          border-inline-start:3px solid var(--marque); border-radius:0 var(--rayon-petit) var(--rayon-petit) 0;
          background:var(--surface-2); color:var(--texte); font-size:.9rem; }
.attente .duree{ color:var(--texte-tenu); font-size:.84rem; }

/* ============================================================ TABLEAU GROUPE
   Une ligne par objet, son detail replie dessous. La ligne de groupe se clique en
   entier : viser un chevron de huit pixels a la souris est une exigence inutile. */
/* `ligne-pliante` et non `groupe` : `.barre .groupe` existe depuis toujours pour les
   intitules de section du menu lateral. Une regle nue `.groupe` les a repeints en blanc
   sur fond sombre, sur TOUS les ecrans - une classe empruntee s'applique la ou on ne
   regardait pas. */
tr.ligne-pliante{ cursor:pointer; background:var(--surface-2); }
tr.ligne-pliante:hover{ background:var(--surface-3); }
tr.ligne-pliante > td{ padding-block:10px; }
.ligne-groupe{ display:flex; align-items:center; gap:10px; }
.ligne-groupe .etiquette{ flex:none; }
.apercu-groupe{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-inline-size:52ch; }

/* Le chevron dit l'etat : ferme il pointe dans le sens de la lecture, ouvert il tombe.
   Il tourne dans le bon sens en arabe parce qu'il part de la direction du document. */
.chevron{ flex:none; inline-size:8px; block-size:8px; border-inline-end:2px solid var(--texte-tenu);
          border-block-end:2px solid var(--texte-tenu); transform:rotate(-45deg);
          transition:transform .15s ease; margin-inline-end:2px; }
[dir="rtl"] .chevron{ transform:rotate(135deg); }
tr.ligne-pliante.ouvert .chevron{ transform:rotate(45deg); }
[dir="rtl"] tr.ligne-pliante.ouvert .chevron{ transform:rotate(45deg); }

.detail-groupe > td:first-child{ padding-inline-start:26px; }
@media (prefers-reduced-motion: reduce){ .chevron{ transition:none; } }

/* ==================================================== RELIRE UNE RUBRIQUE TRADUITE
   Le parcours s'ouvre SOUS le panneau : on le lit en gardant le document a l'ecran. */
.parcours-traduit{ margin-block-start:14px; border:1px solid var(--bordure);
                   border-radius:var(--rayon-petit); background:var(--surface-2);
                   padding:12px 14px; }
.tete-parcours{ display:flex; align-items:center; gap:9px; margin-block-end:10px; }
.tete-parcours .pousse{ margin-inline-start:auto; }

.bloc-traduit{ background:var(--surface); border:1px solid var(--bordure);
               border-radius:var(--rayon-petit); padding:10px 12px; }
.bloc-traduit + .bloc-traduit{ margin-block-start:8px; }
.entete-bloc{ display:flex; align-items:center; gap:8px; font-size:.78rem;
              color:var(--texte-faible); margin-block-end:6px; }

/* Le texte traduit porte la taille d'une LECTURE, pas d'une etiquette : c'est lui
   qu'on vient relire. L'original passe dessous, en retrait. */
.texte-traduit{ font-size:1rem; line-height:1.55; color:var(--texte);
                white-space:pre-wrap; overflow-wrap:anywhere; }
.texte-origine{ margin-block-start:6px; padding-block-start:6px;
                border-block-start:1px dashed var(--bordure); font-size:.82rem;
                color:var(--texte-tenu); white-space:pre-wrap; overflow-wrap:anywhere; }

/* ======================================================= LIRE DANS UNE AUTRE LANGUE */
.barre-lecture{ display:flex; align-items:center; gap:8px; margin-block-end:14px; }
.bandeau-lecture{ display:flex; align-items:flex-start; gap:11px; padding:12px 15px;
                  margin-block-end:16px; border-inline-start:3px solid var(--accent);
                  border-radius:0 var(--rayon-petit) var(--rayon-petit) 0;
                  background:var(--surface-2); }
.bandeau-lecture svg{ inline-size:18px; block-size:18px; color:var(--accent); flex:none; }
.bandeau-lecture .note{ margin-block-start:3px; }

/* Une tete de carte qui se replie. Toute la barre est cliquable : viser un chevron de
   huit pixels a la souris est une exigence inutile. */
.tete-carte.pliable{ cursor:pointer; }
.tete-carte.pliable:hover{ background:var(--surface-2); }
.tete-carte.pliable .pousse{ display:flex; align-items:center; gap:10px; }
.tete-carte.pliable.ouvert .chevron{ transform:rotate(45deg); }
[dir="rtl"] .tete-carte.pliable.ouvert .chevron{ transform:rotate(45deg); }
