/* ============================================================
   MAPi · MESSAGERIE INTERNE (préfixe it-)
   Les salons de l'équipe, que le client ne voit jamais.

   DÉCISION FONDATRICE, et c'est une exception assumée à la charte :
   l'interne ne porte PAS le bleu de marque. Le bleu, c'est ce que
   le client voit ; s'en servir aussi pour ce qu'il ne doit pas voir
   reviendrait à peindre les deux mondes de la même couleur. L'interne
   prend donc une encre propre, un indigo qui n'existe nulle part
   ailleurs dans le produit, et il la porte partout : bandeau, bord
   du champ de saisie, bulles envoyées, pastilles, jusqu'à la coque
   de la page. On reconnaît l'environnement du coin de l'œil, sans
   avoir à lire un libellé.

   C'est la couche 1 des quatre garde-fous ; les trois autres sont
   dans js/interne.js (état permanent du composer, confirmation
   asymétrique côté client, contrôle du contenu avant envoi).
   ============================================================ */
:root {
    --it: #5A46C8;
    --it-soft: #EFECFC;
    --it-muted: #DAD3F6;
    --it-ink: #3B2C93;
    --it-line: #C4B9EE;
}
html[data-chrome="d"] {
    --it: #9C8BF5;
    --it-soft: #272052;
    --it-muted: #3A3175;
    --it-ink: #C3B7FF;
    --it-line: #463D89;
}

/* ---------- Coque de la page ---------- */
.it-page { display: grid; grid-template-columns: 268px minmax(0, 1fr); gap: 16px; align-items: start; }
/* `display: grid` posé par la classe l'emporte sur l'attribut `hidden` :
   sans cette règle, masquer une direction ne masque rien. Le piège est
   documenté dans CLAUDE.md, il se paie à chaque conteneur typé. */
.it-page[hidden], .it-rail[hidden], .it-ctx[hidden], .it-uni[hidden] { display: none; }
/* LA BASCULE DE VUE, en tête du panneau. Elle commande ce qu'il y a
   dessous : la liste des salons, ou le plateau. Elle tient toute la
   largeur du panneau, à parts égales, parce que les deux vues se valent
   et qu'aucune n'est le mode dégradé de l'autre. */
.it-vue {
    display: grid; grid-template-columns: 1fr 1fr; gap: 3px; margin-bottom: 10px;
    padding: 3px; background: var(--gray-100); border-radius: var(--radius-pill);
}
.it-vue[hidden] { display: none; }
/* L'EXEMPLAIRE DE LA PAGE NE SORT QUE SUR TÉLÉPHONE. Au-dessus du seuil,
   c'est celui de la colonne qui sert (voir `railHtml`), et celui-ci doit
   disparaître SANS occuper de cellule : `.it-page` est une grille, un
   enfant en trop y prendrait une colonne et décalerait tout le reste. */
.it-page.is-a > .it-vue { display: none; }
.it-vue button {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    min-height: 32px; padding: 0 10px;
    border: none; border-radius: var(--radius-pill); background: none; font: inherit;
    font-size: 12px; font-weight: 800; color: var(--text-secondary); cursor: pointer;
    transition: background .15s, color .15s;
}
.it-vue button[aria-pressed="true"] { background: var(--surface); color: var(--it-ink); box-shadow: var(--shadow-sm); }
.it-vue button:not([aria-pressed="true"]):hover { color: var(--text-primary); }
.it-vue button:focus-visible { outline: 2px solid var(--it); outline-offset: 1px; }
.it-vue svg { flex-shrink: 0; }

