/* Feuille de style des COMMUNAUTÉS — écran de profil (§6) et écran de gestion (§7).
   Cf. docs/SPEC-communautes.md, docs/communities.md, docs/design-rules.md (règles 1 et 3),
   docs/ui-shell.md (registre des z-index), et webapp/auth.css, dont ce fichier est le
   décalque de discipline.

   TROIS CONTRAINTES GOUVERNENT CE FICHIER. Les trois sont gardées par un test.

   1. PÉRIMÈTRE — la contrainte dure, et c'est la leçon d'auth.css puis d'events.css. Ce
      fichier est chargé INCONDITIONNELLEMENT par index.html (lien bloquant dans le
      <head>), dans les DEUX modes, alors que community.js sort avant de créer le moindre
      nœud quand `/auth/state` rend `mode: "off"`. Sur l'app de bureau cette feuille doit
      donc rester SANS EFFET — pas un pixel ne bouge. Conséquence : le PREMIER compound de
      CHAQUE sélecteur — y compris à l'intérieur d'un @media — descend d'un `#cm-*` ou
      d'une classe `.cm-*` que seul community.js crée. Aucune exception : contrairement à
      auth.css et son `body.auth-locked`, ce chantier ne pose aucune classe sur un élément
      qu'il ne crée pas (cf. le verrou de défilement, plus bas).
      Le piège que le détecteur cherche, avec sa contre-épreuve dans le test, est la règle
      qui COMMENCE par un sélecteur légitime et glisse un élément partagé dans la même
      liste : `.cm-members, select{…}` cadrerait `select` sur TOUTE la page. Le second est
      un sélecteur global tapi dans un `@media`, que le détecteur balaie aussi.

   2. TOKENS SEULEMENT (règle de conception 3). Aucune couleur littérale — ni #rgb, ni
      #rrggbb, ni AUCUNE des trois notations fonctionnelles : les cinq thèmes commutent à
      chaud et une valeur en dur devient illisible dans quatre d'entre eux. Les ombres
      passent par `var(--shadow)`, les fonds d'overlay par `var(--overlay)`, les états par
      les triplets `--ok/--ok-bg/--ok-line`, `--bad/…`, `--warn/…`, l'anneau de focus par
      `--focus`.
      PIÈGE MESURÉ EN ÉCRIVANT CE FICHIER : le détecteur balaie le fichier BRUT,
      commentaires compris. Nommer ici une notation fonctionnelle pour l'interdire suffit
      donc à faire échouer le test — d'où la périphrase ci-dessus, qui est la même que
      celle d'events.css, et pour la même raison.

   3. LES NOMS SONT CEUX QUE LE JS POSE — et c'est une RÉÉCRITURE, pas un choix de départ.
      La première version de cette feuille a été écrite AVANT community.js, par un autre
      agent, contre une idée du DOM que le JS n'a pas suivie : elle supposait UN modal à
      deux vues (`.cm-view`, `.cm-back`) et posait la géométrie du calque sur `#cm-modal`,
      un identifiant que RIEN ne crée — community.js construit DEUX modaux, `#cm-profile`
      et `#cm-manage`, tous deux de CLASSE `.cm-modal`. Mesuré au navigateur : la seule
      règle qui atteignait le nœud était `[hidden]{display:none}`, donc l'écran s'ouvrait
      DANS LE FLUX du document, 2 295 px sous la ligne de flottaison, sans fond ni
      empilement, pendant que `inert` rendait le reste de la page inutilisable. Le
      croisement final relevait 22 règles sans cible et 29 classes sans règle, la feuille
      passant pourtant TOUS les autres gardes (aucune couleur littérale, aucun sélecteur
      hors périmètre, 100 % préfixé). C'est exactement ce qu'aucun test hérité ne voyait.
      L'inventaire ci-dessous est donc un CONTRAT croisé DANS LES DEUX SENS par
      `tests/test_communities_visibility.py` (règle sans cible / classe sans règle), et
      c'est le seul garde capable de voir une feuille écrite en parallèle du JS.

   ------------------------------------------------------------------------------------
   CONTRAT CSS — les 50 noms que community.js pose, tous stylés, et rien d'autre
   ------------------------------------------------------------------------------------
   Coquille, partagée par les DEUX modaux :
     #cm-profile #cm-manage .cm-modal .cm-box .cm-head .cm-title .cm-x .cm-msg .cm-body
     .cm-sec .cm-sec-h .cm-lead .cm-note .cm-status .cm-empty .cm-btn
   Profil (§6) :
     .cm-acct .cm-acct-nm .cm-grid .cm-k .cm-v
     .cm-right .cm-pending .cm-newrow .cm-new-name
     .cm-badges .cm-badge(.cm-b-mgr .cm-b-mem .cm-ask-on) .cm-badge-nm .cm-badge-x .cm-ask
   Gestion d'une communauté (§7) :
     .cm-members .cm-mrow(.cm-is-me .cm-is-mgr .cm-ask-on) .cm-mname .cm-mrole .cm-mdate
     .cm-macts
     .cm-invites .cm-irow .cm-iname .cm-ikind .cm-idate
     .cm-invite .cm-invrow .cm-inv-name
     .cm-danger
   Modificateurs NON préfixés, jamais seuls, toujours combinés (convention d'auth.css) :
     .cm-btn.prim .cm-btn.ghost .cm-btn.bad · .cm-msg.on .cm-msg.bad · .cm-mrole.on

   DEUX MODAUX, PAS UN — et c'est le JS qui a tranché, contre la première version de cette
   feuille. `openManage` FERME le profil et le rouvre à la fermeture : les deux calques ne
   sont donc jamais empilés, et la valeur de z-index unique suffit. `.cm-ask-on` est le
   nom commun de la bascule de confirmation EN LIGNE (règle 1) : il s'applique aussi bien
   à un badge du profil qu'à une ligne de membre ou au bloc « ne plus gérer », parce que
   c'est le même geste et qu'il doit avoir la même grammaire visuelle partout.

   Z-INDEX (registre tenu par docs/ui-shell.md — menu de thème 4000, menu utilisateur 4050,
   confirm/prompt 4100, zone admin ET écran « Messages » 4200, écran-porte 4300) : ce
   fichier ne déclare QUE 4200, la valeur de la zone admin et de l'écran Messages, dont cet
   écran est le voisin exact — même origine (le menu utilisateur, 4050, qu'il doit couvrir),
   même absence de geste destructeur à faire confirmer par un dialogue (les confirmations
   sont EN LIGNE, règle 1 : d'où l'absence de conflit avec confirm/prompt à 4100). Aucune
   valeur nouvelle n'est inventée, et rien ne passe devant l'écran-porte.

   PAS DE VERROU DE DÉFILEMENT. `body.auth-locked` appartient à auth.css et n'est posé que
   par les écrans-portes ; la zone admin, elle, ne verrouille pas le fond. Cet écran fait
   comme elle — et surtout, une règle `body{…}` ici tomberait sur l'app de bureau, où
   community.js n'existe pas.

   PAS D'ANIMATION PAR @keyframes. Le détecteur de périmètre sait ignorer un bloc
   `@keyframes` correctement cadré depuis la v0.6.161, donc rien ne l'interdit — mais aucun
   état de cet écran ne demande à pulser, et un témoin de chargement se fait en TEXTE
   (`.cm-status`), pas en rotation.

   CE FICHIER NE STYLE PAS : le panneau Messages ni ses boutons Rejoindre/Refuser (auth.css,
   `.auth-m*` — les invitations actionnables ont fini par vivre ENTIÈREMENT dans auth.js,
   d'où la disparition de `.cm-inv-acts`/`.cm-inv-done` de cette feuille), l'onglet
   « Demandes » de la zone admin (auth.css), ni le sélecteur de visibilité et le badge
   « communauté » du volet Événements (events.css, préfixe `.ev-`). Y ajouter une règle la
   rendrait orpheline, et le test la refuserait. */

