/* Elevora CRM — css/commun.css  [V24] 09/10/2026
   La feuille COMMUNE aux trois espaces : Admin (index.html), Partenaire (index.html avec un compte agent
   ou apporteur) et Client (client.html). Chargée par index.html ET client.html, après leurs autres styles :
   à égalité de spécificité, c'est elle qui l'emporte. Document de Célian du 05/10/2026 (document 2),
   étape 2 : §45 lisibilité, §11 barre latérale, §25 badges et tableaux, §19 alignement, §7 espacement.

   Règle : une valeur qui sert à plusieurs écrans vit ICI, en variable, jamais en dur dans une page.
   Ce fichier ne contient aucune couleur de marque : seulement des variables de lecture et de mise en page. */

/* ═══ §45 — LISIBILITÉ GÉNÉRALE ═══════════════════════════════════════════════════════════════
   1. Taille minimale du texte : --fs-min. Toutes les feuilles de style du CRM et tous les styles posés
      en ligne par le JavaScript d'interface l'utilisent à la place d'une taille en dur sous 12,5 px
      (les documents envoyés — devis, contrat, rapport, e-mails — gardent leurs propres tailles : ce
      ne sont pas des écrans). Pour ajuster : une seule valeur, ici.
   2. Contraste du texte secondaire : --text2 (libellés, descriptions) et --text3 (aides, repères),
      déclarés dans :root / body.light de css/elevora.css (Admin, Partenaire) ET dans le <style> de
      client.html (Client), aux MÊMES valeurs — tests/v24-lisibilite.py vérifie qu'ils ne divergent pas.
      Ratios WCAG 2.2 mesurés par calcul de luminance relative, sur les quatre fonds (--bg, --bg2,
      --bg3, --bg4) ET sur les cases teintées (--glow, --blue-bg, --amber-bg, --green-bg, --red-bg,
      --rose-bg posées sur --bg2 / --bg3) :
        sombre : --text2 #B4B2CA 6,1:1 au pire (7,0 sur --bg2) · avant #A6A4BE 5,2:1
                 --text3 #AAA8C2 5,5:1 au pire (6,6 sur --bg2) · avant #9896B4 4,4:1 (sous 4,5 !)
        clair  : --text2 #3F3F58 7,4:1 au pire (10,2 sur --bg2) · avant #474760 6,5:1
                 --text3 #51516A 5,6:1 au pire (7,7 sur --bg2) · avant #626279 4,3:1 (sous 4,5 !)
      tests/v24-lisibilite.py refait ce calcul à chaque lancement.
   3. Hiérarchie : titre de page et de carte > valeur (chiffre) > texte courant --text > libellé --text2
      en graisse 500-600 > aide --text3. Les en-têtes de tableau prennent --text2 et la graisse 600. */
:root{
  --fs-min:12.5px;            /* plancher de TOUT texte lisible (aides, libellés, pastilles, en-têtes) */
  --fs-corps:14px;            /* texte courant */
  --fw-libelle:600;           /* libellés, en-têtes de colonnes, repères */
  --espace-bloc:20px;         /* §7 : l'espace entre deux grands blocs d'une page (chiffres, filtres, liste) */
}
@media (max-width:560px){:root{--espace-bloc:16px}}

/* ═══ §11 — BARRE LATÉRALE (Admin, Partenaire et Client) ══════════════════════════════════════════
   Largeur, taille et graisse des libellés : une seule source. La barre passe de 248 à 268 px (+20 px : les
   libellés grossissent de 13,5 à 14,5 px et ne doivent être ni serrés ni coupés) ; l'espace Client passe de
   240 à 268 px pour rester aligné. Les couleurs de catégories (--cat-*) sont dans css/navigation.css. */
:root{
  --sb-w:268px;               /* barre ouverte */
  --sb-w-reduite:68px;        /* barre réduite en icônes (Admin et Partenaire) */
  --sb-fs:14.5px;             /* libellé d'une page (avant 13,5 px) */
  --sb-fw:500;                /* graisse d'un libellé (avant 400) */
  --sb-fw-actif:700;          /* la page ouverte (avant 600, qui n'est pas chargée : Satoshi 400 / 500 / 700) */
  --sb-cat-fs:var(--fs-min);  /* titre de catégorie (avant 10 px) */
  --sb-cat-fw:700;
  --sidebar:var(--sb-w);      /* client.html */
}
/* L'espace Client : mêmes libellés que la barre de l'admin. */
.nav-item{font-size:var(--sb-fs);font-weight:var(--sb-fw)}
.nav-item.active{font-weight:var(--sb-fw-actif)}
thead th{font-weight:var(--fw-libelle);color:var(--text2)}