/* ---------- Colonne des salons ---------- */
.it-rail {
    background: var(--surface); border: 1px solid var(--gray-200); border-radius: var(--radius);
    box-shadow: var(--shadow-sm); padding: 10px; position: sticky; top: 12px;
    max-height: calc(100dvh - 150px); overflow: auto; scrollbar-width: thin;
}
.it-grp { margin-top: 12px; }
.it-grp:first-child { margin-top: 0; }
.it-grp-t {
    display: flex; align-items: center; gap: 6px; padding: 4px 9px 7px;
    font-size: 10.5px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--text-secondary);
}
.it-grp-t b { margin-left: auto; font-weight: 800; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.it-sal {
    display: flex; align-items: center; gap: 8px; width: 100%; min-height: 36px; padding: 0 9px;
    border: none; background: none; border-radius: 9px; font: inherit; font-size: 13px; font-weight: 700;
    color: var(--text-secondary); cursor: pointer; text-align: left; transition: background .14s, color .14s;
}
.it-sal .it-h { color: var(--text-muted); font-weight: 800; flex-shrink: 0; }
.it-sal span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.it-sal:hover { background: var(--gray-100); color: var(--text-primary); }
.it-sal.is-on { background: var(--it-soft); color: var(--it-ink); }
.it-sal.is-on .it-h { color: var(--it); }
.it-sal.is-nl { color: var(--text-primary); }
.it-sal-n {
    flex-shrink: 0; min-width: 19px; height: 19px; padding: 0 6px; border-radius: var(--radius-pill);
    background: var(--it); color: #fff; font-size: 11px; font-weight: 800;
    display: inline-flex; align-items: center; justify-content: center; font-variant-numeric: tabular-nums;
}
.it-sal.is-arch { opacity: .55; }

/* ---------- Le fil ---------- */
.it-fil { background: var(--surface); border: 1px solid var(--gray-200); border-radius: var(--radius); box-shadow: var(--shadow-sm); display: flex; flex-direction: column; min-height: 60dvh; overflow: hidden; }
/* Le bandeau de salon porte l'encre interne : c'est le premier signal */
.it-fil-h { display: flex; align-items: center; gap: 12px; padding: 13px 18px; background: var(--it-soft); border-bottom: 1.5px solid var(--it-line); flex-wrap: wrap; }
.it-fil-t { flex: 1; min-width: 0; }
.it-fil-t b { display: flex; align-items: center; gap: 6px; font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 900; font-size: 16px; color: var(--it-ink); }
.it-fil-t small { display: block; margin-top: 2px; font-size: 12px; color: var(--text-secondary); }
.it-fil-gens { display: flex; align-items: center; }
.it-ava {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 26px; height: 26px; border-radius: 50%; margin-left: -7px; border: 2px solid var(--it-soft);
    color: #fff; font-size: 9.5px; font-weight: 800;
}
.it-ava:first-child { margin-left: 0; }
.it-fil-lien { font-size: 12px; font-weight: 800; color: var(--it-ink); text-decoration: underline; }

.it-msgs { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 18px; scrollbar-width: thin; }
.it-jour { display: flex; align-items: center; gap: 12px; margin: 16px 0 12px; font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); }
.it-jour::before, .it-jour::after { content: ''; flex: 1; height: 1px; background: var(--gray-200); }
.it-msg { display: grid; grid-template-columns: 36px minmax(0, 1fr); gap: 11px; padding: 5px 0; }
.it-msg + .it-msg.is-suite { padding-top: 0; }
.it-msg.is-suite .it-msg-ava, .it-msg.is-suite .it-msg-h { visibility: hidden; height: 0; margin: 0; padding: 0; overflow: hidden; }
.it-msg-ava { width: 36px; height: 36px; border-radius: 11px; color: #fff; font-size: 12px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; }
.it-msg-h { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.it-msg-h b { font-size: 13.5px; font-weight: 800; color: var(--text-primary); }
.it-msg-h small { font-size: 11px; color: var(--text-secondary); }
.it-msg-b { font-size: 13.5px; line-height: 1.55; color: var(--text-secondary); max-width: 78ch; overflow-wrap: break-word; }
/* Mes messages : l'encre interne, pour qu'un coup d'œil au fil suffise */
.it-msg.is-moi .it-msg-b { color: var(--text-primary); }
.it-msg.is-moi .it-msg-h b { color: var(--it-ink); }

/* ---------- Le composer : la couche 2 du garde-fou ----------
   L'état est porté par la zone de saisie elle-même, là où l'erreur
   se produit, et pas en haut d'un écran qu'on a scrollé. */
.it-comp { flex-shrink: 0; border-top: 1.5px solid var(--gray-200); padding: 12px 18px 14px; }
.it-comp-box { border: 2px solid var(--it); border-radius: 14px; background: var(--surface); overflow: hidden; }
.it-comp-lbl {
    display: flex; align-items: center; gap: 7px; padding: 6px 12px;
    background: var(--it); color: #fff; font-size: 11px; font-weight: 800; letter-spacing: .02em;
}
.it-comp-lbl svg { flex-shrink: 0; }
.it-comp-lbl b { font-weight: 800; }
.it-comp-lbl span { margin-left: auto; opacity: .82; font-weight: 700; }
.it-comp textarea {
    display: block; width: 100%; min-height: 62px; max-height: 200px; padding: 11px 13px;
    border: none; background: none; font: inherit; font-size: 13.5px; line-height: 1.55; color: var(--text-primary); resize: vertical;
}
.it-comp textarea:focus-visible { outline: none; }
.it-comp-foot { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-top: 1px solid var(--gray-200); }
/* La ligne de mode d'emploi (« Entrée envoie, @ tague un collègue… ») a
   été retirée : elle occupait toute la place entre les trois boutons et
   « Envoyer », et faute de pouvoir rétrécir elle venait buter dans le
   bouton dès que le composeur se resserrait. Un composeur n'a pas
   besoin d'être commenté. */
.it-comp .btn--it { margin-left: auto; background: var(--it); color: #fff; border-color: var(--it); }
.it-comp .btn--it:hover { background: var(--it-ink); border-color: var(--it-ink); }

/* ---------- Membres ---------- */
.it-gens { display: flex; flex-direction: column; gap: 2px; }
.it-gen { display: flex; align-items: center; gap: 9px; padding: 5px 9px; border-radius: 9px; }
.it-gen:hover { background: var(--gray-100); }
.it-gen b { flex: 1; min-width: 0; font-size: 12.5px; font-weight: 700; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.it-gen small { font-size: 11px; color: var(--text-secondary); }
.it-pt { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

/* ---------- Mode Univers ---------- */
.it-uni { position: relative; background: #1E2A44; border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-sm); }
/* `touch-action: manipulation` : le plateau ne capture pas le geste, la
   page défile normalement au-dessus de lui (le module ne vise qu'au
   relâché, sans déplacement), et le délai de 300 ms du tap disparaît. */
.it-uni canvas { display: block; width: 100%; height: auto; image-rendering: pixelated; cursor: pointer; touch-action: manipulation; }
/* Le mode d'emploi dit le geste du support, pas les deux à la fois */
.it-uni-doigt { display: none; }
@media (hover: none) {
    .it-uni-clav { display: none; }
    .it-uni-doigt { display: inline; }
}
.it-uni-aide {
    position: absolute; left: 12px; bottom: 12px; display: flex; align-items: center; gap: 8px;
    padding: 7px 13px; border-radius: var(--radius-pill); background: rgba(11, 18, 32, .82); color: #fff;
    /* PAS DE FLOU DE FOND : elle est posée sur le plateau, qui se
       redessine soixante fois par seconde, et le navigateur devrait
       refaire le flou à chaque image. Mesuré sur la barre de visio,
       même opacité : la différence vaut 0,8 niveau sur 255 en moyenne.
       Voir la note de css/univers.css. */
    font-size: 11.5px; font-weight: 700;
}
.it-uni-aide kbd {
    display: inline-block; padding: 1px 6px; border-radius: 5px; border: 1px solid rgba(255, 255, 255, .45);
    font: inherit; font-size: 10.5px; font-weight: 800;
}
/* La bulle de salon, ancrée au-dessus de la pièce */
.it-uni-tag {
    position: absolute; transform: translate(-50%, -100%); pointer-events: none;
    padding: 3px 10px; border-radius: var(--radius-pill); background: var(--it); color: #fff;
    font-size: 11px; font-weight: 800; white-space: nowrap; box-shadow: 0 4px 12px rgba(9, 30, 66, .3);
}
.it-uni-tag.is-off { background: rgba(11, 18, 32, .72); }

/* Le repli mobile vit en fin de fichier, après `.it-page.is-a` :
   posé ici, il était écrasé par la grille à trois colonnes qui vient
   plus bas, et le fil se retrouvait à 77 px de large sur un
   téléphone. Voir la section « TÉLÉPHONE ET TABLETTE » en fin de
   fichier. */

@media (prefers-reduced-motion: no-preference) {
    .it-msg.is-neuf { animation: it-in .28s cubic-bezier(.22, 1, .36, 1) both; }
    @keyframes it-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
}

/* ============================================================
   Le PENDANT CLIENT du garde-fou (messages.html)
   Le composer interne dit « Interne » en indigo ; celui du client
   dit « À <entreprise> » en bleu. C'est la PAIRE qui fait le
   repère : chaque moitié prise seule ne prouve rien, les deux
   côte à côte ne se confondent pas.
   ============================================================ */
.mg-dest {
    display: flex; align-items: center; gap: 7px; margin: 0 0 8px;
    padding: 5px 11px; border-radius: var(--radius-pill);
    background: var(--blue-pale); color: var(--blue-dark);
    font-size: 11.5px; font-weight: 700; align-self: flex-start;
}
.mg-dest svg { flex-shrink: 0; }
.mg-dest b { font-weight: 800; }

/* La confirmation d'envoi : elle nomme, elle ne bloque pas */
.mg-cf-t { font-size: 13.5px; color: var(--text-secondary); line-height: 1.55; margin-bottom: 12px; }
.mg-cf-l { list-style: none; display: flex; flex-direction: column; gap: 8px; margin: 0 0 14px; }
.mg-cf-l li {
    display: flex; align-items: baseline; gap: 10px; padding: 9px 13px; border-radius: 11px;
    background: var(--orange-soft); color: var(--orange-ink);
}
.mg-cf-l b { font-weight: 800; font-size: 13.5px; }
.mg-cf-l span { font-size: 12px; opacity: .9; }
.mg-cf-n { font-size: 12.5px; color: var(--text-secondary); line-height: 1.5; }

/* ============================================================
   L'ÉCRAN RETENU · trois colonnes : salons, fil, contexte du dossier
   (les directions Flux et Réception ont été écartées et supprimées).
   Le salon d'un dossier vit à côté de son dossier : on arbitre sans
   quitter la conversation.
   ============================================================ */
.it-sal { text-align: left; justify-content: flex-start; }
/* Le « # » est un <span>, donc il héritait du `flex: 1` posé sur
   `.it-sal span` : il prenait la moitié de la ligne et poussait le
   libellé au centre. Il ne grandit plus. */
/* Tout ce qui n'est pas le libellé garde sa taille : sans ça, le « # »
   et la pastille héritent du `flex: 1` posé sur `.it-sal span` et se
   partagent la ligne à égalité avec le nom. */
.it-sal .it-h, .it-sal .it-sal-pt, .it-sal .it-sal-n, .it-sal .it-grpa { flex: 0 0 auto; }
.it-sal span { text-align: left; }
.it-sal-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.it-sal-tx b { font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.it-sal-tx small { font-size: 10.5px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.it-sal.is-on .it-sal-tx small { color: var(--it); }
.it-sal { min-height: 40px; padding: 4px 9px; }

/* ============================================================
   MESSAGES PRIVÉS (préfixe it-mp)
   L'autre moitié d'une messagerie d'équipe : ce qui se dit à une
   seule personne. La ligne montre la PERSONNE, pas un slug : un
   avatar, une pastille de présence cousue dessus, le nom, et le
   dernier mot échangé. On sait avant d'écrire si l'autre est là.

   La pastille de non-lu d'un privé porte toujours un chiffre :
   voir js/data-interne.js, un privé n'a qu'un destinataire, il
   n'a pas besoin de me nommer pour m'attendre.
   ============================================================ */
.it-sal .it-mpa { position: relative; flex: 0 0 auto; }
.it-mpa {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 9px; color: #fff; font-size: 9.5px; font-weight: 800;
}
.it-mpt {
    position: absolute; right: -3px; bottom: -3px; width: 10px; height: 10px; border-radius: 50%;
    border: 2px solid var(--surface);
}
.it-sal.is-on .it-mpt { border-color: var(--it-soft); }
/* Le dernier mot échangé se lit d'un ton en dessous du nom */
.it-sal.is-mp .it-sal-tx small { font-style: normal; display: flex; align-items: center; gap: 5px; }
/* ---------- LE STATUT S'ÉCRIT, il ne se devine pas ----------
   Une pastille de six pixels ne dit « en ligne » qu'à qui connaît déjà
   le code, et pas du tout à qui ne distingue pas le vert de l'orange.
   Le mot est donc sur la ligne, avant l'aperçu, et il prend l'encre de
   son état : la couleur double le texte, elle ne le remplace pas. */
.it-mpst { flex: none; width: 6px; height: 6px; border-radius: 50%; }
.it-sal.is-mp .it-sal-tx small em {
    flex: none; font-style: normal; font-weight: 800; letter-spacing: .01em;
}
.it-sal.is-p-actif .it-sal-tx small em { color: var(--green-ink, #1E7A3C); }
.it-sal.is-p-reunion .it-sal-tx small em { color: var(--orange-ink, #A85B22); }
.it-sal.is-p-absent .it-sal-tx small em { color: var(--text-muted); }
.it-sal.is-on .it-sal-tx small em { color: inherit; }
/* L'aperçu cède la place au statut quand la colonne se resserre : savoir
   si quelqu'un est là prime sur le dernier mot qu'il a écrit. */
.it-sal.is-mp .it-sal-tx small { min-width: 0; }

/* Le bandeau du fil : la personne au lieu du salon */
.it-fil-h.is-mp { gap: 13px; }
.it-fil-ava {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 40px; height: 40px; border-radius: 13px; color: #fff; font-size: 13px; font-weight: 800;
}
.it-fil-h.is-mp .it-fil-t small { display: flex; align-items: center; gap: 7px; }
.it-fil-pv {
    display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: var(--radius-pill);
    background: var(--surface); border: 1.5px solid var(--it-line); color: var(--it-ink);
    font-size: 11.5px; font-weight: 800;
}

/* La carte d'identité du contexte */
.it-card.is-mpc { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 3px; }
.it-mpc-ava {
    display: inline-flex; align-items: center; justify-content: center; margin-bottom: 6px;
    width: 54px; height: 54px; border-radius: 17px; color: #fff; font-size: 17px; font-weight: 800;
}
.it-card.is-mpc b { font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 900; font-size: 15px; color: var(--text-primary); }
.it-card.is-mpc small { font-size: 12px; color: var(--text-secondary); }
.it-mpc-st { display: inline-flex; align-items: center; gap: 7px; margin-top: 7px; font-size: 11.5px; font-weight: 700; color: var(--text-secondary); }
.it-mpc-plus { margin: 8px 0 0 9px; font-size: 11.5px; color: var(--text-secondary); }
/* Une personne listée est un raccourci vers son privé, pas un libellé */
button.it-gen { width: 100%; border: none; background: none; font: inherit; text-align: left; }
.it-gen.is-click { cursor: pointer; }
.it-gen.is-click:hover { background: var(--it-soft); }
.it-gen.is-click:hover b { color: var(--it-ink); }
.it-gen:focus-visible { outline: 2px solid var(--it); outline-offset: 1px; border-radius: 9px; }

/* Recherche du rail, commune aux trois */
/* UNE RANGÉE DE DEUX OBJETS, pas un champ qui en contient un autre.
   La porte des privés a d'abord été posée DANS le champ, en bout : elle
   y volait 38 px au texte, son anneau de focus se dessinait à
   l'intérieur du liseré de l'input, et deux commandes qui ne font pas la
   même chose partageaient une même boîte. Le champ cherche, le bouton
   navigue : ils se tiennent côte à côte, chacun dans sa boîte. */
.it-q { position: relative; display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
/* `>` ET PAS UN DESCENDANT. La loupe est le seul enfant DIRECT du
   champ ; en sélecteur descendant, cette règle happait aussi l'icône du
   bouton des privés : arrachée en position absolue par-dessus la loupe,
   décolorée, et rendue incliquable par le `pointer-events: none`. Elle
   reste absolue et calée sur le bord GAUCHE de la rangée, qui est celui
   de l'input : le champ est le premier objet et la rangée n'a pas de
   rembourrage. */
.it-q > svg { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--text-muted); pointer-events: none; z-index: 1; }
.it-q input {
    flex: 1 1 auto; min-width: 0;
    min-height: 36px; padding: 0 12px 0 33px; border: 1.5px solid var(--gray-300);
    border-radius: 10px; font: inherit; font-size: 12.5px; background: var(--surface); color: var(--text-primary);
}
.it-q input:focus-visible { outline: 2px solid var(--it); outline-offset: 1px; border-color: var(--it); }

/* ------------------------------------------------------------
   LA PORTE DES PRIVÉS (2026-08-17)
   Les conversations privées vivent au bas de la colonne, sous trente
   salons. Ce bouton les ramène d'un geste, depuis n'importe quelle
   famille. Il se pose DANS le champ, en bout, en jumeau de la loupe :
   c'est la seule façon d'être « à côté de la recherche » sans voler de
   largeur à la rangée des onglets, et le champ lui cède 38 px à droite
   comme il en cède 33 à la loupe à gauche.

   Rayon 9 px : celui des vignettes de privé (.it-mpa plus haut). Le
   bouton rime avec ce vers quoi il mène. Encre indigo quand il est
   enfoncé, comme tout ce qui est « entre nous » dans cet écran.
   ------------------------------------------------------------ */
.it-qmp {
    position: relative; flex: 0 0 auto;
    width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center;
    border: 1.5px solid var(--gray-300); border-radius: 10px;
    background: var(--surface); color: var(--text-secondary);
    cursor: pointer; transition: background .15s, color .15s, border-color .15s;
}
.it-qmp:hover { background: var(--it-soft); border-color: var(--it); color: var(--it); }
.it-qmp[aria-pressed="true"] { background: var(--it); border-color: var(--it); color: #fff; }
.it-qmp:focus-visible { outline: 2px solid var(--it); outline-offset: 2px; }
/* La pastille déborde du coin et s'en détache par un anneau DE LA
   COULEUR DU BOUTON, pas du fond de page : sur le bouton enfoncé, un
   anneau blanc creusait un croissant clair dans l'indigo, comme si le
   coin était mordu. Elle reste lisible dans les deux états, blanche sur
   indigo quand il est enfoncé, indigo sur blanc sinon. */
.it-qmp-n, .it-qmp-pt {
    position: absolute; top: -3px; right: -3px;
    box-shadow: 0 0 0 2px var(--surface); border-radius: 999px;
}
.it-qmp-n {
    min-width: 15px; height: 15px; padding: 0 3px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--it); color: #fff; font-size: 9.5px; font-weight: 800; line-height: 1;
}
.it-qmp-pt { width: 7px; height: 7px; background: var(--it); }
.it-qmp[aria-pressed="true"] .it-qmp-n { background: #fff; color: var(--it); box-shadow: 0 0 0 2px var(--it); }
.it-qmp[aria-pressed="true"] .it-qmp-pt { background: #fff; box-shadow: 0 0 0 2px var(--it); }
@media (prefers-reduced-motion: reduce) { .it-qmp { transition: none; } }

/* ============================================================
   UNE LIGNE DE GROUPE : LES VISAGES DANS LE CARRÉ D'UN VISAGE
   ------------------------------------------------------------
   Un groupe se reconnaît à ses gens et non à un nom : la ligne montre
   donc deux ou trois portraits. Mais la gouttière des vignettes est
   une COLONNE, et elle ne se négocie pas : trois visages en tuilage
   horizontal faisaient 52 px là où un visage seul en fait 26, et les
   noms partaient à trois abscisses différentes selon le nombre de
   personnes dans le groupe (156, 167, 182 px, mesuré). Trois bords
   gauches dans la même liste, dont le décalage dépendait d'une
   information dont le lecteur n'a que faire.

   Les tuiles tiennent donc dans le carré d'un visage (26 px, même
   rayon proportionnel), posées en absolu : deux en diagonale, trois
   en triangle. Elles se chevauchent un peu, et le liseré à la couleur
   de la surface les sépare, comme le tuilage d'origine le faisait.

   S'AJOUTE UNE CAUSE PLUS BÊTE, la même que celle déjà payée deux
   fois plus haut pour le « # » et les pastilles : `.it-sal span`
   (0-1-1) pose `flex: 1` et bat le `flex: 0 0 auto` de `.it-grpa`
   (0-1-0). La pile prenait la moitié de la ligne et poussait le nom
   de 57 px vers la droite. Elle est désormais dans la liste des
   exceptions, avec les autres.
   ============================================================ */
.it-grpa { position: relative; display: block; width: 26px; height: 26px; }
.it-grpa i {
    position: absolute; width: 15px; height: 15px; border-radius: 5px;
    display: inline-flex; align-items: center; justify-content: center;
    font-style: normal; font-size: 7px; font-weight: 800; color: #fff;
    box-shadow: 0 0 0 1.5px var(--surface);
}
/* Un seul autre membre : la tuile prend toute la place, comme un privé. */
.it-grpa[data-n="1"] i { inset: 0; width: auto; height: auto; border-radius: 9px; font-size: 9.5px; }
.it-grpa[data-n="2"] i:nth-child(1) { left: 0; top: 0; }
.it-grpa[data-n="2"] i:nth-child(2) { right: 0; bottom: 0; }
.it-grpa[data-n="3"] i:nth-child(1) { left: 0; top: 0; }
.it-grpa[data-n="3"] i:nth-child(2) { right: 0; top: 0; }
.it-grpa[data-n="3"] i:nth-child(3) { left: 50%; bottom: 0; transform: translateX(-50%); }
/* La tuile est déjà positionnée : `.it-vis { position: relative }` ne
   doit pas la remettre dans le flux. La spécificité suffit (0-1-1
   contre 0-1-0), c'est écrit ici pour qu'on ne l'inverse pas. */
/* Le liseré qui sépare les tuiles est de la couleur du FOND DE LA
   LIGNE, pas du blanc : sur une ligne survolée ou ouverte il trahirait
   sinon un carré blanc autour de chaque visage. */
.it-sal:hover .it-grpa i { box-shadow: 0 0 0 1.5px var(--gray-100); }
.it-sal.is-on .it-grpa i, .it-sal.is-on:hover .it-grpa i { box-shadow: 0 0 0 1.5px var(--it-soft); }
.it-sal.is-grp .it-sal-tx b { font-weight: 700; }

/* ---------- A · Atelier : la troisième colonne ---------- */
.it-page.is-a { grid-template-columns: 250px minmax(0, 1fr) 268px; }
/* Le fil occupe la hauteur utile : sans ça, un salon court laissait un
   grand vide sous le composer et l'écran paraissait inachevé. */
.it-page.is-a .it-fil { height: calc(100dvh - 176px); min-height: 420px; }
.it-ctx { display: flex; flex-direction: column; gap: 12px; position: sticky; top: 12px; }
.it-card { background: var(--surface); border: 1px solid var(--gray-200); border-radius: var(--radius); box-shadow: var(--shadow-sm); padding: 14px 16px; }
.it-card h3 { font-size: 11px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--text-secondary); margin-bottom: 10px; }
.it-card .it-gen { padding: 4px 0; }
.it-dl { display: flex; flex-direction: column; gap: 9px; }
.it-dl div { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.it-dl dt { font-size: 11.5px; color: var(--text-secondary); }
.it-dl dd { margin: 0; font-size: 12.5px; font-weight: 800; color: var(--text-primary); text-align: right; }
.it-etape { display: flex; gap: 3px; margin-top: 10px; }
.it-etape i { flex: 1; height: 4px; border-radius: 2px; background: var(--gray-200); }
.it-etape i.is-on { background: var(--it); }
@media (max-width: 1240px) { .it-page.is-a { grid-template-columns: 250px minmax(0, 1fr); } .it-ctx { display: none; } }

/* ============================================================
/* ============================================================
   LES PASTILLES · deux niveaux, et c'est tout le sujet
   Une MENTION porte un chiffre plein : elle attend une réponse de
   moi. Un non-lu simple ne porte qu'un POINT : il attend d'être lu.
   Chiffrer les deux revenait à dire que tout est également urgent,
   donc que rien ne l'est — et à constellet l'écran d'indigo, au
   point que la couleur qui signifie « interne » devenait du bruit.
   Le nom en gras suffit à dire qu'il y a du nouveau.
   ============================================================ */
.it-sal-n {
    flex-shrink: 0; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-pill);
    background: var(--it); color: #fff; font-size: 10.5px; font-weight: 800;
    display: inline-flex; align-items: center; justify-content: center; font-variant-numeric: tabular-nums;
}
.it-sal-pt { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--it); }
.it-sal.is-nl .it-sal-tx b { color: var(--text-primary); font-weight: 800; }
.it-sal.is-on .it-sal-n { background: var(--it-ink); }

/* Groupes repliables : à seize salons, on ne veut pas tout voir */
.it-grp-t {
    display: flex; align-items: center; gap: 7px; width: 100%; padding: 6px 9px;
    border: none; background: none; font: inherit;
    font-size: 10.5px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-secondary); cursor: pointer; border-radius: 8px;
}
.it-grp-t:hover { background: var(--gray-100); color: var(--text-primary); }
.it-grp-t svg { flex-shrink: 0; transition: transform .16s; }
.it-grp-t[aria-expanded="true"] svg { transform: rotate(90deg); }
.it-grp-t b { margin-left: auto; font-weight: 800; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.it-grp-t .it-sal-n { margin-left: auto; }
.it-grp.is-plie .it-grp-l { display: none; }
@media (prefers-reduced-motion: reduce) { .it-grp-t svg { transition: none; } }

/* Le trait de reprise de lecture */
.it-neuf { display: flex; align-items: center; gap: 10px; margin: 18px 0 12px; }
.it-neuf::before, .it-neuf::after { content: ''; flex: 1; height: 1px; background: var(--it-line); }
.it-neuf span {
    flex-shrink: 0; padding: 2px 11px; border-radius: var(--radius-pill);
    background: var(--it); color: #fff; font-size: 10.5px; font-weight: 800; letter-spacing: .03em;
}

/* Un message qui me nomme : liseré à gauche, pas un fond de plus */
.it-msg.is-mention { position: relative; }
.it-msg.is-mention .it-msg-b {
    padding-left: 11px; border-left: 3px solid var(--it); border-radius: 0 8px 8px 0;
    background: var(--it-soft); color: var(--it-ink); padding-top: 7px; padding-bottom: 7px; padding-right: 11px;
}
.it-tag-m {
    padding: 1px 7px; border-radius: var(--radius-pill); background: var(--it-soft); color: var(--it-ink);
    font-size: 9.5px; font-weight: 800; letter-spacing: .03em; text-transform: uppercase;
}
.it-ava--n { background: var(--gray-300); color: var(--text-secondary); }

/* ============================================================
   DEUX BLOCS DISTINCTS · Équipe et Dossiers
   Repris tel quel du segmenté du menu Tâches (.tk-modes), pour
   qu'une même intention se dise partout de la même façon. Deux
   familles qui ne se lisent pas pareil : les salons d'équipe sont
   permanents et peu nombreux, ceux de dossier naissent et meurent
   avec leur dossier. Empilés, ils obligeaient l'œil à faire le tri.
   ============================================================ */
/* DES ONGLETS, PAS UN SECOND SEGMENTÉ (2026-08-02). La bascule de vue
   juste au-dessus est déjà une pilule à deux parts ; répéter la même
   forme dessous donnait deux commandes jumelles empilées, dont on ne
   savait plus laquelle commandait quoi. Équipe et Dossiers deviennent
   donc de vrais onglets, soulignés : la forme dit la hiérarchie, la
   pilule choisit l'écran, les onglets choisissent le contenu. */
.it-modes {
    display: flex; gap: 2px; margin-bottom: 10px;
    border-bottom: 1.5px solid var(--gray-200);
}
.it-mode {
    flex: 1; position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    min-height: 36px; padding: 0 8px 8px; border: none; background: none;
    font: inherit; font-size: 12.5px; font-weight: 800;
    color: var(--text-secondary); cursor: pointer; transition: color .15s;
}
.it-mode svg { flex-shrink: 0; opacity: .7; }
/* Le trait déborde d'un pixel et demi sous la bordure du groupe : sans
   ce chevauchement, l'onglet actif paraît posé DEVANT une ligne au lieu
   d'y être accroché. */
.it-mode::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: -1.5px; height: 2.5px;
    border-radius: 2px; background: transparent;
}
/* L'indigo, pas le bleu de marque : on est dans l'interne */
.it-mode[aria-selected="true"] { color: var(--it-ink); }
.it-mode[aria-selected="true"]::after { background: var(--it); }
.it-mode[aria-selected="true"] svg { opacity: 1; }
.it-mode:not([aria-selected="true"]):hover { color: var(--text-primary); }
.it-mode:not([aria-selected="true"]):hover::after { background: var(--gray-300); }
.it-mode:focus-visible { outline: 2px solid var(--it); outline-offset: -2px; border-radius: 8px 8px 0 0; }

/* ============================================================
   RECHERCHE DE MESSAGES
   Le même champ répond deux fois : la colonne filtre les salons
   pour naviguer, le centre montre les messages trouvés. Chercher,
   c'est le plus souvent chercher une phrase, pas un salon.
   ============================================================ */
.it-fil.is-res { padding: 0; }
.it-res-h { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; padding: 15px 18px; border-bottom: 1px solid var(--gray-200); }
.it-res-h b { font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 900; font-size: 16px; color: var(--text-primary); }
.it-res-h span { font-size: 13px; color: var(--text-secondary); }
.it-res-x { margin-left: auto; border: none; background: none; font: inherit; font-size: 12px; font-weight: 800; color: var(--it-ink); cursor: pointer; text-decoration: underline; }
.it-res-f { display: flex; gap: 7px; flex-wrap: wrap; padding: 12px 18px; border-bottom: 1px solid var(--gray-200); }
.it-res-f .chip[aria-pressed="true"] { border-color: var(--it); background: var(--it-soft); color: var(--it-ink); }
.it-res-l { flex: 1; min-height: 0; overflow-y: auto; scrollbar-width: thin; }
.it-res {
    display: grid; grid-template-columns: 36px minmax(0, 1fr); gap: 11px; width: 100%;
    padding: 12px 18px; border: none; border-bottom: 1px solid var(--gray-200);
    background: none; font: inherit; text-align: left; cursor: pointer;
}
.it-res:hover { background: var(--it-soft); }
.it-res-tx { min-width: 0; }
.it-res-m { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.it-res-m b { font-size: 13px; font-weight: 800; color: var(--text-primary); }
.it-res-m small { font-size: 11px; color: var(--text-secondary); margin-left: auto; }
.it-res-s { font-size: 11px; font-weight: 800; color: var(--it-ink); background: var(--it-soft); padding: 1px 8px; border-radius: var(--radius-pill); }
.it-res-c { display: block; margin-top: 4px; font-size: 13px; line-height: 1.5; color: var(--text-secondary); }
/* Le terme trouvé, surligné : c'est ce qui rend un résultat lisible d'un coup */
.it-res-c mark { background: #FFE9A8; color: var(--text-primary); font-weight: 700; border-radius: 3px; padding: 0 2px; }
html[data-chrome="d"] .it-res-c mark { background: #5A4A18; color: #FFE9A8; }
.it-res-plus { padding: 14px 18px; font-size: 12.5px; color: var(--text-secondary); }

/* ============================================================
   PIÈCES JOINTES · images et stickers
   Les images viennent du disque, du presse-papiers ou d'un
   glisser-déposer. Les stickers sont dessinés en SVG et animés en
   CSS : aucun fichier à charger, donc rien à rater hors ligne, et
   le mouvement se coupe quand le système le demande.
   ============================================================ */
.it-cb {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    min-width: 30px; height: 30px; padding: 0 8px; border-radius: 9px;
    border: 1.5px solid var(--gray-300); background: var(--surface);
    font: inherit; font-size: 10.5px; font-weight: 800; color: var(--text-secondary); cursor: pointer;
    transition: border-color .15s, color .15s, background .15s;
}
.it-cb:hover { border-color: var(--it); color: var(--it-ink); background: var(--it-soft); }
.it-comp-box.is-over { border-style: dashed; background: var(--it-soft); }
.it-pj { display: flex; gap: 8px; flex-wrap: wrap; padding: 0 13px 10px; }
.it-pj[hidden] { display: none; }
.it-pj-v { position: relative; display: inline-flex; }
.it-pj-v img { width: 64px; height: 64px; object-fit: cover; border-radius: 10px; border: 1px solid var(--gray-200); }
.it-pj-x {
    position: absolute; top: -6px; right: -6px; width: 20px; height: 20px; border-radius: 50%;
    border: none; background: var(--text-primary); color: #fff; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
}
.it-msg-pj { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.it-msg-img { display: inline-flex; }
.it-msg-img img { max-width: 260px; max-height: 200px; border-radius: 12px; border: 1px solid var(--gray-200); display: block; }
.it-stick { display: inline-flex; width: 48px; height: 48px; }
.it-stick svg { width: 100%; height: 100%; }
.it-stick.is-big { width: 84px; height: 84px; }
/* Le champ de recherche des stickers portait `.bo-in`, qui vit dans
   css/crm.css : cette page ne la charge pas, l'input arrivait nu (146 px,
   sans bordure ni hauteur). On l'habille comme celui du rail. */
#stQ, #gifQ {
    width: 100%; min-height: 44px; padding: 0 13px; border: 1.5px solid var(--gray-300);
    border-radius: 11px; font: inherit; font-size: 16px; background: var(--surface); color: var(--text-primary);
}
#stQ:focus-visible, #gifQ:focus-visible { outline: 2px solid var(--it); outline-offset: 1px; border-color: var(--it); }
/* ---------- Sortir d'un canal, épingles, @tags, GIF, dessin ---------- */
/* L'ÉTAT RESTE DANS LE TITRE, LA COMMANDE EST PARTIE DANS LA FEUILLE.
   Cette étiquette dit qu'on est sorti ; le bouton qui fait sortir vit
   depuis le 2026-08-09 au bout du contexte, derrière le « i ». Un état
   se lit là où l'on regarde, une commande irréversible-par-inadvertance
   se range là où l'on va exprès. */
.it-fil-sorti { margin-left: 8px; font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); border: 1px solid var(--gray-300); border-radius: var(--radius-pill); padding: 2px 8px; vertical-align: 2px; }
.it-fil-ep {
    display: inline-flex; align-items: center; gap: 6px; flex: none;
    border: 1.5px solid var(--gray-300); border-radius: var(--radius-pill); background: none;
    color: var(--text-secondary); font: 700 12px/1 'Mukta Mahee', sans-serif; padding: 6px 12px; cursor: pointer;
    transition: border-color .15s, color .15s, background .15s;
}
.it-fil-ep:hover { border-color: var(--it-encre, #5A46C8); color: var(--it-encre, #5A46C8); }
.it-fil-ep.is-on { border-color: var(--it-encre, #5A46C8); color: var(--it-encre, #5A46C8); background: var(--it-pale, #F1EEFC); }
.it-fil-ep:focus-visible { outline: 2px solid var(--it-encre, #5A46C8); outline-offset: -1.5px; }
/* ---------- Chercher dans la conversation ----------
   Première carte de la feuille : c'est la raison la plus fréquente de
   l'ouvrir. Le champ ressemble à celui de la colonne, pour qu'on n'ait
   pas à apprendre un deuxième objet ; les réponses, elles, ne
   ressemblent à rien d'autre, parce qu'elles ne mènent nulle part
   ailleurs que dans le fil ouvert. */
.it-rq-f { position: relative; display: flex; align-items: center; }
.it-rq-f svg { position: absolute; left: 11px; color: var(--text-muted); pointer-events: none; }
.it-rq-f input {
    width: 100%; min-height: 40px; padding: 0 12px 0 34px;
    border: 1.5px solid var(--gray-300); border-radius: var(--radius-pill);
    background: var(--surface); font: inherit; font-size: 13px; color: var(--text-primary);
}
.it-rq-f input:focus-visible { outline: 2px solid var(--it); outline-offset: 1px; border-color: var(--it); }
.it-rq-r { margin-top: 10px; }
.it-rq-vide, .it-rq-n { font-size: 11.5px; color: var(--text-secondary); }
.it-rq-n { margin-bottom: 8px; font-weight: 700; }
/* Un résultat est un RACCOURCI vers un endroit du fil : il se lit comme
   une ligne de liste, pas comme un message. Deux étages, qui d'abord et
   quand, l'extrait ensuite. */
.it-rq-i {
    display: flex; flex-direction: column; gap: 3px; width: 100%; text-align: left;
    padding: 9px 11px; margin-bottom: 6px;
    border: 1px solid var(--gray-200); border-radius: 12px;
    background: var(--surface); font: inherit; cursor: pointer;
    transition: border-color .14s, background .14s;
}
.it-rq-i:hover { border-color: var(--it); background: var(--it-pale, #F1EEFC); }
.it-rq-i:focus-visible { outline: 2px solid var(--it); outline-offset: 1px; }
.it-rq-h { display: flex; align-items: baseline; gap: 8px; }
.it-rq-h b { font-size: 12.5px; font-weight: 800; color: var(--text-primary); }
.it-rq-h small { font-size: 11px; color: var(--text-muted); }
.it-rq-x { font-size: 12.5px; line-height: 1.5; color: var(--text-secondary); }
.it-rq-x mark { background: var(--it-pale, #F1EEFC); color: var(--it-ink); font-weight: 800; border-radius: 3px; padding: 0 2px; }
.it-rq-i:hover .it-rq-x mark { background: var(--surface); }
/* LE MESSAGE S'ALLUME À L'ARRIVÉE. Sans ce halo, on atterrit quelque
   part dans une conversation sans savoir lequel des messages visibles
   était celui qu'on cherchait. Une seconde et demie, puis il redevient
   un message comme les autres. */
.it-msg.is-trouve { border-radius: 12px; }
@media (prefers-reduced-motion: no-preference) {
    .it-msg.is-trouve { animation: it-trouve 1.8s ease-out both; }
    @keyframes it-trouve {
        0%, 55% { background: var(--it-pale, #F1EEFC); box-shadow: 0 0 0 6px var(--it-pale, #F1EEFC); }
        100% { background: transparent; box-shadow: 0 0 0 6px transparent; }
    }
}
@media (prefers-reduced-motion: reduce) {
    .it-msg.is-trouve { background: var(--it-pale, #F1EEFC); box-shadow: 0 0 0 6px var(--it-pale, #F1EEFC); }
}

/* La carte « Notifications », en pied de feuille. Elle n'attire pas
   l'oeil : c'est une commande qu'on vient chercher, pas une qu'on
   propose. La phrase passe avant le bouton, pour qu'on sache ce qu'on
   fait avant de le faire. */
.it-out-d { margin-bottom: 10px; font-size: 12px; line-height: 1.5; color: var(--text-secondary); }
.it-out-b { width: 100%; justify-content: center; }
.it-out-b.is-dehors { border-color: var(--it-encre, #5A46C8); color: var(--it-encre, #5A46C8); background: var(--it-pale, #F1EEFC); }
/* Le bandeau des épinglés : au-dessus du fil, replié par défaut */
.it-eplist { flex: none; border-bottom: 1px solid var(--gray-200); background: var(--it-pale, #F1EEFC); padding: 8px 14px; max-height: 200px; overflow-y: auto; scrollbar-width: thin; }
.it-eplist-h { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 800; color: var(--it-encre, #5A46C8); padding-bottom: 4px; }
.it-eplist-x { margin-left: auto; border: 0; background: none; color: var(--text-secondary); cursor: pointer; width: 22px; height: 22px; border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; }
.it-eplist-x:hover { background: rgba(90, 70, 200, .12); }
.it-ep-item {
    display: flex; align-items: baseline; gap: 8px; width: 100%; text-align: left;
    border: 0; background: none; font: inherit; font-size: 12.5px; padding: 5px 4px; border-radius: 8px; cursor: pointer;
}
.it-ep-item:hover { background: rgba(90, 70, 200, .1); }
.it-ep-item b { flex: none; font-weight: 800; color: var(--text-primary); }
.it-ep-item span { flex: 1; min-width: 0; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.it-ep-item small { flex: none; color: var(--text-muted); font-variant-numeric: tabular-nums; }
/* L'épingle d'un message : au survol seulement, l'entretien n'est pas le premier plan */
.it-msg-pin { margin-left: auto; border: 0; background: none; color: var(--text-muted); width: 24px; height: 24px; border-radius: 7px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; opacity: 0; transition: opacity .12s, background .15s, color .15s; }
.it-msg:hover .it-msg-pin, .it-msg-pin:focus-visible { opacity: 1; }
.it-msg-pin:hover { background: var(--it-pale, #F1EEFC); color: var(--it-encre, #5A46C8); }
.it-msg.is-epingle .it-msg-pin { opacity: .8; color: var(--it-encre, #5A46C8); }
.it-tag-ep { display: inline-flex; align-items: center; gap: 3px; font-size: 10px; font-weight: 800; color: var(--it-encre, #5A46C8); background: var(--it-pale, #F1EEFC); border-radius: var(--radius-pill); padding: 2px 7px; }
@media (prefers-reduced-motion: no-preference) {
    .it-msg.is-cible { animation: it-cible 1.2s cubic-bezier(.22, 1, .36, 1); }
}
@keyframes it-cible { 0%, 55% { background: var(--it-pale, #F1EEFC); } 100% { background: none; } }
/* Le @tag dans un corps de message */
.it-at-tag { font-weight: 800; color: var(--it-encre, #5A46C8); background: var(--it-pale, #F1EEFC); border-radius: 6px; padding: 0 3px; }
/* La liste d'autocomplétion du @ */
.it-at {
    position: fixed; z-index: 95; max-height: 300px; overflow-y: auto; scrollbar-width: thin;
    background: var(--surface); border: 1px solid var(--gray-200); border-radius: 12px; padding: 5px;
    box-shadow: 0 18px 44px -14px rgba(9, 30, 66, .4);
}
.it-at-o { display: flex; align-items: center; gap: 8px; width: 100%; border: 0; background: none; font: inherit; font-size: 13px; text-align: left; padding: 6px 8px; border-radius: 8px; cursor: pointer; }
.it-at-o b { flex: none; font-weight: 800; }
.it-at-o small { flex: 1; min-width: 0; display: inline-flex; align-items: center; gap: 5px; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.it-at-o.is-sur, .it-at-o:hover { background: var(--it-pale, #F1EEFC); }
.it-at-ava { width: 24px; height: 24px; border-radius: 8px; font-size: 9px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-weight: 800; flex: none; overflow: hidden; }
/* La grille de GIF Giphy */
.it-gif-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 10px 0 4px; min-height: 70px; }
.it-gif-b { border: 1.5px solid var(--gray-200); border-radius: 10px; background: var(--gray-100); padding: 0; overflow: hidden; cursor: pointer; aspect-ratio: 4 / 3; transition: border-color .15s, transform .15s; }
.it-gif-b:hover { border-color: var(--it-encre, #5A46C8); transform: translateY(-1px); }
.it-gif-b img { width: 100%; height: 100%; object-fit: cover; display: block; }
.it-gif-info { grid-column: 1 / -1; align-self: center; text-align: center; font-size: 12.5px; color: var(--text-secondary); padding: 16px 8px; }
.it-st-sep { margin: 14px 0 8px; font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
/* Le mode dessin */
.it-ds-barre { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.it-ds-c { width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--gray-300); cursor: pointer; padding: 0; }
.it-ds-c.is-on { border-color: var(--it-encre, #5A46C8); box-shadow: 0 0 0 3px var(--it-pale, #F1EEFC); }
.it-ds-t { width: 28px; height: 28px; border-radius: 8px; border: 1.5px solid var(--gray-300); background: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0; }
.it-ds-t i { display: block; border-radius: 50%; background: var(--text-primary); }
.it-ds-t.is-on { border-color: var(--it-encre, #5A46C8); background: var(--it-pale, #F1EEFC); }
.it-ds-g { border: 1.5px solid var(--gray-300); border-radius: var(--radius-pill); background: none; font: 700 12px/1 'Mukta Mahee', sans-serif; color: var(--text-secondary); padding: 6px 11px; cursor: pointer; }
.it-ds-g:hover { border-color: var(--it-encre, #5A46C8); color: var(--it-encre, #5A46C8); }
.it-ds-sep { width: 1px; height: 20px; background: var(--gray-300); margin: 0 3px; }
.it-ds-cv { width: 100%; border: 1.5px solid var(--gray-300); border-radius: 12px; background: #FBFCFE; touch-action: none; cursor: crosshair; display: block; }
/* Un salon quitté se fait discret dans le rail */
.it-sal.is-sorti { opacity: .55; }

.it-stgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 10px; margin-top: 14px; }
.it-stb {
    display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 12px 6px;
    border: 1.5px solid var(--gray-200); border-radius: 13px; background: var(--surface);
    font: inherit; font-size: 11px; font-weight: 700; color: var(--text-secondary); cursor: pointer;
    transition: border-color .15s, background .15s;
}
.it-stb:hover { border-color: var(--it); background: var(--it-soft); color: var(--it-ink); }
.it-stb[hidden] { display: none; }

/* Les stickers ne bougent que si le système l'autorise */
@media (prefers-reduced-motion: no-preference) {
    .s-pop { animation: s-pop 2.4s ease-in-out infinite; transform-origin: center; }
    @keyframes s-pop { 0%, 70%, 100% { transform: scale(1); } 78% { transform: scale(1.07); } }
    .s-tick { stroke-dasharray: 44; animation: s-tick 2.4s ease-in-out infinite; }
    @keyframes s-tick { 0%, 12% { stroke-dashoffset: 44; } 30%, 100% { stroke-dashoffset: 0; } }
    .s-up { animation: s-up 1.8s ease-in-out infinite; }
    @keyframes s-up { 0%, 100% { transform: translateY(2px); } 50% { transform: translateY(-3px); } }
    .s-beat { animation: s-beat 1.4s ease-in-out infinite; transform-origin: center; }
    @keyframes s-beat { 0%, 100% { transform: scale(1); } 20% { transform: scale(1.12); } 40% { transform: scale(1); } }
    .s-blink { animation: s-blink 1.2s steps(1) infinite; }
    @keyframes s-blink { 0%, 60% { opacity: 1; } 61%, 100% { opacity: .25; } }
    .s-steam { animation: s-steam 2.2s ease-in-out infinite; }
    @keyframes s-steam { 0%, 100% { opacity: .35; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-2px); } }
    .s-draw { stroke-dasharray: 40; animation: s-draw 3s ease-in-out infinite; }
    @keyframes s-draw { 0%, 10% { stroke-dashoffset: 40; } 45%, 100% { stroke-dashoffset: 0; } }
    .s-turn { animation: s-turn 3.2s ease-in-out infinite; transform-origin: 32px 32px; }
    @keyframes s-turn { 0%, 60% { transform: rotate(0); } 85%, 100% { transform: rotate(180deg); } }
    .s-conf { animation: s-conf 1.8s ease-in-out infinite; }
    @keyframes s-conf { 0%, 100% { transform: translateY(0); opacity: 1; } 50% { transform: translateY(-4px); opacity: .7; } }
}

/* ============================================================
   TÉLÉPHONE ET TABLETTE
   Points de rupture 1240 (le contexte tombe) et 860 (la liste et
   le fil ne tiennent plus côte à côte), repris de la messagerie
   CLIENT (messages.html) : deux messageries de la même app
   doivent se replier de la même façon, sinon on réapprend un
   geste en changeant d'onglet.

   Le modèle est celui de n'importe quelle messagerie de
   téléphone : la LISTE occupe l'écran, ouvrir un salon la
   RECOUVRE, un bouton retour ramène. Une seule chose à la fois.
   `body.it-fil-on` (posé par interne.html) dit laquelle.

   CE QUI PORTE LE GARDE-FOU, DEPUIS QUE LE SCEAU N'EST PLUS LÀ.
   Ce bloc s'appuyait sur un sceau « Équipe MAPi » en tête de page :
   il a été retiré du balisage le 2026-08-02, et le bandeau du
   composeur qui avait pris le relais est parti le 2026-08-09. Ne pas
   raisonner sur des fantômes : sur téléphone, ce qui dit « interne »
   est l'indigo de tout l'écran, le cadre de 2 px du champ de saisie,
   le cadenas devant le nom du fil, et l'entrée « Interne » de la
   barre du bas, toujours visible à quelques pixels du composeur.
   ============================================================ */

/* Retour à la liste : n'existe qu'en vue téléphone */
.it-back {
    display: none; flex-shrink: 0; align-items: center; justify-content: center;
    width: 40px; height: 40px; border-radius: 50%;
    border: 1.5px solid var(--it-line); background: var(--surface); color: var(--it-ink); cursor: pointer;
}
.it-back:focus-visible { outline: 2px solid var(--it); outline-offset: 2px; }
/* Appel du contexte : n'existe que lorsque la 3e colonne est tombée */
.it-info, .it-ctx-x { display: none; }
/* Le voile de la feuille de contexte. Jamais piloté par `hidden` :
   la classe qui pose son `display` l'emporterait sur l'attribut. */
.it-ctx-fond { display: none; position: fixed; inset: 0; z-index: 94; border: none; background: rgba(9, 30, 66, .34); }

@media (max-width: 1240px) {
    /* Le contexte ne tient plus à côté du fil. Plutôt que de le
       perdre (un salon de dossier sans son dossier ne sert plus à
       arbitrer), il devient une FEUILLE qui monte du bas, appelée
       par le bouton « Contexte » du bandeau. */
    .it-info {
        display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
        min-height: 36px; padding: 0 12px; border-radius: var(--radius-pill);
        border: 1.5px solid var(--it-line); background: var(--surface); color: var(--it-ink);
        font: inherit; font-size: 12px; font-weight: 800; cursor: pointer;
    }
    .it-info:focus-visible { outline: 2px solid var(--it); outline-offset: 2px; }
    body.it-ctx-on .it-ctx-fond { display: block; }
    body.it-ctx-on .it-ctx {
        display: flex; position: fixed; top: auto; left: 0; right: 0; bottom: 0; z-index: 95;
        max-height: min(78dvh, 620px); overflow-y: auto; scrollbar-width: thin;
        padding: 14px 16px calc(20px + env(safe-area-inset-bottom));
        background: var(--gray-100); border-top: 1.5px solid var(--it-line);
        border-radius: 20px 20px 0 0; box-shadow: 0 -14px 40px rgba(9, 30, 66, .22);
    }
    /* Ouverte, la feuille est déplacée sous <body> par interne.html : hors du
       sous-arbre animé de la page (dont le `transform` capturerait son
       ancrage), et au-dessus de la barre de navigation, comme tout tiroir. */
    /* La poignée de fermeture reste sous le pouce quand la feuille défile */
    body.it-ctx-on .it-ctx-x {
        display: inline-flex; align-items: center; justify-content: center; gap: 7px;
        position: sticky; top: 0; z-index: 1; align-self: flex-end; flex-shrink: 0;
        min-height: 40px; padding: 0 15px; border: 1.5px solid var(--it-line); border-radius: var(--radius-pill);
        background: var(--surface); box-shadow: var(--shadow-sm);
        font: inherit; font-size: 12.5px; font-weight: 800; color: var(--it-ink); cursor: pointer;
    }
    body.it-ctx-on .it-ctx-x:focus-visible { outline: 2px solid var(--it); outline-offset: 2px; }
    @media (prefers-reduced-motion: no-preference) {
        body.it-ctx-on .it-ctx { animation: it-sheet .26s cubic-bezier(.22, 1, .36, 1) both; }
        @keyframes it-sheet { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
    }
}
html[data-chrome="d"] body.it-ctx-on .it-ctx { box-shadow: 0 -14px 40px rgba(0, 0, 0, .5); }

/* La hauteur du fil est calée sur la COQUE, pas sur la grille : sous 960 px
   la coque se couche (barre du rail en haut, header sur deux ou trois
   rangées selon la largeur, navbar en bas) et la constante de 176 px du
   bureau se trompe de plus de 150 px. Aucune constante ne tient : le
   `--it-fil-h` est MESURÉ par interne.html (`calePlace`) au rendu et au
   redimensionnement, le calc n'est qu'un repli avant la première mesure. */
@media (max-width: 960px) {
    .it-page.is-a .it-fil { height: var(--it-fil-h, calc(100dvh - 286px)); min-height: 0; }
}

@media (max-width: 860px) {
    /* Une colonne, une vue à la fois */
    .it-page.is-a { grid-template-columns: minmax(0, 1fr); gap: 12px; }
    .it-rail { position: static; max-height: none; overflow: visible; }
    /* C'est la PAGE qui ancre la pilule, pas la colonne : la colonne se
       masque dès qu'une conversation s'ouvre, et la pilule serait partie
       avec elle. La page, elle, porte les deux vues. */
    .it-page.is-a { position: relative; }
    body.it-fil-on .it-rail { display: none; }

    /* LA MÊME PORTE, DANS LES DEUX MONDES (2026-08-09).
       ------------------------------------------------------------
       Cette bascule ne commande pas la messagerie : elle commande
       LEQUEL DES DEUX MONDES est ouvert. Il n'y avait aucune raison
       qu'elle change d'apparence et de place selon le monde où l'on se
       trouve. Sur téléphone elle devient donc exactement la pilule de
       l'Univers, au même endroit de l'écran, et l'objet a l'air de
       RESTER en place pendant que le monde bascule derrière lui : c'est
       la même poignée de porte des deux côtés.

       Elle est SOMBRE sur un panneau clair, et c'est voulu. Elle
       n'appartient à aucun des deux mondes, elle les sépare ; lui donner
       la peau du panneau la ferait passer pour une commande de la liste.

       SA HAUTEUR EST CELLE DE LA RANGÉE QU'ELLE CÔTOIE. Réglée à 47 px
       elle dépassait la rangée « Équipe / Dossiers » par le bas et
       pesait plus lourd qu'elle : une commande secondaire qui domine la
       navigation. Elle fait maintenant 44, comme un onglet, comme les
       deux ronds du bandeau de conversation : elle se pose DANS la
       rangée au lieu de flotter en dessous, et sa cible garde ses
       44 px de haut sans le moindre artifice.

       AUCUNE ZONE MORTE, ET PAS PAR UN DÉBORD INVISIBLE. La première
       version étendait la cible par un `::after` : mesuré au hit-test,
       un quart de la pilule restait sourd, le pseudo-élément ne
       couvrant pas ce que son `top`/`bottom` annonçait. On a donc
       retiré l'astuce : les deux boutons REMPLISSENT la pilule, bord à
       bord, sans bourrage ni gouttière entre eux. Chaque pixel de
       l'objet appartient à un bouton, par construction et non par
       calcul. Le `overflow: hidden` de la pilule taille leurs coins au
       rayon commun, et l'état pressé colore franchement sa moitié :
       c'est la grammaire d'un segmenté, en plus lisible que la petite
       pastille flottante d'avant. */
    .it-page.is-a > .it-vue {
        display: inline-flex;
        position: absolute; right: 12px; z-index: 6;
        align-items: stretch; gap: 0; margin: 0;
        grid-template-columns: none; padding: 0; border-radius: 12px; overflow: hidden;
        background: rgba(20, 26, 36, .93);
        /* LE LISERÉ EST UNE OMBRE INTERNE, PAS UNE BORDURE, et c'est ce
           qui achève de supprimer les zones mortes. Une bordure de
           1,5 px repousse les boutons vers l'intérieur : cet anneau
           n'appartient à personne, et le hit-test le confirmait
           (136 points sourds sur 805, tous sur le pourtour). En ombre
           interne, il se peint PAR-DESSUS les boutons, qui touchent
           alors le bord. Même trait à l'oeil, plus un pixel de perdu. */
        border: none;
        box-shadow: 0 6px 18px rgba(0, 0, 0, .3), inset 0 0 0 1.5px rgba(255, 255, 255, .1);
    }
    .it-page.is-a > .it-vue button {
        width: 34.5px; height: 44px; min-height: 0; padding: 0; gap: 0;
        border-radius: 0; background: none; color: rgba(255, 255, 255, .62);
        box-shadow: none;
    }
    .it-page.is-a > .it-vue button span { display: none; }
    .it-page.is-a > .it-vue svg { width: 15px; height: 15px; }
    .it-page.is-a > .it-vue button.is-on {
        background: rgba(255, 255, 255, .16); color: #fff; box-shadow: none;
    }
    .it-page.is-a > .it-vue button:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
    /* UN SEUL RETRAIT, PARCE QU'IL N'Y A PLUS QU'UNE SEULE BOÎTE.
       Les trois surfaces étant désormais à fleur d'écran et démarrant à
       la même altitude, la pilule se pose au même endroit sans qu'on ait
       à la corriger d'un écran à l'autre : elle est IMMOBILE, on bascule
       le monde sous elle. C'est tout l'intérêt d'avoir d'abord harmonisé
       les cadres. */
    .it-page.is-a > .it-vue { top: 12px; right: 12px; }
    /* ET SOUS LA PASTILLE, LE MÊME BANDEAU DES DEUX CÔTÉS (2026-08-10).
       ------------------------------------------------------------
       La pastille est posée sur la page, à 12 px du coin, immobile d'un
       écran à l'autre. Mais dans une conversation elle tombait dans un
       BANDEAU PLEIN (fond `--it-soft`, liseré bas, 67 px de haut) et
       dans la liste elle flottait au-dessus d'une simple rangée
       d'onglets, sur le fond de page : même position, deux impressions,
       intégrée d'un côté, posée là de l'autre.

       Les onglets reprennent donc EXACTEMENT la boîte de `.it-fil-h` :
       mêmes retraits (dont la réserve de 89 px pour la pastille), même
       fond, même liseré, même hauteur de 67. Les marges négatives
       annulent la gouttière du rail pour aller à fleur d'écran, comme le
       bandeau d'en face. Le retrait bas reste à ZÉRO et les onglets
       s'étirent sur toute la hauteur : c'est ce qui garde leur trait
       d'activité ACCROCHÉ au liseré du bandeau (centrés, il flotterait
       six pixels au-dessus), et cela pose leur libellé à 93,75 px du
       haut, contre 94 pour le centre de la pastille. */
    body:not(.it-fil-on) .it-rail .it-modes {
        margin: -12px calc(-1 * max(14px, env(safe-area-inset-right)))
                12px calc(-1 * max(14px, env(safe-area-inset-left)));
        min-height: var(--it-tete);
        gap: 10px;
        padding: 10px max(89px, calc(77px + env(safe-area-inset-right)))
                 0 max(14px, env(safe-area-inset-left));
        background: var(--it-soft);
        border-bottom-color: var(--it-line);
    }
    body:not(.it-fil-on) .it-fil { display: none; }
    .it-back { display: inline-flex; }
    /* DANS UNE CONVERSATION, LA PAGE NE DÉFILE PAS (2026-08-08).
       ------------------------------------------------------------
       `main.page` réserve 132 px en bas pour que le contenu ne passe pas
       sous la barre de navigation. C'est juste pour une page qui défile ;
       ici le panneau est déjà calé SUR la barre (`calePlace` lui soustrait
       sa hauteur), et les deux réserves s'additionnaient : 61 px de vide
       sous le composeur, mesurés, qu'il fallait faire défiler pour
       atteindre. Sur un téléphone où la barre d'adresse se rétracte, ces
       61 px suffisent à mettre le champ hors de vue.
       Une conversation, c'est un écran : l'en-tête en haut, les messages
       qui défilent au milieu, le composeur en bas, et rien derrière. On
       ne fait plus défiler que ce qu'on est venu lire.

       ET PUISQUE C'EST UN ÉCRAN, C'EST TOUT L'ÉCRAN (2026-08-09).
       ------------------------------------------------------------
       Le fil était une carte : 16 px de page à gauche, 16 à droite, un
       liseré, un rayon de 16 et une ombre portée. La grammaire du
       bureau, où une carte se détache d'un fond ; sur un téléphone, il
       ne reste rien autour d'elle pour la détacher de quoi que ce soit,
       et ces 34 px sortaient directement de la ligne de texte. Mesuré à
       375 : la phrase d'un message s'arrêtait à 278 px.

       Le cadre disparaît donc, et la conversation occupe la fenêtre.
       Le coin arrondi qu'on voit encore en haut n'est pas le sien :
       c'est celui de la coque, qui découpe ce qu'elle contient, et
       c'est très bien ainsi. Reste une GOUTTIÈRE de 14 px, la même pour
       l'en-tête, les messages et le champ, pour que tout s'aligne sur
       une seule verticale : « pleine largeur » ne veut pas dire du
       texte collé au bord de la vitre. Gain mesuré : 30 px de ligne.

       DEUX ÉTATS PORTENT `it-fil-on` SANS ÊTRE UNE CONVERSATION, et les
       deux se seraient retrouvés bord à bord avec leur propre cadre :
       - le formulaire « Ouvrir un canal » (`ouvreCanal` pose
         `filOuvert = true`, interne.html) injecte `.itc` dans `#itFil`,
         et `.itc` a SON liseré et SON rayon de 16 : mesuré à 375 px de
         large, coins du haut rognés, cadre doublé ;
       - l'Univers, parce que `syncVues` ne remet jamais `filOuvert` à
         faux en entrant sur le plateau : `body` peut porter `un-jeu` ET
         `it-fil-on`, et le plateau garde rayon et ombre.
       D'où les deux exclusions. Elles ne coûtent rien à la conversation,
       qui n'est jamais dans l'un de ces deux états. */
    /* LES TROIS ÉCRANS ONT LE MÊME CADRE, C'EST-À-DIRE AUCUN.
       ------------------------------------------------------------
       La conversation était pleine largeur depuis le 2026-08-09, la
       liste et le plateau restaient des cartes posées dans une
       gouttière de 16 px. Trois surfaces qui se remplacent au même
       endroit et qui n'avaient pas la même boîte : en passant de l'une
       à l'autre tout se décalait, la bascule comprise, puisqu'elle se
       mesure depuis le bord de la surface.

       Ils sont donc tous les trois à fleur d'écran, et la gouttière de
       lecture passe à l'intérieur : 14 px, la même partout, de sorte que
       les RANGÉES commencent sur la même verticale. Les textes, eux, ne
       s'alignent pas au pixel : une ligne de salon a son propre bourrage
       et un message a sa colonne d'avatar. C'est la boîte qui est
       commune, pas la première lettre.

       `:has(#itPage)` restreint la règle à cet écran : cette feuille
       est chargée par quatorze pages, et `main.page` leur appartient à
       toutes.

       LA RÉSERVE DU BAS DÉPEND DE CE QUI DÉFILE, ET LA LISTE DÉFILE.
       Premier jet : 12 px pour les trois écrans. C'était juste pour la
       conversation et pour le plateau, dont la hauteur est calée sur la
       barre de navigation et qui ne défilent pas ; c'était faux pour la
       liste. Mesuré : sa dernière conversation finissait 35 px SOUS la
       barre, et aucun défilement ne pouvait l'en sortir. Elle garde donc
       la réserve de l'app, qui vaut depuis le 2026-08-13 l'empreinte
       exacte de la barre flottante (css/expert.css) et non plus une
       constante de 132 px. */
    body:has(#itPage) main.page { padding: var(--una-cale, 0px) 0 calc(var(--mnav-h, 60px) + var(--mnav-bas, 10px) + 16px); }
    body:has(#itPage).it-fil-on main.page,
    body:has(#itPage).un-jeu main.page { padding: var(--una-cale, 0px) 0 12px; }
    /* Pas de liseré du tout : une surface à fleur d'écran ne borde rien.
       Il faut aussi que les trois boîtes commencent exactement au même
       pixel, sinon la bascule, qui se mesure depuis leur bord, se
       décalerait de l'épaisseur d'un trait d'un écran à l'autre. */
    body:has(#itPage) .it-fil,
    body:has(#itPage) .it-rail {
        border: none; border-radius: 0; box-shadow: none;
    }
    /* LE FORMULAIRE « OUVRIR UN CANAL » SUIT LA MÊME LOI. Il était exclu
       de tout ceci « pour ne pas doubler son cadre » ; mesuré, l'exclusion
       FABRIQUAIT le cadre doublé qu'elle prétendait éviter : `.it-fil` à
       16..359 avec son liseré et son rayon, `.itc` à 17..358 avec les
       siens, deux traits concentriques à un pixel l'un de l'autre. C'est
       le cadre de `.itc` qui saute : il vit déjà dans celui du fil. */
    body:has(#itPage) .itc { border: none; border-radius: 0; }
    /* La colonne prend la gouttière des messages, et son haut cale sa
       première rangée à la hauteur du bandeau d'une conversation : c'est
       ce qui permet à la bascule de ne plus bouger d'un écran à l'autre.
       EN PROPRIÉTÉS LONGUES : en raccourci, `padding` remettait le bas à
       12 px et tuait sans bruit le resserrement de la vue recherche
       (mesuré : 12 px au lieu des 4 voulus, parce que le `:has(#itPage)`
       compte un identifiant et prend le dessus). */
    body:has(#itPage) .it-rail {
        padding-top: 12px;
        padding-right: max(14px, env(safe-area-inset-right));
        padding-bottom: 12px;
        padding-left: max(14px, env(safe-area-inset-left));
    }
    /* La gouttière prend l'encoche en compte : sur un téléphone couché,
       `env()` vaut jusqu'à 44 px de ce côté-là, et 14 px de retrait
       mettraient la première lettre sous le verre noir. */
    body.it-fil-on .it-fil-h {
        padding-left: max(14px, env(safe-area-inset-left));
        /* LA PILULE OCCUPE LE COIN, LE BANDEAU LUI CÈDE LA PLACE, ET PAS
           UN PIXEL DE PLUS. Sans réserve, le bouton « i » se rangeait au
           bord droit et passait sous la pilule. Mais la première mesure
           réservait 107 px pour une pilule qui commence à 294 : 26 px
           volés au nom, qui se coupait en « Héloïse… ». Le compte juste
           est 81 (12 de retrait + 69 de pilule) plus 8 de respiration. */
        padding-right: max(89px, calc(77px + env(safe-area-inset-right)));
    }

    /* En recherche, la colonne se réduit à son champ et les
       résultats s'affichent dessous : sinon le champ disparaissait
       sous le doigt à la deuxième lettre, avec le clavier. */
    body.it-rech .it-rail .it-modes,
    body.it-rech .it-rail .it-grp,
    body.it-rech .it-rail .it-grp-l,
    body.it-rech .it-rail .ctxp-empty,
    /* La bascule part avec le reste : c'est la seule à ne plus être dans
       le flux depuis qu'elle est une pilule flottante, et elle se posait
       donc SUR le champ de recherche (mesuré, recouvrement franc). Ce
       n'est pas une exception, c'est la même règle que les cinq
       au-dessus : en recherche, la colonne se réduit à son champ. Elle
       revient dès que la requête est vidée. */
    body.it-rech .it-page.is-a > .it-vue,
    /* ELLE COUVRAIT LA CROIX DU FORMULAIRE, ENTIÈREMENT. Mesuré : sur
       vingt-cinq points de la croix « Fermer », vingt-cinq tombaient sur
       la pilule. Appuyer dessus ne fermait pas le formulaire, ça changeait
       de monde en laissant la saisie vivante derrière. Un formulaire est
       un écran à lui seul : il n'a pas besoin d'une porte vers le plateau
       dans son coin. */
    body:has(.itc) .it-page.is-a > .it-vue { display: none; }
    body:has(#itPage).it-rech .it-rail { padding-bottom: 4px; }
    body.it-rech .it-fil { display: flex; }
    body.it-rech .it-q { margin-bottom: 0; }
    /* Des résultats, ça se fait défiler avec la page, pas dans une boîte
       de 500 px sous un champ de recherche. */
    body.it-rech .it-page.is-a .it-fil { height: auto; min-height: 0; }
    body.it-rech .it-res-l { overflow: visible; }

    /* Le plateau Univers VIT aussi sur téléphone depuis 2026-08-03 : on
       y marche au doigt et on y zoome à deux ; c'est css/univers.css qui
       lui donne l'écran entier sous 861 px. */

    /* Cibles tactiles : au moins 44 px partout où l'on tape */
    .it-sal { min-height: 48px; }
    .it-mode { min-height: 44px; }
    .it-grp-t { min-height: 40px; }
    .it-cb { min-width: 44px; height: 44px; }
    .it-res { padding: 14px 12px; }
    .it-res-x, .it-fil-lien { min-height: 40px; display: inline-flex; align-items: center; }
    /* 16 px : en dessous, iOS zoome sur le champ au moment du focus
       et l'on se retrouve avec une page deux fois trop large. */
    .it-q input { min-height: 44px; font-size: 16px; }
    /* Au doigt, la porte vaut une cible pleine. Elle ne la vaut PAS sur
       bureau, et c'est voulu : hors de ce seuil le rail vit à 36 px
       (.it-sal, .it-mode) et la porte se cale sur la hauteur du champ,
       qu'elle borde. */
    .it-qmp { width: 44px; height: 44px; border-radius: 11px; }
    .it-comp textarea { font-size: 16px; }
    /* Cinq commandes du fil passaient sous les 44 px. La croix des pièces
       jointes reste petite (elle se pose sur une vignette de 64 px) mais
       étend sa zone de frappe : au doigt, on ouvrait l'image au lieu de la
       retirer. */
    .it-back { width: 44px; height: 44px; }
    .it-res-x, .it-fil-lien { min-height: 44px; }
    .it-pj-x { width: 26px; height: 26px; top: -8px; right: -8px; }
    .it-pj-x::after { content: ''; position: absolute; inset: -9px; }

    /* Le bandeau du salon et le composer */
    /* LES DEUX BANDEAUX TIENNENT LEUR HAUTEUR D'UNE SEULE SOURCE. Tant
       qu'elle était implicite (le bandeau du fil valait ce que valait
       son contenu, et la barre d'onglets un `min-height` recopié à la
       main), la première retouche de typographie les désaccordait : les
       interlignes resserrés ont fait maigrir le bandeau du fil de 1,2 px,
       et la pastille, elle, n'a pas bougé d'un cheveu. Une valeur, deux
       usages, plus de dérive. 67 px, c'est 44 de cible tactile plus
       deux fois dix de retrait, plus le liseré et demi. */
    :root { --it-tete: 67px; }
    .it-fil-h { min-height: var(--it-tete); padding: 10px 12px; gap: 10px; }
    /* LE BANDEAU DOIT TENIR SUR UNE LIGNE. Mesuré dans un privé à 375x667 :
       il montait à 202 px et ne laissait que 26 px à la conversation, une
       fente où plus aucun message n'était visible. Le retour, l'avatar, la
       pastille « Conversation privée » et le libellé « Contexte » gardaient
       leur largeur et ne laissaient que 53 px au nom, qui se cassait sur
       trois lignes. Quatre décisions.
       1. Nom et sous-titre sur une ligne chacun, coupés à l'ellipse.
          `display: block` est ce qui la rend possible : sur un conteneur
          flex, `text-overflow` ne s'applique pas. Le cadenas et la puce de
          présence reprennent donc leur marge à la main. */
    .it-fil-t b { display: block; font-size: 15px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .it-fil-t b svg { vertical-align: -2px; margin-right: 5px; }
    .it-fil-t small,
    .it-fil-h.is-mp .it-fil-t small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .it-fil-h.is-mp .it-fil-t small .it-pt { display: inline-block; margin-right: 6px; }
    /* 2. La pastille « Conversation privée » s'efface : sur une seule
          colonne elle poussait le nom hors du bandeau. Son cadenas n'est
          pas perdu pour autant, il est passé devant le nom du fil
          (interne.html), là où un salon porte déjà le sien. Ce
          commentaire disait auparavant que le bandeau du composeur
          prenait le relais : il ne le prend plus, il a été retiré le
          2026-08-09. */
    .it-fil-pv { display: none; }
    /* 3. LES DEUX RONDS DU BANDEAU SE RÉPONDENT (2026-08-08).
       ------------------------------------------------------------
       Ce qu'ils étaient : deux anneaux dépareillés. Le retour à gauche
       faisait 40 px, le contexte à droite 44 ; tous deux portaient un
       liseré clair sur un fond `--surface` qui, dans le thème sombre,
       est presque celui du bandeau. Deux traits fins posés sur du
       violet, l'un plus gros que l'autre, avec au centre une icône de
       14 px perdue dans 44 : ça ne se lisait pas comme deux commandes,
       ça se lisait comme un défaut d'alignement.

       Ce qu'ils sont : même diamètre, même matière. Un fond teinté de
       la couleur de la messagerie plutôt qu'un blanc qui disparaît,
       donc un disque qui existe dans les deux thèmes ; un liseré tiré
       de la même teinte, assez présent pour cerner le geste ; et
       l'icône passée à 18 px, la taille qu'appelle un rond de 44.
       Ils encadrent le nom de la personne, l'un ramène, l'autre
       ouvre : deux boutons de même rang, donc de même dessin. */
    .it-back, .it-info {
        width: 44px; height: 44px; min-width: 44px; min-height: 44px;
        padding: 0; border-radius: 50%; justify-content: center;
        background: color-mix(in oklab, var(--it) 15%, var(--surface));
        /* Le liseré est la limite du composant : la WCAG lui demande 3:1
           sur l'en-tête. À 38 % d'opacité il n'en tenait que 1,78 et le
           disque flottait sans contour ; à 72 % opaques, il en tient 3,2. */
        border: 1.5px solid color-mix(in oklab, var(--it) 72%, var(--surface));
        color: var(--it-ink);
    }
    .it-back svg, .it-info svg { width: 18px; height: 18px; }
    /* Les libellés se replient : « Contexte » sur son rond, « en privé »
       derrière « Envoyer », qui se cassait en deux lignes dans sa pilule.
       Les deux boutons portent un aria-label, sinon masquer le mot
       livrerait un bouton muet aux lecteurs d'écran. */
    .it-info span, .it-send-q { display: none; }
    /* Sans survol, l'appui est le seul retour possible : il enfonce. */
    .it-back:active, .it-info:active {
        background: color-mix(in oklab, var(--it) 30%, var(--surface));
        transform: scale(.94);
    }
    /* 4. La pile d'avatars et le lien « Espace client » cèdent la place : le
          lien n'est pas perdu, la feuille de contexte porte le même bouton.
          L'AVATAR DU BANDEAU part avec eux : dans un message privé, le
          visage de la personne est déjà là, devant chacun de ses messages,
          à deux centimètres en dessous. En haut il ne dit rien de plus et
          il prenait 53 px au NOM, qui se coupait. Un bandeau de
          conversation doit d'abord dire à qui l'on parle. */
    .it-fil-gens, .it-fil-lien, .it-fil-h .it-fil-ava { display: none; }
    .it-msgs {
        padding: 13px max(14px, env(safe-area-inset-right)) 13px max(14px, env(safe-area-inset-left));
    }
    .it-msg-img img { max-width: 100%; }
    /* Le composer vide occupait 208 px pour 84 px de conversation : sur un
       petit téléphone, le champ de saisie était deux fois plus grand que ce
       qu'on était venu lire. Il rend une soixantaine de pixels sans rien
       perdre de son garde-fou. */
    .it-comp {
        padding: 8px max(14px, env(safe-area-inset-right)) 12px max(14px, env(safe-area-inset-left));
    }
    /* LE BANDEAU S'EFFACE, LE GARDE-FOU RESTE (2026-08-09).
       ------------------------------------------------------------
       Il disait « Interne · privé avec X » puis « Vous deux seulement,
       aucun client », sur deux lignes et 46 px de haut, au-dessus du
       champ. Sur un téléphone, c'est un tiers du composeur pour une
       phrase qu'on lit une fois et qu'on ne relit jamais.

       Ce qui le portait vraiment n'était pas le texte : le commentaire
       en tête de ce composeur le dit depuis le début, « l'état est
       porté par la zone de saisie elle-même ». Ce cadre violet de 2 px
       autour du champ, c'est lui le garde-fou, et il ne bouge pas. Il
       est renforcé par tout le reste de l'écran : l'app entière est
       violette, l'en-tête nomme le collègue ou le salon, l'invite dit
       « Écrire à Héloïse… » ou « Écrire dans #général… », et le nom
       accessible du bouton reste « Envoyer en privé » / « en interne ».
       Ce qui disparaît, c'est la phrase, pas l'information. */
    .it-comp-lbl { display: none; }
    /* LE CHAMP SUIT CE QU'ON ÉCRIT. Il partait à 46 px, une ligne, dans
       une messagerie où l'on écrit des paragraphes ; les 46 px repris au
       bandeau lui reviennent et le doublent. `min-height` plutôt que
       `height` : c'est la hauteur de REPOS, celle d'un champ vide, et le
       script la dépasse ligne à ligne jusqu'au plafond de 200 px, après
       quoi c'est le champ qui défile. */
    .it-comp textarea { min-height: 88px; height: auto; }
    .it-comp-foot { gap: 8px; padding: 8px 10px; }
    .it-comp .btn--it { min-height: 44px; }
    .it-stgrid { grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); }

    /* ============================================================
       L'ÉCHELLE TYPOGRAPHIQUE DU TÉLÉPHONE (2026-08-10)
       ------------------------------------------------------------
       Il n'y en avait pas. Dans tout ce bloc, trois `font-size` étaient
       déclarés : 16 px sur le champ de recherche et sur le composeur
       (l'anti-zoom d'iOS) et un `.it-fil-t b` qui DESCEND de 16 à 15.
       Les dix-sept autres tailles sont la grille du BUREAU, vue sur un
       téléphone, par un lecteur trois fois plus loin de l'écran. D'où un
       aperçu de conversation à 10,5 px et un corps de message à 13,5.

       LA PLACE NE VIENT PAS DES RANGÉES, ELLE VIENT DE L'INTERLIGNE.
       Mesuré avant : les dix-sept rangées de la liste font 48,0 px, sans
       exception, parce que leur `min-height` tactile commande, pas leur
       texte. Le nom d'un salon en 13 px héritait pourtant d'un interligne
       de 1,6, soit 20,8 px de plomb pour 13 px de lettres, sur une ligne
       qui porte `nowrap` et `ellipsis` et qui ne reviendra donc JAMAIS à
       la ligne. Resserrés à 1,25 et 1,3, le nom et l'aperçu financent
       leur propre hausse : la rangée ne bouge pas et la liste montre le
       même nombre de conversations qu'avant.

       LE SEUL POSTE QUI COÛTE VRAIMENT EST LE CORPS DU MESSAGE, et c'est
       délibéré : c'est le seul texte de ces deux écrans qu'on lit en
       phrases. Un message long y gagne une ligne, donc on défile un peu
       plus. On défile pour lire ; on ne plisse pas les yeux pour lire.

       DEUX PIÈGES VÉRIFIÉS À LA MAIN, PAS DÉDUITS :
       - `.it-neufc` est déclaré APRÈS ce bloc. Une règle `.it-neufc {}`
         écrite ici perdrait à égalité de spécificité, par ordre de
         source, et l'on croirait la valeur ignorée. D'où le préfixe
         `.it-rail`.
       - la pastille de compteur mesure 18 px de haut ; un chiffre à
         11,5 px y pose une boîte de ligne de 18,4. Elle passe à 20, ou
         le nombre déborde de son rond. Les deux valeurs sont
         indissociables.

       Et deux textes changent aussi de COULEUR : l'aperçu du dernier
       message et le séparateur de jour étaient en `--text-muted`, dont
       tokens.css dit lui-même qu'il est « réservé aux petits labels ;
       jamais pour du texte courant ». Un extrait de message est du texte
       courant.
       ============================================================ */

    /* --- La liste des conversations --- */
    .it-sal-tx b { font-size: 15px; line-height: 1.25; }
    .it-sal .it-h { font-size: 15px; }
    .it-sal-tx small { font-size: 12px; line-height: 1.3; color: var(--text-secondary); }
    .it-sal.is-mp .it-sal-tx small em { font-size: 12px; }
    .it-sal-n { min-width: 20px; height: 20px; font-size: 11.5px; }
    .it-grp-t { font-size: 12px; }
    /* 13,5 ET NON 14 : la place existait pour les deux (mesuré à 320 px,
       le cas le plus dur puisque la barre cède 89 px à la pastille, le
       contenu tient sans retour à la ligne dans les deux cas), donc ce
       n'est pas la largeur qui tranche, c'est le RANG. À 14 contre des
       noms de salon à 15, et avec une graisse 800 contre 700, l'onglet
       pesait autant que le contenu qu'il sert à trouver. */
    .it-mode { font-size: 13.5px; }
    .it-rail .it-neufc { font-size: 13.5px; }

    /* --- La conversation --- */
    .it-fil-t b { font-size: 16px; line-height: 1.3; }
    .it-fil-t small { font-size: 12.5px; }
    .it-msg-h b { font-size: 15px; line-height: 1.3; }
    .it-msg-h small { font-size: 12px; }
    .it-msg-b { font-size: 15px; line-height: 1.5; }
    .it-jour { font-size: 12px; color: var(--text-secondary); }
    .it-cb { font-size: 12px; }
    .it-comp .btn--it { font-size: 13.5px; }
}

/* Sous 480 px, le fil gagne ce que l'avatar et la pastille peuvent
   céder : la rangée de message se resserre autour de son texte. */
@media (max-width: 480px) {
    .it-fil-pv span, .it-fil-pv { font-size: 11px; }
    .it-msg { grid-template-columns: 30px minmax(0, 1fr); gap: 9px; }
    .it-msg-ava { width: 30px; height: 30px; font-size: 10.5px; border-radius: 9px; }
}

/* Téléphone couché : 375 px de haut, dont un bon tiers de chrome. Le fil
   garde son défilement interne pour que le champ de saisie reste au bord
   de l'écran plutôt qu'au bout de la conversation. */
@media (max-height: 560px) and (orientation: landscape) {
    /* La hauteur du fil reste mesurée (voir `calePlace`) : couché, il ne
       reste qu'une bande, et le plancher de 240 px assume une page qui
       défile d'un pouce plutôt qu'un composer inatteignable.

       LE CHAMP AGRANDI NE PASSE PAS ICI, ET LE FIL NE PRÉVIENT PAS.
       Debout, le champ se repose à 88 px ; couché, le fil entier ne fait
       que 244 px de haut. Mesuré avec les 88 px : en-tête 67 + composeur
       175 = 242, il restait 26 px de conversation et le bouton « Envoyer »
       finissait à 306 pour un fil qui s'arrête à 304. `overflow: hidden`
       ne le fait pas déborder, il le RETRANCHE : bouton invisible, donc
       inatteignable, sans le moindre signe. On redescend donc le repos à
       40 px (le `min-height` du bloc téléphone doit être annulé, pas
       seulement la hauteur) et l'on plafonne la croissance à 64 px, de
       quoi voir deux lignes sans jamais chasser le bouton. */
    .it-comp textarea { min-height: 40px; height: 40px; max-height: 64px; }
    body.it-ctx-on .it-ctx { max-height: 82dvh; }
}

/* ============================================================
   L'AVATAR INTERNE : LE PERSONNAGE
   Dans la messagerie d'équipe, on se montre par le bonhomme qu'on a
   composé. La couleur de la personne reste EN FOND : elle tient la
   place tant que le visage charge, puis fait le fond de la vignette,
   si bien qu'on reconnaît quelqu'un à sa couleur même de loin.

   Pas d'`overflow: hidden` ici : la pastille de présence est DANS la
   vignette et déborde volontairement de son coin. C'est le visage qui
   est carré (voir js/perso.js) et l'image qui hérite du rayon, ce qui
   revient au même sans rien couper.

   Rendu au plus proche voisin : 32 px agrandis à 54 avec interpolation
   deviennent une bouillie.
   ============================================================ */
.it-vis { position: relative; }
.it-vis img {
    position: absolute; left: 0; top: 0; width: 100%; height: 100%;
    border-radius: inherit; image-rendering: pixelated;
}

/* ============================================================
   L'ÉCRAN NE DÉFILE PAS
   Une messagerie est un poste de travail, pas un document : on doit
   pouvoir écrire sans que la colonne des salons soit partie en haut, et
   revenir au fil sans chercher où l'on en était. Le cadre est donc
   FIGÉ, et le défilement rendu aux trois zones qui en ont besoin : la
   colonne des salons, le fil, la colonne de contexte.

   La hauteur est MESURÉE (`--it-h`, posée par `calePlace()`), jamais
   calculée en dur. La coque n'a pas la même hauteur d'un écran à
   l'autre, le header se pliant en deux ou trois rangées : les
   `calc(100dvh - 176px)` d'avant se trompaient d'une centaine de
   pixels selon la page, ce qui poussait le composer sous le bord.

   Uniquement à partir de 861 px : sous ce seuil l'écran passe en une
   seule vue à la fois, avec sa propre mécanique (voir plus bas).
   ============================================================ */
@media (min-width: 861px) {
    body[data-page="interne"] .frame { overflow: hidden; }
    body[data-page="interne"] main.page { padding-bottom: 16px; }
    .it-page.is-a { height: var(--it-h, calc(100dvh - 176px)); align-items: stretch; }
    /* `min-height: 0` sur chaque colonne : sans lui, un enfant de grille
       refuse de devenir plus petit que son contenu et déborde du cadre
       au lieu de faire défiler l'intérieur. */
    .it-page.is-a > * { min-height: 0; }
    .it-rail { position: static; top: auto; max-height: none; }
    .it-page.is-a .it-fil { height: 100%; min-height: 0; }
    .it-ctx { position: static; top: auto; overflow-y: auto; scrollbar-width: thin; padding-right: 2px; }
}

/* ============================================================
   OUVRIR UN CANAL (préfixe itc-) · réservé aux administrateurs
   Les sept salons de thème sont livrés avec le produit ; une équipe
   qui vit en ouvre d'autres. Le formulaire prend LE CENTRE et non une
   fenêtre par-dessus : la colonne des salons reste lisible pendant
   qu'on choisit un nom (on y vérifie qu'on ne redouble pas un canal
   existant), et onze cases de membres ne tiennent pas dans un rail de
   270 px.
   ============================================================ */

/* Le bouton vit SOUS la liste des salons, là où l'on constate qu'il
   manque un canal. Pointillé : c'est une place à remplir, pas une
   action de plus au même rang que les salons. */
.it-neufc {
    display: flex; align-items: center; gap: 8px; width: 100%;
    margin: 2px 0 10px; padding: 8px 10px;
    border: 1.5px dashed var(--gray-300); border-radius: 10px;
    background: none; color: var(--text-secondary);
    font: inherit; font-size: 12.5px; font-weight: 700; text-align: left;
    cursor: pointer; transition: border-color .15s, color .15s, background .15s;
}
.it-neufc:hover { border-color: var(--it); color: var(--it-ink); background: var(--it-soft); }
.it-neufc:focus-visible { outline: 2px solid var(--it); outline-offset: 2px; }

.itc {
    height: 100%; overflow-y: auto; scrollbar-width: thin;
    padding: 20px 22px 24px;
    background: var(--surface); border: 1px solid var(--gray-200);
    border-radius: var(--radius);
}
.itc-h { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.itc-h h2 { font-size: 17px; font-weight: 800; color: var(--text-primary); }
.itc-x {
    margin-left: auto; width: 32px; height: 32px; display: inline-flex;
    align-items: center; justify-content: center;
    border: none; border-radius: 50%; background: none;
    color: var(--text-muted); cursor: pointer; transition: background .15s, color .15s;
}
.itc-x:hover { background: var(--gray-100); color: var(--text-primary); }
.itc-x:focus-visible { outline: 2px solid var(--it); outline-offset: 1px; }
.itc-intro { font-size: 13px; line-height: 1.55; color: var(--text-secondary); margin-bottom: 20px; max-width: 56ch; }

.itc-champ { margin-bottom: 20px; max-width: 560px; }
.itc-champ > label, .itc-lab {
    display: block; margin-bottom: 6px;
    font-size: 12px; font-weight: 800; letter-spacing: .03em; text-transform: uppercase;
    color: var(--text-secondary);
}
.itc-lab i { font-style: normal; font-weight: 700; text-transform: none; letter-spacing: 0; color: var(--text-muted); }
.itc-champ small { display: block; margin-top: 6px; font-size: 12px; color: var(--text-secondary); line-height: 1.5; }
.itc-champ small b { font-weight: 800; color: var(--it-ink); }
.itc-champ input[type="text"], .itc-champ select {
    width: 100%; height: 40px; padding: 0 12px;
    border: 1.5px solid var(--gray-300); border-radius: 10px;
    background: var(--surface); color: var(--text-primary); font: inherit; font-size: 14px;
}
.itc-champ input[type="text"]:hover, .itc-champ select:hover { border-color: var(--it); }
.itc-champ input[type="text"]:focus-visible, .itc-champ select:focus-visible {
    outline: 2px solid var(--it); outline-offset: 1px; border-color: var(--it);
}
/* Le dièse est DANS le champ : il rappelle qu'on nomme un canal, pas
   une personne, et il est là où le nom va s'écrire. */
.itc-slug { position: relative; }
.itc-slug span {
    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
    font-size: 15px; font-weight: 800; color: var(--text-muted); pointer-events: none;
}
.itc-slug input { padding-left: 26px !important; }
.itc-vide { font-size: 12.5px; color: var(--text-secondary); line-height: 1.5; }

.itc-tous { display: flex; gap: 6px; margin-bottom: 8px; }
.itc-mini {
    height: 28px; padding: 0 11px; border: 1.5px solid var(--gray-300); border-radius: var(--radius-pill);
    background: var(--surface); color: var(--text-secondary);
    font: inherit; font-size: 12px; font-weight: 700; cursor: pointer; transition: border-color .15s, color .15s;
}
.itc-mini:hover { border-color: var(--it); color: var(--it-ink); }
.itc-mini:focus-visible { outline: 2px solid var(--it); outline-offset: 2px; }

/* Deux colonnes : onze membres en une file font défiler le formulaire
   pour rien, et l'on veut voir l'équipe entière d'un coup d'œil. */
.itc-gens { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 4px; }
.itc-gen {
    display: flex; align-items: center; gap: 9px; padding: 7px 10px;
    border: 1.5px solid transparent; border-radius: 10px; cursor: pointer;
    transition: background .15s, border-color .15s;
}
.itc-gen:hover { background: var(--gray-100); }
.itc-gen.is-on { background: var(--it-soft); border-color: color-mix(in srgb, var(--it) 26%, transparent); }
.itc-gen.is-moi { cursor: default; opacity: .8; }
.itc-gen input { width: 17px; height: 17px; accent-color: var(--it); cursor: pointer; flex-shrink: 0; }
.itc-gen input:disabled { cursor: default; }
.itc-gen input:focus-visible { outline: 2px solid var(--it); outline-offset: 2px; }
.itc-ava {
    width: 28px; height: 28px; flex-shrink: 0; border-radius: 9px; overflow: hidden;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 10.5px; font-weight: 800; color: #fff;
}
.itc-gen-tx { min-width: 0; display: flex; flex-direction: column; }
.itc-gen-tx b { font-size: 12.5px; font-weight: 700; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.itc-gen-tx small { font-size: 11px; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.itc-err {
    margin-bottom: 12px; padding: 9px 12px; border-radius: 10px;
    background: var(--orange-soft); color: var(--orange-ink);
    font-size: 12.5px; font-weight: 700;
}
.itc-err[hidden] { display: none; }
.itc-f { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding-top: 4px; }
.itc-f .btn--primary { background: var(--it); }
.itc-f .btn--primary:hover { background: var(--it-ink); }
/* Fermer un canal efface ses messages : l'action est à part, en bout de
   ligne, et passe par une confirmation. */
.itc-sup {
    margin-left: auto; border: none; background: none; padding: 6px 8px;
    font: inherit; font-size: 12.5px; font-weight: 700; color: var(--danger-ink, #B4342A);
    text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
/* Assombrir/éclaircir le jeton plutôt que figer un rouge : `--danger-ink`
   est défini dans les DEUX thèmes, et le #8E2820 d'un rouge clair tombait
   à 1,8:1 sur le fond sombre, juste au moment du survol. */
.itc-sup:hover { color: color-mix(in srgb, var(--danger-ink) 78%, var(--text-primary)); }
.itc-sup:focus-visible { outline: 2px solid var(--it); outline-offset: 2px; border-radius: 6px; }

/* La carte du canal, dans la colonne de contexte */
.it-canc-s { font-size: 12.5px; color: var(--text-secondary); line-height: 1.5; margin-bottom: 8px; }
.it-canc-s i, .it-canc-b i { color: var(--text-muted); }
.it-canc-b { display: flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 700; color: var(--text-primary); }
.it-canc-e { margin-top: 12px; width: 100%; justify-content: center; }

/* Le mot qui passe */
.it-toast {
    position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 12px);
    z-index: 200; max-width: min(460px, calc(100vw - 32px));
    padding: 11px 18px; border-radius: var(--radius-pill);
    background: var(--text-primary); color: var(--surface);
    font-size: 13px; font-weight: 700; text-align: center;
    box-shadow: var(--shadow-lg);
    opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s cubic-bezier(.22, 1, .36, 1);
}
.it-toast.is-on { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) { .it-toast { transition: opacity .01ms; } }

/* ============================================================
   LES GESTES D'UN MESSAGE (2026-08-19)
   ------------------------------------------------------------
   Réagir, répondre, transférer, corriger, copier, épingler, mettre de
   côté. Deux surfaces : une BARRE au survol pour ce qu'on fait dix
   fois par jour, un MENU sous « ⋯ » pour le reste.

   LA BARRE FLOTTE SUR LE MESSAGE, en haut à droite, et ne pousse rien :
   posée dans le flux, elle ferait sauter tout le fil d'une ligne à
   chaque survol. Elle apparaît au survol ET au focus interne : au
   clavier, une barre qui n'existe qu'à la souris n'existe pas.
   ============================================================ */
.it-msg { position: relative; }
.it-gestes {
    position: absolute; top: -12px; right: 0; z-index: 2;
    display: flex; align-items: center; gap: 2px; padding: 3px;
    background: var(--surface); border: 1px solid var(--gray-200); border-radius: 12px;
    box-shadow: 0 6px 18px -8px rgba(9, 30, 66, .35);
    opacity: 0; pointer-events: none;
}
.it-msg:hover .it-gestes,
.it-gestes:focus-within { opacity: 1; pointer-events: auto; }
@media (prefers-reduced-motion: no-preference) {
    .it-gestes { transition: opacity .12s; }
}
/* Sous le doigt, il n'y a pas de survol : la barre est là en
   permanence, discrète, plutôt qu'inatteignable. */
@media (pointer: coarse) {
    .it-gestes { opacity: 1; pointer-events: auto; position: static; margin-top: 6px; align-self: flex-start; width: fit-content; }
    .it-g { min-width: 44px; min-height: 44px; }
}
.it-g {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border: 0; border-radius: 9px;
    background: none; color: var(--text-secondary); cursor: pointer; font-size: 15px; line-height: 1;
}
.it-g:hover { background: var(--it-pale, #F1EEFC); color: var(--it-encre, #5A46C8); }
.it-g:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.it-g--e { font-size: 16px; }
.it-g-sep { width: 1px; height: 18px; margin: 0 2px; background: var(--gray-200); }

/* Les réactions posées, sous le message : une pastille par icône, son
   compte à côté. La mienne se distingue par son LISERÉ et son fond, pas
   par la seule couleur du chiffre. */
.it-reacs { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
.it-reac {
    display: inline-flex; align-items: center; gap: 5px;
    min-height: 26px; padding: 0 9px; border-radius: var(--radius-pill);
    border: 1.5px solid var(--gray-200); background: var(--gray-100);
    font: inherit; font-size: 13px; color: var(--text-secondary); cursor: pointer;
}
.it-reac:hover { border-color: var(--it-encre, #5A46C8); }
.it-reac:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.it-reac b { font-size: 11.5px; font-weight: 800; font-variant-numeric: tabular-nums; }
.it-reac.is-moi { border-color: var(--it-encre, #5A46C8); background: var(--it-pale, #F1EEFC); color: var(--it-encre, #5A46C8); }
.it-reac-e { display: inline-flex; align-items: center; font-size: 14px; line-height: 1; }
.it-reac--plus { padding: 0 7px; color: var(--text-muted); }
.it-reacs .emo-img, .it-gestes .emo-img, .it-mm .emo-img { width: 16px; height: 16px; object-fit: contain; display: block; }

/* La citation d'une réponse, au-dessus du message : plus petite, en
   retrait, et cliquable pour remonter à l'original. */
.it-rep-q {
    display: flex; align-items: center; gap: 6px; max-width: 100%; margin-bottom: 3px;
    padding: 2px 6px 2px 2px; border: 0; border-radius: 8px; background: none;
    font: inherit; font-size: 12px; color: var(--text-muted); text-align: left; cursor: pointer;
}
.it-rep-q:hover { background: var(--gray-100); }
.it-rep-q:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.it-rep-q b { flex: none; font-weight: 800; color: var(--it-encre, #5A46C8); }
.it-rep-q span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.it-rep-q.is-perdu { font-style: italic; cursor: default; padding-left: 6px; }
.it-rep-ava { width: 16px; height: 16px; border-radius: 5px; color: #fff; font-size: 8px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; flex: none; }
/* Le trait qui relie la citation au message, comme un fil qu'on remonte */
.it-rep-q::before {
    content: ''; flex: none; width: 14px; height: 8px; margin-left: 2px;
    border-left: 1.5px solid var(--gray-300); border-top: 1.5px solid var(--gray-300);
    border-top-left-radius: 6px; align-self: flex-end;
}

/* La provenance d'un message transféré */
.it-trans-src {
    display: flex; align-items: center; gap: 5px; margin: 2px 0 4px;
    font-size: 11.5px; color: var(--text-muted);
}
.it-trans-src b { font-weight: 800; color: var(--text-secondary); }
/* Quand elle mène quelque part, elle le montre : c'est un bouton, il se
   survole, il prend le focus, et la flèche paraît au survol pour ne pas
   charger une ligne qui est d'abord une mention de provenance. */
button.it-trans-src {
    border: 0; background: none; font: inherit; font-size: 11.5px;
    padding: 2px 6px 2px 0; margin-left: -0; border-radius: 8px; cursor: pointer; text-align: left;
}
button.it-trans-src:hover { color: var(--blue-dark); background: var(--blue-pale); padding-left: 6px; }
button.it-trans-src:hover b { color: var(--blue-dark); }
button.it-trans-src:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.it-trans-go { display: inline-flex; opacity: 0; transform: scaleX(-1); }
button.it-trans-src:hover .it-trans-go, button.it-trans-src:focus-visible .it-trans-go { opacity: 1; }
@media (pointer: coarse) {
    /* Sous le doigt il n'y a pas de survol : la flèche reste, et la ligne
       fait la hauteur d'une vraie cible. */
    button.it-trans-src { min-height: 44px; padding-left: 6px; }
    .it-trans-go { opacity: 1; }
}

/* ============================================================
   L'ANNONCE D'UNE VICTOIRE, DANS LE FIL (2026-08-20)
   ------------------------------------------------------------
   LE DESSIN N'EST PAS ICI. La carte est celle de la fête, empruntée
   à js/fanfare.js (`__FANFARE.carte`), qui injecte sa propre feuille :
   deux dessins pour un seul objet avaient divergé en une journée.
   Il ne reste ici que ce qui appartient au FIL : la largeur d'un
   message, et le fait qu'embarquée la carte n'a ni croix ni rangée
   de réactions (le message a déjà la sienne, dessous).
   ============================================================ */
.it-deal { max-width: 430px; margin-top: 4px; }
.it-deal .fanf-ce {
    width: 100%;
    /* Plus courte que la carte plein écran : dans un fil on lit une
       suite de messages, pas une carte de 520 px chacun. Les
       proportions internes, elles, sont les mêmes. */
    min-height: 400px;
    margin-top: 0;
    box-shadow: 0 12px 30px -12px rgba(9, 30, 66, .4);
}
@media (max-width: 560px) { .it-deal { max-width: none; } }

/* La marque d'un message corrigé : discrète, mais jamais absente */
.it-edite { font-style: normal; font-size: 11px; color: var(--text-muted); margin-left: 5px; }

/* Le champ de correction, à la place du corps */
.it-edit { margin-top: 2px; }
.it-edit-in {
    width: 100%; max-width: 78ch; min-height: 62px; padding: 9px 11px; resize: vertical;
    border: 1.5px solid var(--it-encre, #5A46C8); border-radius: 11px;
    background: var(--surface); color: var(--text-primary); font: inherit; font-size: 13.5px; line-height: 1.55;
}
.it-edit-in:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.it-edit-b { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 7px; }
.it-edit-b small { font-size: 11px; color: var(--text-muted); }

/* Le bandeau de réponse, dans le composeur */
.it-repb {
    display: flex; align-items: center; gap: 8px; margin-bottom: 7px;
    padding: 7px 9px; border-radius: 11px;
    background: var(--it-pale, #F1EEFC); color: var(--it-encre, #5A46C8);
}
.it-repb-t { flex: 1; min-width: 0; display: flex; flex-direction: column; font-size: 12px; }
.it-repb-t b { font-weight: 800; }
.it-repb-t span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-secondary); }
.it-repb-x {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border: 0; border-radius: 8px; background: none;
    color: var(--it-encre, #5A46C8); cursor: pointer;
}
.it-repb-x:hover { background: rgba(90, 70, 200, .14); }
.it-repb-x:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }

/* Le menu « ⋯ » et le choix du salon de transfert : même boîte, posée
   sur la fenêtre pour sortir du fil qui déborde. */
.it-mm {
    position: fixed; z-index: 96; min-width: 236px; max-width: 300px; padding: 5px;
    background: var(--surface); border: 1px solid var(--gray-200); border-radius: 13px;
    box-shadow: 0 18px 44px -14px rgba(9, 30, 66, .4);
}
.it-mm-rapides { display: flex; gap: 3px; padding: 3px 2px 6px; }
.it-mm-rapides button {
    flex: 1; display: inline-flex; align-items: center; justify-content: center;
    min-height: 38px; border: 0; border-radius: 10px; background: var(--gray-100);
    font-size: 19px; line-height: 1; cursor: pointer;
}
.it-mm-rapides button:hover { background: var(--it-pale, #F1EEFC); }
.it-mm-rapides button:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.it-mm-i {
    display: flex; align-items: center; gap: 11px; width: 100%; min-height: 38px; padding: 7px 9px;
    border: 0; border-radius: 9px; background: none; cursor: pointer;
    font: inherit; font-size: 13.5px; color: var(--text-primary); text-align: left;
}
.it-mm-i svg { flex: none; color: var(--text-secondary); }
.it-mm-i:hover { background: var(--it-pale, #F1EEFC); }
.it-mm-i:hover svg { color: var(--it-encre, #5A46C8); }
.it-mm-i:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.it-mm-h { flex: none; width: 15px; text-align: center; font-weight: 800; color: var(--text-secondary); }
.it-mm-sep { height: 1px; margin: 4px 6px; background: var(--gray-200); }
.it-mm-t { padding: 6px 9px 4px; font-size: 11.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); }
.it-mm-vide { padding: 8px 9px 10px; font-size: 12.5px; color: var(--text-secondary); }
/* SOUS LE DOIGT, TOUT CE QUI SE TOUCHE FAIT 44 px. Quatre cibles neuves
   y échappaient, dont LA PLUS FRÉQUENTE de la fonctionnalité : la
   pastille de réaction, à 26 px, qu'on vise pour retirer sa réaction. */
@media (pointer: coarse) {
    .it-mm-i { min-height: 44px; }
    .it-mm-rapides button { min-height: 44px; }
    .it-reac { min-height: 44px; padding: 0 13px; }
    .it-reac--plus { padding: 0 12px; }
    .it-repb-x { width: 44px; height: 44px; }
    .it-rep-q { min-height: 44px; }
}
/* La liste des destinations : un champ de recherche, puis les lignes qui
   défilent. Le menu est déjà borné en largeur, il l'est ici en hauteur. */
.it-mm-q { padding: 2px 4px 6px; }
.it-mm-q input {
    width: 100%; min-height: 34px; padding: 0 10px;
    border: 1.5px solid var(--gray-300); border-radius: 9px;
    background: var(--surface); color: var(--text-primary); font: inherit; font-size: 13px;
}
.it-mm-q input:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; border-color: var(--blue); }
.it-mm-l { max-height: 244px; overflow-y: auto; scrollbar-width: thin; }
.it-mm-t span {
    display: inline-block; margin-left: 4px; padding: 0 6px; border-radius: var(--radius-pill);
    background: var(--gray-200); color: var(--text-secondary); font-variant-numeric: tabular-nums;
}
/* Un raccourci déjà posé se voit AVANT qu'on le reclique : il bascule,
   et sans marque on retirait sa réaction en croyant l'ajouter. */
.it-g--e.is-moi { background: var(--it-pale, #F1EEFC); box-shadow: inset 0 0 0 1.5px var(--it-encre, #5A46C8); }

/* Un message mis de côté : la même étiquette que l'épingle, une autre
   couleur, et le mot qui la distingue. */
.it-tag-ep.is-sig { color: var(--blue-dark); background: var(--blue-pale); }

/* ============================================================
   LE SÉLECTEUR D'ICÔNES PARTAGÉ (js/emojis.js)
   ------------------------------------------------------------
   Il vit dans <body>, en `fixed` : le fil des messages déborde, et un
   panneau posé dedans y serait rogné. Sa grille est la même que celle
   des icônes de page de Notion, à la mesure près.
   ============================================================ */
.emo-p {
    position: fixed; z-index: 97; width: 296px; max-height: 340px; overflow-y: auto; scrollbar-width: thin;
    padding: 8px; background: var(--surface); border: 1px solid var(--gray-200); border-radius: 14px;
    box-shadow: 0 18px 44px -14px rgba(9, 30, 66, .4);
}
.emo-t { padding: 4px 4px 5px; font-size: 11px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); }
.emo-t + .emo-t, .emo-grille + .emo-t, .emo-objets + .emo-t { margin-top: 6px; }
.emo-grille { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; }
.emo-objets { display: grid; grid-template-columns: repeat(6, 1fr); gap: 2px; }
.emo-p button {
    display: inline-flex; align-items: center; justify-content: center;
    aspect-ratio: 1; border: 0; border-radius: 9px; background: none;
    font-size: 18px; line-height: 1; cursor: pointer; padding: 0;
}
.emo-p button:hover { background: var(--it-pale, #F1EEFC); }
.emo-p button:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.emo-objets img { width: 24px; height: 24px; object-fit: contain; display: block; }
.emo-rien {
    display: block; width: 100%; aspect-ratio: auto; min-height: 36px; margin-top: 6px;
    font-size: 13px; color: var(--text-secondary); border-top: 1px solid var(--gray-200); border-radius: 0;
}