/* ============================== coquille commune ============================== */
/* LE CALQUE, sur la CLASSE et non sur un identifiant : les deux écrans sont deux nœuds
   distincts (`#cm-profile`, `#cm-manage`) qui partagent cette classe. Écrire la géométrie
   sur un id — ce que faisait la première version — la réservait à un nœud qui n'existe
   pas. Même forme que `.auth-modal` : les trois écrans ouverts depuis le menu du compte
   (comptes, messages, profil) doivent se ressembler. Ce sont bien deux feuilles distinctes
   et non un partage de classes : chacune ne peut styler que ce que SON module crée, sans
   quoi le mode local ne serait plus mesurable fichier par fichier. */
.cm-modal{
  position:fixed;inset:0;z-index:4200;
  display:flex;align-items:center;justify-content:center;padding:24px;
  background:var(--overlay);
}
.cm-modal[hidden]{display:none}

.cm-box{
  width:100%;max-width:560px;max-height:82vh;display:flex;flex-direction:column;
  background:var(--panel);border:1px solid var(--line);border-radius:10px;
  box-shadow:0 18px 48px var(--shadow);
  color:var(--txt);font:13px/1.5 system-ui,Segoe UI,Roboto,sans-serif;
}
/* L'écran de gestion porte une LISTE (noms, rôles, dates, actions sur la même ligne) là où
   le profil n'aligne que des couples clé/valeur : il lui faut un peu plus de largeur avant
   que les lignes de membre ne se replient. C'est la seule différence entre les deux. */