/* ═══ §25 — BADGES, PASTILLES ET TABLEAUX : JAMAIS DE TEXTE COUPÉ EN DEUX ═════════════════════════════
   Les pastilles du CRM s'écrivent de cent façons (classes .badge, .tag, .doc-badge, .pa-badge, .cb-badge,
   .vd-pill, .rel-pastille… et des <span style="border-radius:…"> posés dans le JS). Une seule règle les
   tient toutes sur UNE ligne : le fond reste une forme pleine, le mot ne se coupe jamais. Les conteneurs
   de pastilles (noms au pluriel : .badges, .chips, .pastilles, .tags) gardent, eux, le droit de passer à la
   ligne entre deux pastilles. Les montants, eux, sont corrigés à la source : js/00m-montants.js (espace
   insécable entre milliers et avant « € »). */
:is(.badge,.tag,.elv-badge,[class*="badge"],[class*="-pill"],[class*="pill-"],[class*="-chip"],[class*="pastille"],[class*="-tag"],[class*="-puce"]):not([class*="badges"],[class*="pills"],[class*="chips"],[class*="pastilles"],[class*="-tags"],[class*="-puces"]){white-space:nowrap}
.badge,.tag{display:inline-flex;align-items:center;max-width:100%}
/* Pastilles écrites en ligne dans un tableau (fond + coins arrondis posés dans l'attribut style). */
table span[style*="border-radius"],table a[style*="border-radius"],table b[style*="border-radius"],table div[style*="inline-flex"][style*="border-radius"],table div[style*="inline-block"][style*="border-radius"]{white-space:nowrap}
/* Une cellule de montant (police mono) ne se coupe pas, ni le texte secondaire qu'elle porte (« 1 projet passé »). */
td[style*="font-family:var(--mono)"],td.num{white-space:nowrap}

/* Quand la place manque, dans cet ordre (§25.3) : 1. marges réduites ; 2. colonnes secondaires masquées sous un
   seuil de LARGEUR DU CONTENEUR (pas de l'écran : la barre latérale compte) ; 3. défilement horizontal, avec la
   première colonne (le nom) figée. Jamais d'écrasement qui casse les pastilles : le tableau garde la largeur de
   son contenu, et c'est son cadre qui défile. */