#cm-profile .cm-box{max-width:560px}
#cm-manage .cm-box{max-width:640px}
/* Entre les deux : ses lignes portent un nom de groupe ET un lien vers la carte,
   donc plus large que le profil ; mais elle n'a pas de tableau de membres, donc
   plus étroite que la gestion. */
#cm-communities .cm-box{max-width:600px}

.cm-head{
  display:flex;align-items:center;gap:10px;
  padding:12px 14px;border-bottom:1px solid var(--line);
}
.cm-title{margin:0;font-size:15px;font-weight:700;flex:1;min-width:0;overflow-wrap:anywhere}
.cm-x{
  background:transparent;border:0;color:var(--mut);font-size:20px;line-height:1;
  cursor:pointer;padding:0 4px;
}
.cm-x:hover{color:var(--txt)}
.cm-x:focus-visible{outline:none;box-shadow:0 0 0 2px var(--focus);border-radius:6px}

/* Retour du serveur. Le TEXTE vient toujours d'une clé i18n traduite à partir du code
   machine rendu par `_bad(code, message, champ)` — jamais du français renvoyé par la
   route. Le bandeau vit ENTRE l'en-tête et le corps, donc hors du nœud que `renderProfile`
   reconstruit : il survit au re-rendu, et c'est voulu. `paintMsg` pose `.on` quand il y a
   quelque chose à dire et `.bad` quand c'est un refus ; sans `.on` la règle ne peint rien,
   ce qui évite un cadre vide au milieu de l'écran. */
.cm-msg{display:none}
.cm-msg.on{
  display:block;margin:10px 14px 0;padding:8px 10px;font-size:12.5px;
  color:var(--ok);background:var(--ok-bg);border:1px solid var(--ok-line);border-radius:6px;
}
/* Un REFUS dans un cadre `--ok` se lirait comme une réussite : `.bad` bascule les trois
   couleurs d'un coup (même mécanique que `.auth-msg.bad`). */
.cm-msg.on.bad{color:var(--bad);background:var(--bad-bg);border-color:var(--bad-line)}

.cm-body{padding:12px 14px 16px;overflow:auto}

/* Une SECTION du corps (compte, droit de gestion, badges, membres, invitations…). Les deux
   sections de badges N'APPARAISSENT QUE SI ELLES ONT DU CONTENU (§6) : un joueur ordinaire
   doit voir un profil court, comme il ne voit pas l'entrée « Gérer les comptes ». */
.cm-sec{margin:14px 0 0}
.cm-sec:first-child{margin-top:0}
/* L'intertitre de section, seul nœud de titre du corps. */
.cm-sec-h{
  margin:0 0 6px;font-size:11px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--mut);
}
/* Le chapeau d'une section — la phrase qui explique à quoi sert le droit de gestion avant
   qu'on ne le demande. */
.cm-lead{margin:0 0 8px;font-size:12.5px;color:var(--txt2);line-height:1.45}
/* Rappel en petits caractères — « une demande refusée peut être reposée » (§6). Ce n'est
   pas un avertissement d'échec : teinte sourde, pas `--warn`, qui est réservé à la bascule
   de confirmation. */
.cm-note{margin:0 0 8px;font-size:11.5px;color:var(--mut);line-height:1.45}

/* Ligne d'état : elle sert de témoin de chargement (« … ») — cf. l'absence d'animation, en
   tête de fichier. Hauteur minimale non nulle pour ne pas faire sauter la mise en page
   quand elle se remplit. */
.cm-status{color:var(--acc);font-size:12px;min-height:15px;padding:6px 0}

/* Règle 6 : jamais d'interface vide sans un mot. Ce bloc dit POURQUOI la liste est vide
   (aucun membre à afficher). */
.cm-empty{padding:16px 4px;color:var(--mut);text-align:center;font-size:12.5px}

.cm-btn{
  font:inherit;font-size:12.5px;padding:6px 12px;border-radius:6px;cursor:pointer;
  background:var(--input);color:var(--txt);border:1px solid var(--line);
}
.cm-btn:hover{border-color:var(--acc)}
.cm-btn:focus-visible{outline:none;box-shadow:0 0 0 2px var(--focus)}
.cm-btn:disabled{opacity:.6;cursor:default}
.cm-btn:disabled:hover{border-color:var(--line)}
.cm-btn.prim{background:var(--acc);color:var(--on-acc);border-color:var(--acc);font-weight:600}
.cm-btn.ghost{background:transparent;color:var(--txt2)}
.cm-btn.ghost:hover{color:var(--txt)}
.cm-btn.bad{background:var(--bad-bg);color:var(--bad);border-color:var(--bad-line)}

/* ================================== 1. le compte ================================== */
/* Nom, date de création, dernière connexion. Les deux dates forment deux couples clé/valeur
   en grille pour que les valeurs s'alignent. `auto 1fr` plutôt que deux colonnes égales —
   les clés sont courtes dans les onze langues, les valeurs ne le sont pas (un horodatage
   localisé en japonais et en allemand n'a pas la même longueur). */
.cm-acct{
  background:var(--panel2);border:1px solid var(--line);border-radius:8px;
  padding:10px 12px;
}
.cm-acct-nm{display:block;font-size:14px;margin-bottom:6px;overflow-wrap:anywhere}
.cm-grid{display:grid;grid-template-columns:auto 1fr;gap:2px 10px;align-items:baseline}
.cm-k{color:var(--mut);font-size:11.5px;white-space:nowrap}
.cm-v{color:var(--txt);min-width:0;overflow-wrap:anywhere}

/* ============================= 2. le droit de gestion ============================= */
/* Trois états mutuellement exclusifs (§6) : absent → un bouton « Demander le rôle » ;
   demandé → « Demande en attente », NON cliquable ; accordé → « Créer une communauté ».
   Le bloc garde la même boîte dans les trois cas pour que l'écran ne se réorganise pas
   sous l'utilisateur au moment où il clique. */
.cm-right{
  background:var(--panel2);border:1px solid var(--line);border-radius:8px;
  padding:10px 12px;
}
/* DEMANDE EN ATTENTE. Ce n'est ni une réussite ni un échec : c'est un délai, donc `--warn`,
   la même teinte que la bascule de confirmation en ligne. Le rendu doit dire « ne cliquez
   pas, c'est déjà fait » sans qu'on ait à l'essayer — d'où la pastille inerte plutôt qu'un
   bouton désactivé, qui invite à cliquer avant de refuser. */
.cm-pending{
  display:inline-flex;align-items:center;gap:6px;
  padding:3px 10px;border-radius:999px;font-size:12px;font-weight:600;
  color:var(--warn);background:var(--warn-bg);border:1px solid var(--warn-line);
  cursor:default;
}
/* Création d'une communauté : le champ et ses deux boutons, EN LIGNE (règle 1 — pas de
   prompt() natif). */