:is(.adm-table-wrap,.tk-table-cadre,.tc,.dx-table,#cl-table){container-type:inline-size;overflow-x:auto;max-width:100%}
@container (max-width:1100px){
  :is(.adm-table-wrap,.tk-table-cadre,.tc,.dx-table,#cl-table) :is(th,td){padding-left:10px;padding-right:10px}
}
/* Colonne du nom figée : première colonne, ou deuxième quand la première est une case ou un repli. Pas dans la
   présentation « cartes » du téléphone (table.tab-cartes, css/mobile.css) : il n'y a plus de colonnes. */
:is(.adm-table-wrap,.tk-table-cadre,.tc) > table:not(.tab-cartes) :is(th,td):first-child,
#cl-table table:not(.tab-cartes) :is(th,td):nth-child(2),
.dx-table table:not(.tab-cartes) :is(th,td):nth-child(2){position:sticky;left:0;z-index:1}
:is(.adm-table-wrap,.tk-table-cadre,.tc) > table:not(.tab-cartes) tbody :is(th,td):first-child,
#cl-table table:not(.tab-cartes) tbody td:nth-child(2),.dx-table table:not(.tab-cartes) tbody td:nth-child(2){background:var(--bg2);box-shadow:1px 0 0 var(--border)}
:is(.adm-table-wrap,.tk-table-cadre,.tc) > table:not(.tab-cartes) tbody tr:hover > :first-child,
#cl-table table:not(.tab-cartes) tbody tr:hover > td:nth-child(2),.dx-table table:not(.tab-cartes) tbody tr:hover > td:nth-child(2){background:var(--bg3)}
/* Colonnes secondaires masquées sous un seuil (elles restent dans la fiche) : clients, prospects, pipeline en liste. */
@container (max-width:1000px){
  #cl-table table:not(.tab-cartes) :is(th,td):nth-child(9){display:none}                       /* Clients : Source */
  .pl-table:not(.tab-cartes) :is(th,td):nth-child(4){display:none}                             /* Pipeline, liste : Source */
}
@container (max-width:860px){
  #cl-table table:not(.tab-cartes) :is(th,td):is(:nth-child(8),:nth-child(6)){display:none}    /* Clients : Risque, Avancement */
  .pl-table:not(.tab-cartes) :is(th,td):nth-child(6){display:none}                             /* Pipeline, liste : Dernier mouvement */
  .ea-table:not(.tab-cartes) :is(th,td):nth-child(5){display:none}                             /* Prospects : Déclaré le */
}

/* ═══ §19 — ALIGNEMENT : un texte se lit en partant de la gauche ═══════════════════════════════════════
   Une cellule d'en-tête de LIGNE (<th scope="row">) est centrée par le navigateur : c'est ce qui centrait la
   colonne « Nom » de Textes et messages. Les colonnes de chiffres ou de statuts courts gardent leur
   alignement propre (classes .agt-n, .num…) ; seul le texte (noms, titres, descriptions) revient à gauche. */
tbody th,tfoot th{text-align:start}
/* Le nom d'une ligne et sa description : le nom d'abord, la description dessous, à gauche (Textes et messages). */
.tc th[scope="row"] > .pr-leger{display:block;font-weight:400;margin-top:2px}

/* ═══ §7 — ESPACEMENT : les blocs d'une page respirent ═════════════════════════════════════════════════
   Bandeau de chiffres, barre de filtres, liste : --espace-bloc (20 px, 16 px sur téléphone) entre chacun,
   sur toutes les pages au même schéma (Pipeline : Prospection, Clients, Recrutement ; Agents ; Comptabilité…). */
#recrutement-zone .pr-bd{margin-bottom:var(--espace-bloc)}   /* Recrutement : les cartes touchaient la barre de filtres (0 px) */
/* Les autres pages au même schéma posent déjà l'espace avec cette même variable : Pipeline Prospection et Clients
   (css/pipeline.css), Agents (css/agents.css : .agt-page). Le contrôle de tests/v24-lisibilite.py mesure chacune. */
:is(.pl-outils,.cand-outils){margin-bottom:var(--espace-bloc)}

/* ═══ §47 / §50 — LISTES LONGUES : GROUPES REPLIABLES (js/00t-repliable.js) ═══════════════════════════
   Une flèche à côté du titre ferme et ouvre un groupe ; fermé, le titre et le compteur restent. L'état est
   retenu par personne (préférences du compte). Un seul composant pour les groupes de Tâches, les
   Transcriptions et toute liste qui s'allonge : on n'écrit pas de repli à la main.
   Le mouvement est une hauteur qui se déroule (0,22 s) ; sous « réduire les animations » du système, tout
   est instantané. Fermé, le corps est retiré de la tabulation et de la lecture d'écran (inert + visibility). */
:root{--repl-duree:.22s}
.elv-repl-t{margin:0;font:inherit}
.elv-repl-bascule{display:inline-flex;align-items:center;gap:8px;min-height:36px;padding:4px 10px 4px 6px;border:0;border-radius:var(--rs);background:transparent;color:var(--text);font:600 var(--fs-corps) var(--font);text-align:start;cursor:pointer}
.elv-repl-bascule:hover{background:var(--bg3)}
.elv-repl-bascule:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.elv-repl-fl{display:inline-flex;flex-shrink:0;color:var(--text2);transition:transform var(--repl-duree) ease}
.elv-repl-bascule[aria-expanded="true"] .elv-repl-fl{transform:rotate(90deg)}
.elv-repl-titre{min-width:0;overflow-wrap:anywhere}
.elv-repl-n{flex-shrink:0;padding:1px 8px;border-radius:20px;background:var(--bg4);color:var(--text2);font:600 var(--fs-min) var(--mono)}
/* Un groupe de blocs : le corps se déroule. */
.elv-repl-corps{display:grid;grid-template-rows:1fr;transition:grid-template-rows var(--repl-duree) ease,visibility 0s}
.elv-repl-corps-i{min-height:0;overflow:hidden;margin:-4px;padding:4px}
.elv-repl[data-repl-ouvert="0"] > .elv-repl-corps{grid-template-rows:0fr;visibility:hidden;transition:grid-template-rows var(--repl-duree) ease,visibility 0s var(--repl-duree)}
/* Un groupe de tableau (le <tbody>) : les lignes se retirent, l'en-tête reste ; à l'ouverture elles apparaissent en fondu. */
.elv-repl[data-repl-ouvert="0"] > tr:not(.elv-repl-tete){display:none}
.elv-repl--anime[data-repl-ouvert="1"] > tr:not(.elv-repl-tete){animation:elv-repl-entree var(--repl-duree) ease}
@keyframes elv-repl-entree{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
tr.elv-repl-tete th{text-align:start;font-weight:600}
/* Un bouton masqué par l'attribut hidden le reste (.btn pose display:inline-flex, qui l'emportait). */
.btn[hidden]{display:none !important}
/* « Tout réduire / Tout ouvrir » : à droite, au-dessus de la liste. */
.elv-repl-barre{display:flex;justify-content:flex-end;margin:0 0 var(--s2)}
.elv-repl-tout{display:inline-flex;flex-wrap:wrap;gap:var(--s2)}
@media (prefers-reduced-motion:reduce){
  .elv-repl-fl,.elv-repl-corps,.elv-repl[data-repl-ouvert="0"] > .elv-repl-corps{transition:none}
  .elv-repl--anime[data-repl-ouvert="1"] > tr:not(.elv-repl-tete){animation:none}
}

/* ═══ §41 — RÉGLAGE DES ANIMATIONS (étape 11b, 13/10/2026) ═══════════════════════════════════════════════════
   Le panneau construit par js/00z-animations.js (ElvAnimations.rendre) : Paramètres → Affichage, Mon profil (Admin et Partenaire) et
   Informations (Client). Un interrupteur général, le style, une ligne par animation déclarée au registre, l'interface. Texte courant 14 px,
   aides en --text2 (4,5:1 mesuré), jamais sous --fs-min. */
.an-panneau{display:flex;flex-direction:column;gap:14px;max-width:720px}
.an-t{margin:0;font-size:16px;font-weight:700;color:var(--text)}
.an-sous-t{margin:0;font-size:14px;font-weight:700;color:var(--text)}
.an-note{margin:0;font-size:13px;line-height:1.5;color:var(--text2)}
.an-sys{padding:9px 12px;border:1px solid var(--border2);border-radius:var(--r,10px);background:var(--bg3)}
.an-bloc,.an-groupe{display:flex;flex-direction:column;gap:8px}
.an-groupe{padding-top:12px;border-top:1px solid var(--border)}
.an-ligne{display:flex;align-items:flex-start;gap:12px;padding:6px 0;cursor:pointer}
.an-case,.an-radio input{flex:0 0 auto;width:18px;height:18px;margin:2px 0 0;accent-color:var(--accent-fill,var(--accent))}
.an-texte{display:flex;flex-direction:column;gap:2px;min-width:0}
.an-titre{font-size:14px;font-weight:600;color:var(--text)}
.an-aide{font-size:var(--fs-min,12.5px);line-height:1.45;color:var(--text2)}
.an-style{margin:0;padding:0 0 0 30px;border:0;display:flex;flex-direction:column;gap:6px}
.an-style[disabled]{opacity:.6}
.an-legende{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.an-radio{display:flex;align-items:flex-start;gap:10px;font-size:13px;line-height:1.45;color:var(--text2);cursor:pointer}
.an-radio b{color:var(--text);font-weight:600}
.an-liste{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.an-item{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;border-bottom:1px solid var(--border)}
.an-item:last-child{border-bottom:0}
.an-item .an-ligne{flex:1 1 260px}
.an-apercu{flex:0 0 auto}
.an-etat{margin:0;min-height:1.4em;font-size:13px;color:var(--text2)}
.an-etat-ko{color:var(--red)}

/* [Lot conformité, point 12] 15/10/2026 — bloc « Opposition et information » d'une fiche (js/00l3-opposition.js) et pastille des listes. */
.opp-bloc{margin-top:18px;padding-top:14px;border-top:1px solid var(--border)}
.opp-bloc>legend{font-size:var(--fs-min, 12.5px);font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--text2);margin-bottom:6px}
.opp-bloc .opp-aide{margin:0 0 4px}
.opp-etat{font-size:var(--fs-min, 12.5px);line-height:1.5;color:var(--red);margin:4px 0 0 25px}
.opp-etat:empty{display:none}
.opp-bloc .opp-motif{margin:6px 0 0 25px}
.opp-info{margin-top:14px;font-size:var(--fs-min, 12.5px);line-height:1.55;color:var(--text2)}
.opp-info .btn{margin-left:6px}
.opp-pastille{display:inline-flex;align-items:center;padding:1px 8px;border-radius:999px;background:var(--red-bg);color:var(--red);font-size:var(--fs-min, 12.5px);font-weight:600;white-space:nowrap}