.cm-newrow{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.cm-new-name{
  flex:1 1 180px;padding:6px 10px;font:inherit;font-size:12.5px;min-width:0;
  background:var(--input);color:var(--txt);
  border:1px solid var(--line);border-radius:6px;
}
.cm-new-name:focus{outline:none;border-color:var(--acc);box-shadow:0 0 0 3px var(--focus)}

/* ======================= 3 et 4. les badges de communauté ======================= */
/* DEUX ALLURES DISTINCTES, et c'est le seul endroit de l'écran où la différence doit se
   lire d'un coup d'œil : les deux listes sont DISJOINTES (D3 — gérer implique appartenir,
   donc une communauté gérée n'est jamais répétée dans « dont je suis membre »), et rien
   d'autre que le badge ne dit laquelle est laquelle une fois la section défilée hors vue.
     · « je gère »        → cerné et écrit en `--acc` ; son nom ouvre l'écran de gestion.
     · « je suis membre » → cerné `--line`, écrit en `--txt2` ; son nom ouvre le carnet
                            (Q4 : un membre simple voit les noms de son groupe).
   Aucune des deux ne peint son fond en `--acc` : un badge plein volerait la vedette au
   bouton primaire de la section « droit de gestion », qui est la seule vraie action de
   l'écran pour un compte qui n'a encore rien. */
.cm-badges{display:flex;flex-wrap:wrap;gap:7px;margin-top:2px}
/* AUCUNE `transition` DE COULEUR ICI, et c'est une correction, pas un oubli. La première
   version portait une transition sur la teinte de fond et de bordure pour adoucir la
   bascule de confirmation. MESURÉ dans un navigateur, les cinq thèmes commutés à chaud :
   avec cette transition, le fond et la bordure du badge restent FIGÉS sur les valeurs du
   thème « nuit » dans les cinq thèmes — la variable, elle, est bien réévaluée (`--panel2`
   vaut la bonne valeur sur l'élément), mais la couleur calculée n'arrive jamais à
   destination et reste celle d'avant, indéfiniment. Neutraliser la seule transition
   suffit : le badge suit alors exactement les cinq thèmes.
   C'est la règle 3 prise à revers — pas une couleur en dur, mais une couleur de token qui
   cesse de suivre le thème. Une transition ne doit donc jamais porter sur une propriété
   dont la valeur vient d'un `var(--…)` thématique ; events.css n'anime que la position,
   et c'est pour cela qu'il n'a jamais rencontré ce défaut. */
.cm-badge{
  display:inline-flex;align-items:center;gap:6px;max-width:100%;
  padding:3px 4px 3px 10px;border-radius:999px;
  background:var(--panel2);border:1px solid var(--line);
}
.cm-badge.cm-b-mgr{border-color:var(--acc)}
.cm-badge.cm-b-mgr .cm-badge-nm{color:var(--acc)}
.cm-badge.cm-b-mem .cm-badge-nm{color:var(--txt2)}
.cm-badge-nm{
  background:transparent;border:0;padding:0;font:inherit;font-size:12.5px;font-weight:600;
  cursor:pointer;color:var(--txt);
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:220px;
}
.cm-badge-nm:hover{text-decoration:underline}
.cm-badge-nm:focus-visible{outline:none;box-shadow:0 0 0 2px var(--focus);border-radius:4px}
/* Le geste « quitter », sur le badge lui-même : un petit bouton en bout de pastille plutôt
   qu'un menu. Il n'ouvre PAS le départ, il ARME la confirmation en ligne ci-dessous — le
   clic principal du badge reste constructif (il ouvre la communauté). */
.cm-badge-x{
  background:transparent;border:0;color:var(--mut);cursor:pointer;
  font:inherit;font-size:14px;line-height:1;padding:0 6px;border-radius:999px;
}
.cm-badge-x:hover{color:var(--bad)}
.cm-badge-x:focus-visible{outline:none;box-shadow:0 0 0 2px var(--focus)}

/* ==================== la confirmation EN LIGNE, partout la même ==================== */
/* Règle 1 : aucun confirm() natif. L'élément BASCULE — il ne se double pas d'une fenêtre —
   sur le modèle de l'annulation d'événement et de la suppression de compte. Teinte
   `--warn` : c'est un avertissement, pas encore un échec ; `--bad` est réservé au bouton
   qui confirme, et au bandeau de refus s'il vient (D6 : dernier gestionnaire).
   Un seul nom (`.cm-ask-on`) pour les trois usages — quitter une communauté, révoquer un
   membre, ne plus gérer — parce que c'est le même geste.

   POURQUOI LES TROIS COMPOUNDS SONT ÉCRITS, plutôt qu'un `.cm-ask-on` nu : MESURÉ au
   navigateur, la bascule de révocation rendait la valeur de `--panel2` — la teinte
   ordinaire d'une ligne de membre — au lieu de `--warn-bg`. Un `.cm-ask-on`
   seul a la même spécificité que `.cm-mrow`, et `.cm-mrow` est écrite PLUS BAS dans ce
   fichier : elle gagnait par simple ordre de source. Le défaut ne se voyait pas au
   croisement des inventaires — la classe est bien émise ET bien stylée —, seulement à
   l'œil, et seulement sur une des trois bascules. */
.cm-badge.cm-ask-on,
.cm-mrow.cm-ask-on,
.cm-danger.cm-ask-on{
  background:var(--warn-bg);border-color:var(--warn-line);
  padding-right:6px;flex-wrap:wrap;
}
.cm-ask{color:var(--warn);font-size:11.5px;min-width:0;overflow-wrap:anywhere}
.cm-ask-on .cm-btn{padding:2px 9px;font-size:11.5px}

/* ========================= écran de gestion : les membres ========================= */
.cm-members{margin-top:0}
/* Une ligne = un membre. `flex-wrap` plutôt qu'un tableau, comme les lignes de journal
   d'auth.css et pour la même raison : les colonnes ont des largeurs très inégales (un nom
   de compte libre face à une date localisée) et un tableau imposerait soit un défilement
   horizontal, soit la troncature de la colonne la plus utile. */
.cm-mrow{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:7px 10px;margin-bottom:6px;
  background:var(--panel2);border:1px solid var(--line);border-radius:6px;
}
/* MA PROPRE LIGNE, discrètement marquée : dans un carnet de vingt noms, savoir où l'on est
   évite de chercher pourquoi cette ligne-là n'a pas de bouton (D10 : pas d'auto-révocation,
   le bouton n'existe pas). */
.cm-mrow.cm-is-me{border-color:var(--acc)}
/* Un GESTIONNAIRE : liseré d'accent à gauche, en plus de sa pastille de rôle. Le carnet se
   parcourt en diagonale, et c'est l'information qu'on y cherche en premier. */
.cm-mrow.cm-is-mgr{border-left:3px solid var(--acc)}
.cm-mname{font-weight:600;color:var(--txt);min-width:0;overflow-wrap:anywhere}
/* Le RÔLE, en pastille : membre (sourd), gestionnaire (accent). Deux états, deux teintes
   déjà portées par les tokens — aucune couleur nouvelle. */
.cm-mrole{
  font-size:11px;padding:1px 7px;border-radius:999px;white-space:nowrap;
  color:var(--mut);border:1px solid var(--line);
}
.cm-mrole.on{color:var(--acc);border-color:var(--acc)}
.cm-mdate{font-size:11px;color:var(--mut);white-space:nowrap;font-variant-numeric:tabular-nums}
/* Les actions sont poussées au bout de la ligne : « Proposer », « Révoquer » — et le bouton
   de révocation N'EXISTE PAS sur un autre gestionnaire ni sur soi-même (§7 : offrir un
   bouton que la route refusera est une invitation à un message d'erreur). Rien ici ne le
   masque : c'est le JS qui ne l'émet pas. */
.cm-macts{margin-left:auto;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.cm-macts .cm-btn{padding:3px 9px;font-size:12px}

/* ==================== écran de gestion : invitations en attente ==================== */
/* §7 : les invitations en attente figurent dans le même écran, GRISÉES, avec la date
   d'envoi et un bouton « Annuler l'invitation ». Sans elles, un gestionnaire réinvite
   quelqu'un qui n'a simplement pas encore répondu. Le trait discontinu dit « pas encore
   là » mieux qu'une opacité seule, qui se lirait comme un défaut d'affichage — et
   l'opacité reste modérée pour que la date demeure lisible, puisque c'est elle qui décide
   si l'on relance ou si l'on attend. */
.cm-invites .cm-sec-h{margin-bottom:6px}
.cm-irow{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:7px 10px;margin-bottom:6px;
  border:1px dashed var(--line);border-radius:6px;opacity:.78;
}
.cm-iname{font-weight:500;color:var(--txt2);min-width:0;overflow-wrap:anywhere}
/* La NATURE de la proposition — entrée ou co-gestion (D4). Une invitation à co-gérer n'est
   pas une invitation à entrer, et les deux cohabitent dans la même liste. */
.cm-ikind{
  font-size:11px;padding:1px 7px;border-radius:999px;white-space:nowrap;
  color:var(--warn);background:var(--warn-bg);border:1px solid var(--warn-line);
}
.cm-idate{font-size:11px;color:var(--mut);white-space:nowrap;font-variant-numeric:tabular-nums}
.cm-irow .cm-btn{margin-left:auto;padding:3px 9px;font-size:12px}

/* ==================== écran de gestion : inviter, ne plus gérer ==================== */
/* Inviter par NOM de compte (§7) — jamais par identifiant : un gestionnaire n'a aucune
   raison de connaître les identifiants des comptes qu'il n'a pas encore invités, et la
   route ne les accepte plus. */
.cm-invite{margin-top:14px}
.cm-invrow{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.cm-inv-name{
  flex:1 1 180px;padding:6px 10px;font:inherit;font-size:12.5px;min-width:0;
  background:var(--input);color:var(--txt);
  border:1px solid var(--line);border-radius:6px;
}
.cm-inv-name:focus{outline:none;border-color:var(--acc);box-shadow:0 0 0 3px var(--focus)}
/* « Ne plus gérer » (D4.3) : un geste sur SOI, séparé du reste par un filet, et qui
   n'apparaît que s'il reste un autre gestionnaire — sans quoi la route refuserait (D6) et
   l'écran de gestion n'est pas le bon endroit pour apprendre qu'on est seul. */
.cm-danger{
  margin-top:16px;padding-top:12px;border-top:1px solid var(--line);
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
}

/* ================================ fenêtre étroite ================================ */
/* Sous 560 px, la boîte occupe presque tout l'écran et les lignes de membre passent en
   colonne : c'est le NOM et le RÔLE qu'il faut garder lisibles, les actions peuvent
   descendre. `margin-left:auto` est neutralisé sinon les boutons se collent au bord droit
   d'une ligne devenue verticale. */
/* --- Composeur d'ANNONCE (v0.6.165) ------------------------------------------------
   Le gestionnaire écrit une fois et vise une ou plusieurs de ses communautés. La note
   qui coiffe la section n'est pas décorative : elle dit que le membre présent dans
   plusieurs groupes visés ne recevra qu'un exemplaire, ce qu'aucune case à cocher ne
   peut faire deviner. */
/* Séparateur au-dessus : c'est la seule section du profil qui ÉCRIT chez d'autres
   comptes. La détacher des badges qui la précèdent évite qu'un envoi soit déclenché dans
   la lancée d'un geste de navigation. */
.cm-cast{border-top:1px solid var(--line);padding-top:12px}
.cm-cast-note{margin:0 0 8px;font-size:11.5px;color:var(--mut);line-height:1.45}
.cm-cast-list{display:flex;flex-wrap:wrap;gap:6px 14px;margin-bottom:8px}
.cm-cast-l{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--txt);cursor:pointer}
/* Taille EXPLICITE : la feuille de recherche porte un `select, input{width:100%}` global
   qui étire toute case à cocher sur la largeur de son conteneur (mesuré en v0.6.164 sur
   l'interrupteur du fond de carte). Une case n'est pas un champ de saisie.
   Visée par sa CLASSE et non par `.cm-cast-l input` : le garde-fou « toute classe posée
   par le JS a une règle » ne compte que les classes, et une case stylée à travers son
   parent passait pour non stylée — ce qui est aussi vrai à la relecture humaine. */
.cm-cast-c{width:15px;height:15px;flex:0 0 auto;margin:0;cursor:pointer}
.cm-cast-body{
  display:block;width:100%;box-sizing:border-box;
  background:var(--input);border:1px solid var(--line);border-radius:6px;
  padding:8px 10px;font:inherit;font-size:13px;color:var(--txt);
  resize:vertical;min-height:64px;
}
.cm-cast-body:focus{outline:none;border-color:var(--acc);box-shadow:0 0 0 3px var(--focus)}
.cm-cast-act{display:flex;justify-content:flex-end;margin-top:8px}

@media (max-width:560px){
  .cm-modal{padding:10px}
  .cm-box{max-height:92vh}
  .cm-body{padding:10px 10px 14px}
  .cm-msg.on{margin:10px 10px 0}
  .cm-mrow{align-items:flex-start}
  .cm-macts{margin-left:0;width:100%}
  .cm-irow .cm-btn{margin-left:0}
  .cm-badge-nm{max-width:150px}
}


/* ================== ÉCRAN « MES COMMUNAUTÉS » (v0.6.176) ==================
   La GESTION a quitté le profil : les groupes qu'on gère et le composeur d'annonces
   vivent maintenant dans leur propre écran, atteint par l'entrée de menu du même nom.
   Le profil garde ce dont un compte qui ne gère RIEN a besoin — ses invitations, son
   appartenance, sa demande de droit —, sans quoi l'entrée, réservée aux gestionnaires,
   l'aurait privé d'accepter une invitation.

   Une LIGNE par communauté, et non un badge : chaque ligne porte désormais deux gestes
   (ouvrir la gestion, ouvrir la présence sur la carte), et deux boutons dans une pastille
   de la taille d'un mot ne se visent plus. */
.cm-mine{display:flex;flex-direction:column;gap:6px}
.cm-mine-row{
  display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding:7px 9px;border-radius:8px;
  background:var(--panel2);border:1px solid var(--line);
}
.cm-mine-row .cm-badge-nm{font-weight:600;color:var(--acc)}

/* LIENS VERS LA CARTE — un bouton déguisé en lien, jamais un `<a href>` : il ne navigue
   nulle part (il ouvre un volet de la même page), et un ancrage sans destination est un
   piège pour le clavier comme pour le lecteur d'écran. Même choix que `.fb-link`. */
.cm-link{
  background:transparent;border:0;padding:2px 0;
  color:var(--acc);font:inherit;font-size:13px;text-decoration:underline;cursor:pointer;
}
.cm-link:hover{color:var(--txt)}
.cm-link:focus-visible{outline:none;box-shadow:0 0 0 2px var(--focus);border-radius:4px}
/* Variante de LIGNE : plus discrète que le nom du groupe qu'elle accompagne, sinon les
   deux gestes se disputent l'oeil et le principal (ouvrir la gestion) perd. */
.cm-link-s{font-size:12px;color:var(--txt2);flex:0 0 auto}
.cm-link-s:hover{color:var(--acc)}

.cm-pres{display:flex;flex-direction:column;gap:2px}
.cm-pres-note{font-size:11.5px;color:var(--mut)}

/* ============================ USAGE MOBILE (v0.6.162) ============================
   La disposition est déjà traitée plus haut (560 px). Ne manquait que le POINTEUR.
   Registre des seuils : section mobile de search.css. */
@media (hover:none){
  /* `.cm-btn` tombe à 2-3 px de padding vertical selon le contexte, soit ~20 px de haut.
     C'est la moitié de la cible recommandée, sur des actions qui ne se rattrapent pas :
     quitter une communauté, révoquer un membre. */
  .cm-btn{min-height:40px;padding-left:12px;padding-right:12px}
  .cm-x{min-width:40px;min-height:40px}
  /* Un badge de communauté EST un bouton (il ouvre la proposition de départ) : il doit
     se viser comme tel, pas comme une étiquette. */
  .cm-badge{min-height:36px}
  /* Même seuil de 16 px que le volet Événements : en dessous, iOS zoome sur le champ
     focalisé et l'utilisateur se retrouve avec une page décadrée à recentrer à la main. */
  .cm-new-name,.cm-inv-name{min-height:40px;font-size:16px}
  .cm-cast-body{font-size:16px}
  .cm-cast-c{width:18px;height:18px}
}

/* Section « Échanges » du profil (v0.6.177) — une case, sans phrase d'explication.
   Le réglage est actif par défaut et n'ouvre qu'une vitrine vide : ce qui engage, c'est
   de taguer une carte dans la collection, pas cette case. */
.cm-trade{display:flex;align-items:center}
.cm-trade-l{display:inline-flex;align-items:center;gap:8px;cursor:pointer}
/* Meme contre-regle que le volet Echanges : `search.css` pose `input{width:100%}`
   globalement, et la case s'etalait sur toute la largeur du profil. */
.cm-trade-l input[type="checkbox"]{flex:0 0 auto;width:15px;height:15px;margin:0;padding:0;accent-color:var(--acc)}
