/* La messagerie client ⇄ CSM (2026-08-23).
   Un seul fichier pour les trois surfaces : la bulle flottante, la page
   « Messages » du client, et le panneau de /team/messages. Les trois partagent
   le fragment `partials/chat_fil.html`, donc elles partagent ses classes.

   /!\ Chargé sur TOUTES les pages (la bulle est dans `admin_base.html`), donc
   tenu court : pas de règle qui déborde sur autre chose que `.chat-*`. */

/* ── La bulle flottante ──────────────────────────────────────────────────── */

/* /!\ REPRISE DU STYLE le 2026-08-23 au soir, sur demande du fondateur, en même
   temps que le RETRAIT du déplacement (« finalement c'était mieux fixe »). La
   bulle était posée à côté de la charte plutôt que dedans : un rond d'aplat
   violet, un panneau à l'arrondi de 14 px qu'aucun autre écran n'emploie, un
   en-tête sans surface, et un champ de saisie qui ne ressemblait à aucun des
   champs de l'application. Elle empruntait des COULEURS à la charte sans en
   emprunter les FORMES.

   Ce qui change, et pourquoi :
   1. Le lanceur prend l'habit du geste principal (`.btn-primary` : violet lavé,
      liseré violet), plus sa lueur — pas un aplat plein qui crie plus fort que
      tout le reste de l'écran. Ouvert, il redevient un simple bouton de
      fermeture : la couleur appartient alors au panneau.
   2. Le panneau prend `--radius-xl`, l'arrondi que la charte réserve à « une
      grande carte posée sur le fond » : c'est exactement ce qu'il est.
   3. L'en-tête reçoit une surface teintée, un liseré d'accent en haut et un
      médaillon d'icône, comme la tuile `.chiffre` et `.vide-accueil-marque` :
      c'est ce qui fait qu'un panneau est POSÉ sur la page au lieu d'y flotter.
   4. Le composeur devient UNE surface (le champ et ses deux gestes dans la même
      boîte, qui s'allume au focus) au lieu d'un champ suivi d'une rangée de
      boutons dans le vide.

   /!\ Chargé sur TOUTES les pages (la bulle est dans `admin_base.html`), donc
   tenu court : pas de règle qui déborde sur autre chose que `.chat-*`. */

/* /!\ `.toast-stack` occupait déjà bottom:24px right:24px. Il remonte au-dessus
   du lanceur dans `admin_base.html` : sans ça, un toast s'affiche SOUS la bulle
   et devient incliquable. */
.chat-lanceur {
  box-sizing: border-box;
  position: fixed; bottom: 24px; right: 24px; z-index: 150;
  width: 54px; height: 54px; border-radius: 50%;
  background: rgba(167,139,250,0.18);
  color: var(--accent);
  border: 1px solid rgba(167,139,250,0.30);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 10px 30px -8px var(--accent-glow), 0 2px 8px rgba(0,0,0,.35);
  transition: transform var(--motion-base) var(--ease-out),
              background var(--motion-base) var(--ease-out),
              border-color var(--motion-base) var(--ease-out),
              color var(--motion-base) var(--ease-out),
              box-shadow var(--motion-base) var(--ease-out);
}
.chat-lanceur:hover {
  background: rgba(167,139,250,0.28);
  border-color: rgba(167,139,250,0.50);
  color: #FFFFFF;
  box-shadow: 0 14px 34px -8px var(--accent-glow-strong), 0 2px 8px rgba(0,0,0,.35);
}
.chat-lanceur:focus-visible { outline: 2px solid var(--ring); outline-offset: 3px; }
/* Le seul MOUVEMENT, et il est conditionnel — la règle que la charte pose pour
   ses tuiles : la préférence demande de ne pas faire BOUGER, pas de rendre
   inerte. La lumière reste pour tout le monde. */
@media (prefers-reduced-motion: no-preference) {
  .chat-lanceur:hover { transform: translateY(-2px); }
}
.chat-lanceur .chat-fermer-icone { display: none; }
.chat-ouvert .chat-lanceur .chat-fermer-icone { display: block; }
.chat-ouvert .chat-lanceur .chat-ouvrir-icone { display: none; }
/* Ouverte, la bulle n'appelle plus : deux surfaces violettes l'une sur l'autre
   se concurrencent, et c'est le panneau qu'on vient regarder. */
.chat-ouvert .chat-lanceur {
  background: var(--muted);
  border-color: var(--border-strong);
  color: var(--muted-foreground);
  box-shadow: 0 4px 14px rgba(0,0,0,.35);
}
.chat-ouvert .chat-lanceur:hover {
  background: var(--muted); color: var(--foreground);
  border-color: rgba(255,255,255,0.24);
  box-shadow: 0 6px 18px rgba(0,0,0,.40);
}

/* /!\ Positionnement NON absolu par defaut : la meme pastille sert dans le
   lanceur (qui est `position:fixed`, donc un ancetre positionne) ET dans
   l'entree de menu, dont le lien ne l'est pas. En absolu partout, elle
   s'echappait vers un ancetre quelconque et flottait au milieu de l'ecran. */
.chat-pastille {
  display: inline-block;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 999px; background: var(--error); color: #fff;
  font-size: var(--text-2xs); font-weight: 700; line-height: 18px; text-align: center;
}
/* /!\ **SUR LE LANCEUR, ELLE EST POSÉE, PAS COINCÉE** (fondateur, 2026-09-18 :
   « l'affichage du 1 n'est pas top »). À 18 px collée au bord, en `--error`
   saumon, elle se lisait comme un défaut de l'écran : un chiffre écrasé sur un
   contour. Elle grandit, sort franchement du cercle, centre son chiffre en flex
   (la hauteur de ligne décentrait « 1 ») et prend un rouge FRANC qui tient à
   côté du violet — le saumon s'y fondait. */
.chat-lanceur .chat-pastille {
  position: absolute; top: -6px; right: -6px;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 6px; box-sizing: border-box;
  background: #ef4444;
  font-size: calc(12px * var(--echelle-texte)); line-height: 1; font-variant-numeric: tabular-nums;
  border: 2px solid var(--background);
  box-shadow: 0 2px 6px rgba(0,0,0,.45);
}

/* ── LE LANCEUR APPELLE QUAND IL PORTE DES NON-LUS (fondateur, 2026-09-15) ──
   « il faudrait que le client puisse [voir] lorsqu'il a reçu une réponse
   facilement si le chat est refermé ».

   /!\ **LA PASTILLE EXISTAIT DÉJÀ, ET ELLE N'ÉTAIT PAS LE DÉFAUT.** Ce qui
   manquait vivait dans `chat_bulle.html` : le `load` du panneau partait même
   bulle FERMÉE, `/messagerie/fil` marquait lu, et le compteur retombait à zéro
   avant que quiconque ait rien vu. Ces deux règles-ci ne font que rendre le
   signal visible du coin de l'œil, sur un écran que le client ne regarde pas.

   /!\ **`:has()` EST UN CONFORT, PAS UNE DÉPENDANCE** : sans lui on retombe sur
   la pastille seule, qui suffit déjà — jamais sur un écran cassé. Même usage que
   `.chat-messages:has(.chat-vide)` plus bas.

   /!\ **ET LE MOUVEMENT RESTE CONDITIONNEL**, comme partout dans la charte : la
   préférence demande de ne pas faire BOUGER, pas de rendre muet. Le liseré
   d'alerte, lui, reste pour tout le monde. */
/* /!\ **LE CERCLE RESTE VIOLET** (2026-09-18) : il passait au rouge, contour et
   halo compris, et trois rouges empilés disaient « erreur », pas « réponse
   arrivée ». Le rouge est à la pastille seule ; le lanceur, lui, s'ALLUME dans
   la couleur de l'app. */
#chat-bulle:not(.chat-ouvert) .chat-lanceur:has(.chat-pastille) {
  background: rgba(167,139,250,0.28);
  border-color: var(--accent);
  box-shadow: 0 10px 30px -8px var(--accent-glow), 0 0 0 3px rgba(167,139,250,0.18);
}
@media (prefers-reduced-motion: no-preference) {
  #chat-bulle:not(.chat-ouvert) .chat-lanceur:has(.chat-pastille) { animation: chat-appel 2.4s var(--ease-out) infinite; }
}
@keyframes chat-appel {
  0%, 72%, 100% { box-shadow: 0 10px 30px -8px var(--accent-glow), 0 0 0 3px rgba(167,139,250,0.18); }
  86%           { box-shadow: 0 10px 30px -8px var(--accent-glow), 0 0 0 10px rgba(167,139,250,0); }
}

/* /!\ ANCRÉ EN BAS À DROITE, et plus déplaçable (2026-08-23 au soir). Les quatre
   côtés ne sont donc plus jamais réécrits par un script : la boîte garde sa
   place et ses dimensions, quoi qu'il arrive.
   /!\ La hauteur passe par `--fenetre` et non `100vh` : la charte applique un
   `zoom: 1.1` au corps, et un `100vh` nu déborde de l'écran de 10 %.
   /!\ LA LARGEUR A EXACTEMENT LE MÊME PIÈGE, et il était là depuis l'origine.
   MESURÉ le 2026-08-23 (`getComputedStyle` dans un vrai navigateur, pas déduit
   du CSS) : `100vw` rend la largeur BRUTE de la fenêtre, sans tenir compte du
   `zoom`, alors que la longueur qu'on écrit ici est ensuite multipliée par 1,1
   au rendu. `calc(100vw - 32px)` sur un téléphone de 360 donnait donc un
   plafond de 361 px d'écran, plus 26 px de décalage à droite : le panneau
   dépassait. La division par `--echelle` remet les deux dans la même unité. */
.chat-panneau {
  box-sizing: border-box;
  position: fixed; bottom: 92px; right: 24px; z-index: 150;
  width: 384px; max-width: calc(100vw / var(--echelle) - 32px);
  /* /!\ **520, ET LA HAUTEUR N'ETAIT PAS LE VRAI DEFAUT** (2026-09-14). Le
     panneau paraissait vide apres le retrait de la carte de rendez-vous ; j'ai
     d'abord raccourci a 480, et l'accueil s'est retrouve coupe. La vraie cause
     etait ailleurs, et elle est corrigee a cote : `defiler()` collait le fil en
     bas MEME VIDE, ce qui poussait l'invitation et la barre « qui repond » hors
     du cadre. 540 est ce qui loge l'ensemble sans slack : en-tete, barre d'etat,
     accueil, trois questions rapides et la saisie. Mesure a l'ecran. */
  height: 540px; max-height: calc(var(--fenetre) - 140px);
  background: var(--card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-xl); overflow: hidden;
  box-shadow: 0 28px 70px -14px rgba(0,0,0,.62), 0 4px 14px rgba(0,0,0,.35);
  display: none; flex-direction: column;
}
.chat-ouvert .chat-panneau { display: flex; }

/* SUR UN TÉLÉPHONE, le panneau s'ancre aux DEUX bords et n'a plus de largeur
   propre.
   /!\ C'est volontairement `left` + `right` + `width: auto`, et non un
   `max-width` calculé : deux ancrages se résolvent forcément dans la même unité
   que la largeur qu'ils déterminent, quel que soit le `zoom` de la charte —
   alors qu'une formule sur `100vw` mélange deux unités (voir le bloc ci-dessus).
   /!\ CE BRANCHEMENT N'A PAS ÉTÉ VU À L'ÉCRAN, et il faut le dire : Chrome en
   mode « headless » plafonne sa fenêtre à 500 px de large, donc la capture
   d'une fenêtre de 390 px est un simple RECADRAGE d'un rendu de 500 — la
   requête média n'y déclenche jamais. À recetter sur un vrai téléphone. */
@media (max-width: 480px) {
  /* /!\ **PLEIN ÉCRAN SUR TÉLÉPHONE** (A4b, 23/09/2026, décision 1) : la liste
     des conversations et le fil s'y lisent comme une application, la croix de
     l'en-tête ferme. Le lanceur se cache tant que la bulle est ouverte : il
     recouvrirait le composeur. `env(safe-area-inset-*)` : l'encoche et la
     barre du bas du téléphone ne mangent ni l'en-tête ni la saisie. */
  .chat-panneau {
    left: 0; right: 0; top: 0; bottom: 0; width: auto; max-width: none;
    height: auto; max-height: none; border-radius: 0; border: 0;
    padding-top: env(safe-area-inset-top, 0px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .chat-ouvert .chat-lanceur { display: none; }
}

/* L'EN-TÊTE : une surface teintée, un liseré d'accent, un médaillon.
   /!\ Le liseré s'éteint vers la droite : un trait plein d'un bord à l'autre
   ferait une barre de titre de fenêtre — et le panneau n'en est plus une. */
.chat-entete {
  position: relative;
  padding: 13px 14px; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 11px; flex-shrink: 0;
  background: linear-gradient(158deg,
              rgba(180,168,255,0.10) 0%, rgba(255,255,255,0.015) 70%);
}
.chat-entete::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--accent) 0%, rgba(180,168,255,0.10) 100%);
}
/* Le médaillon, calqué sur `.vide-accueil-marque` de la charte, en plus petit. */
.chat-marque {
  width: 32px; height: 32px; flex: 0 0 32px; border-radius: var(--radius-lg);
  display: inline-flex; align-items: center; justify-content: center;
  background: rgb(180 168 255 / 0.12); border: 1px solid rgb(180 168 255 / 0.22);
  color: var(--accent);
}
/* /!\ `flex: 1` POUSSE LE RESTE À DROITE, et c'est ce qui laisse la porte du
   rendez-vous et la croix cohabiter sans se coller au prénom. Sans lui, les deux
   se rangeaient contre le texte et le `margin-left: auto` de la croix seule
   décidait de tout. */
.chat-qui { min-width: 0; flex: 1; }
/* /!\ **UNE LIGNE CHACUNE, ET ELLES SE COUPENT.** L'en-tête faisait quatre
   lignes dès que la porte du rendez-vous est venue prendre sa place à droite :
   « Marlène, votre assistant » se pliait en deux, la phrase du dessous aussi, et
   le panneau perdait quarante points de fil. Vu à l'écran le 2026-09-14.
   /!\ `min-width: 0` sur `.chat-qui` (juste au-dessus) est ce qui AUTORISE la
   coupure : sans lui, un enfant de flex refuse de descendre sous sa largeur de
   contenu, et `text-overflow` ne se déclenche jamais. */
.chat-entete b, .chat-entete p {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chat-entete b { display: block; font-size: var(--text-base); font-weight: 600; }
.chat-entete p { margin: 2px 0 0; font-size: var(--text-xs); color: var(--muted-foreground); }

/* ── La porte du rendez-vous, dans l'en-tête (fondateur, 2026-09-14) ────────
   /!\ **DISCRÈTE, PAS UN APPEL À L'ACTION.** Elle remplace une carte qui
   occupait le tiers haut de la bulle et qu'il a fait retirer. Un bouton plein
   d'accent ici referait, en plus petit, exactement ce qu'il n'a pas voulu :
   c'est la messagerie qu'on vient ouvrir, pas un agenda.
   /!\ Le libellé disparaît en dessous de 380 px de bulle : sur un téléphone,
   l'icône seule tient à côté d'un prénom, la paire non. */
.chat-entete-rdv {
  flex: none; display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 9px; border-radius: var(--radius-md);
  background: rgb(180 168 255 / 0.10); border: 1px solid var(--accent-ring-strong);
  color: var(--accent); text-decoration: none;
  font-size: var(--text-xs); font-weight: 600; white-space: nowrap;
  transition: background var(--motion-base) var(--ease-out),
              color var(--motion-base) var(--ease-out);
}
.chat-entete-rdv:hover { background: var(--accent-ring-strong); color: #FFF; }
.chat-entete-rdv:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }
.chat-entete-rdv svg { flex: none; }
@media (max-width: 420px) {
  .chat-entete-rdv span { display: none; }
  .chat-entete-rdv { padding: 5px 7px; }
}

.chat-fermer {
  margin-left: auto; width: 26px; height: 26px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent;
  border-radius: var(--radius-md);
  color: var(--muted-foreground); cursor: pointer;
  transition: background var(--motion-base) var(--ease-out),
              color var(--motion-base) var(--ease-out);
}
.chat-fermer:hover { background: rgba(255,255,255,0.06); color: var(--foreground); }
.chat-fermer:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }

/* ── Le fil ──────────────────────────────────────────────────────────────── */

/* Les messages sont ancrés EN BAS, contre le composeur. Collés en haut (le
   défaut), trois messages laissent un grand vide sous eux et l'écran se lit comme
   un document, pas comme une conversation. Vu à l'écran le 2026-08-23.

   ⚠️ **PAR `margin-top: auto`, ET PLUS PAR `justify-content: flex-end`**
   (chantier C13 lot 2, 2026-09-10). La phrase d'avant promettait que « le
   défilement vers le haut reste possible : `overflow-y: auto` prime dès que le
   contenu dépasse ». **C'était faux.** Un conteneur de défilement n'a pas de zone
   de défilement au-dessus de son bord haut : ce que `justify-content` y pousse
   sort du document, `scrollTop` ne peut pas devenir négatif, et la molette repart
   à la page derrière. Mesuré dans un navigateur sur le tiroir d'analyse, qui
   portait le même dessin : `scrollHeight` égal à `clientHeight`, `scrollTop`
   maximal 0, et le premier message à -3646 px du haut de la boîte.

   ⚠️ **Corrigé ICI EN MÊME TEMPS que le tiroir d'analyse, et c'est délibéré** :
   c'est le même défaut, au caractère près (le tiroir a recopié ce dessin le
   2026-09-09). Le réparer d'un seul côté garantissait qu'il revienne de l'autre.
   Il se voit moins ici parce qu'une conversation avec le service client est
   courte -- « moins visible » n'est pas « absent ». */
.chat-messages {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 16px 14px; display: flex; flex-direction: column; gap: 8px;
}
/* ⚠️ **UN PSEUDO-ÉLÉMENT, ET PAS `> *:first-child`.** Le premier enfant réel de
   ce conteneur est `<input type="hidden" id="chat-depuis">`, que le navigateur
   met en `display: none` : ce n'est PAS un élément flexible, la marge n'y aurait
   rien poussé, et les messages seraient revenus se coller EN HAUT — soit le
   défaut d'avant, déplacé. `::before`, lui, est toujours le premier élément
   flexible, quels que soient les enfants que le fragment rend.
   ⚠️ `margin-bottom: -8px` annule exactement le `gap` que ce faux premier
   message aurait ajouté au-dessus du vrai. */
.chat-messages::before { content: ''; margin-top: auto; margin-bottom: -8px; }
/* /!\ **SAUF QUAND LE FIL EST VIDE** (2026-09-14). Ce `margin-top: auto` colle
   les messages EN BAS, ce qui est juste pour une conversation. Pose sur l'etat
   vide, il l'a pousse sous le bord haut de la boite : le panneau raccourci le
   meme jour, l'icone de l'accueil s'est retrouvee coupee par l'en-tete. Vu a
   l'ecran, et invisible pour un test.
   /!\ `:has()` est un confort : sans lui, on retombe simplement sur l'accueil
   colle en bas, jamais sur une page cassee. */
.chat-messages:has(.chat-vide)::before { margin-top: 0; }

/* ── LE JALON « l'assistant IA reprend la main » (fondateur, 2026-09-15) ────
   /!\ **IL NE RESSEMBLE PAS À UN MESSAGE, ET C'EST TOUT L'ENJEU.** Pas de
   bulle, pas de côté, pas d'auteur : centré, en petit, sur toute la largeur. Un
   fait de la conversation, pas quelqu'un qui parle — la même distinction que
   l'étiquette « Assistant IA » porte à l'intérieur d'une bulle, ici poussée
   jusqu'à la forme. Habillé en message, il se lirait comme un robot qui
   s'annonce, et la question « qui me parle ? » reviendrait entière. */
.chat-jalon {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin: 2px 6px; padding: 5px 10px;
  color: var(--muted-foreground); font-size: var(--text-2xs);
  text-align: center; line-height: 1.4;
}
.chat-jalon svg { flex: none; color: var(--accent); }

.chat-ligne { display: flex; }
.chat-mien { justify-content: flex-end; }
.chat-sien { justify-content: flex-start; }

/* /!\ Le coin du BAS, du côté de celui qui parle, reste presque droit : c'est ce
   qui distingue une bulle de conversation d'un simple encadré, et ça dit qui a
   écrit quoi avant même qu'on lise l'auteur. */
.chat-bulle-msg {
  max-width: 80%; padding: 9px 12px 7px;
  border-radius: var(--radius-lg);
  background: var(--muted); border: 1px solid var(--border);
  font-size: var(--text-base); line-height: 1.5;
}
.chat-sien .chat-bulle-msg { border-bottom-left-radius: var(--radius-sm); }
.chat-mien .chat-bulle-msg {
  border-bottom-right-radius: var(--radius-sm);
  background: rgba(180,168,255,0.12);
  border-color: var(--accent-ring-strong);
}
.chat-corps { white-space: pre-wrap; word-break: break-word; }
.chat-auteur {
  display: block; font-size: var(--text-xs); font-weight: 600;
  color: var(--accent); margin-bottom: 3px;
}

/* ── LE MESSAGE DE L'ASSISTANT IA — reconnaissable AVANT d'être lu ──────────
   /!\ **C'ÉTAIT LE DÉFAUT** (fondateur, 2026-09-14) : le robot et une personne
   de l'équipe rendaient la MÊME bulle, au même endroit, dans la même couleur.
   Rien ne les distinguait, et la question « qui m'a répondu ? » n'avait pas de
   réponse à l'écran.

   /!\ **LA DIFFÉRENCE EST UNE ÉTIQUETTE, PAS UN APLAT.** Un fond d'accent
   ferait passer les réponses du robot pour les plus importantes du fil ; un gris
   les ferait passer pour du système. La bulle garde son fond et prend un liseré
   à gauche, plus une étiquette nommée.

   /!\ **ELLES SONT DANS CE FICHIER, ET PAS DANS `charte.css`.** `.chat-auteur`
   y est posée `display: block`, cette feuille est chargée APRÈS, et à
   spécificité égale le dernier gagne : écrite là-bas, l'étiquette se dépliait
   sur deux lignes. Même piège que celui documenté pour la bulle de la vitrine. */
.chat-bulle-ia {
  border-left: 2px solid var(--accent-ring-strong);
  border-top-left-radius: var(--radius-sm);
}
.chat-auteur-ia {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--muted-foreground);
}
.chat-auteur-ia svg { color: var(--accent); flex: none; }
/* Le MESSAGE AUTOMATIQUE du système (budget de l'assistant IA atteint, A4c2) :
   ni l'IA ni une personne. Un liseré neutre et son étiquette « Message
   automatique » : il se lit comme une information, pas comme une réponse. */
.chat-bulle-auto {
  border-left: 2px solid var(--border);
  border-top-left-radius: var(--radius-sm);
}
.chat-auteur-auto {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--muted-foreground);
}
.chat-auteur-auto svg { flex: none; }
.chat-heure {
  display: block; margin-top: 4px; font-size: var(--text-2xs);
  color: var(--disabled-foreground); text-align: right;
}

/* La note interne : jaune, barrée d'un cadenas, impossible à confondre avec un
   message que le client verra. C'est le seul endroit de l'écran où l'équipe
   parle d'elle-même. */
.chat-note {
  display: flex; gap: 8px; align-items: flex-start;
  padding: 8px 11px; border-radius: var(--radius-lg);
  background: rgba(251,191,36,0.07);
  border: 1px dashed rgba(251,191,36,0.38);
  color: var(--warning-text); font-size: var(--text-sm); line-height: 1.5;
}
.chat-note svg { flex-shrink: 0; margin-top: 2px; }
.chat-note-corps { white-space: pre-wrap; word-break: break-word; }
.chat-note .chat-heure { text-align: left; color: rgba(252,211,77,0.55); }

/* Le VIDE d'un client qui n'a jamais écrit. Il ACCUEILLE, il ne constate pas :
   c'est le ton de `.vide-accueil` dans la charte, et son icône est teintée
   d'accent plutôt que grise. */
/* /!\ **IL SE POSE EN HAUT, PLUS AU MILIEU** (2026-09-14). Centre dans toute la
   hauteur du fil, il flottait loin de l'en-tete qui vient de nommer l'assistant
   et loin des questions rapides qui le suivent : trois blocs separes par du
   vide, dans une boite deja sombre. Colle sous l'en-tete, l'accueil, la phrase
   et les trois questions se lisent comme UNE seule invitation. */
.chat-vide {
  margin: 0 auto; text-align: center; color: var(--muted-foreground);
  padding: 14px 16px 6px; max-width: 290px;
}
.chat-vide svg { color: var(--accent); margin-bottom: 10px; }
.chat-vide p { margin: 0 0 6px; font-size: var(--text-sm); line-height: 1.55; }
.chat-vide p b { color: var(--foreground); font-size: var(--text-base); }

/* ── Les pièces jointes ──────────────────────────────────────────────────── */

.chat-piece-image { display: block; margin-top: 7px; }
.chat-piece-image img {
  max-width: 100%; max-height: 220px; border-radius: 8px;
  border: 1px solid var(--border); display: block;
}
.chat-piece-doc {
  display: flex; align-items: center; gap: 7px; margin-top: 7px;
  padding: 7px 10px; border-radius: 8px;
  background: var(--card); border: 1px solid var(--border);
  color: var(--foreground); text-decoration: none; font-size: var(--text-sm);
}
.chat-piece-doc:hover { border-color: var(--accent-ring-strong); }
.chat-piece-poids { margin-left: auto; color: var(--disabled-foreground); font-size: var(--text-xs); }

/* ── Le composeur ────────────────────────────────────────────────────────── */

/* /!\ UNE SEULE SURFACE (2026-08-23 au soir) : le champ et ses deux gestes
   vivent dans la même boîte, qui s'allume au focus. Avant, le champ portait sa
   bordure et les boutons flottaient sous lui à même le fond du panneau : deux
   objets pour un seul geste.
   /!\ La boîte est posée par le GABARIT (`.chat-boite-saisie`), et le fragment
   d'équipe la partage : les deux composeurs se ressemblent, c'est voulu. */
.chat-composeur {
  border-top: 1px solid var(--border); padding: 10px 12px 11px;
  flex-shrink: 0; background: var(--card);
  /* /!\ POUR LE REPÈRE « nouveaux messages » ci-dessous, et rien d'autre : il
     se pose SUR le fil, juste au-dessus du bord haut du composeur. */
  position: relative;
}

/* ── « DES MESSAGES PLUS BAS » (fondateur, 2026-09-15) ──────────────────────
   /!\ **ANCRÉ AU COMPOSEUR, PAS AU FIL**, et c'est la même raison qui y a mis
   la barre d'état : posé dans la liste des messages, il défilerait avec eux —
   donc il sortirait de l'écran exactement quand il sert, puisqu'il ne sert QUE
   lorsqu'on est remonté dans l'historique.
   /!\ `bottom: 100%` le pose au-dessus du composeur sans rien pousser : la
   saisie ne se déplace pas sous le doigt de quelqu'un en train d'écrire, ce qui
   est la règle que la barre d'état s'impose déjà juste en dessous. */
.chat-vers-le-bas {
  position: absolute; bottom: calc(100% + 8px); left: 50%;
  transform: translateX(-50%); z-index: 2;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: 999px; white-space: nowrap;
  background: var(--accent); color: #FFFFFF; border: 0; cursor: pointer;
  font-size: var(--text-xs); font-weight: 600;
  box-shadow: 0 8px 20px -6px rgba(0,0,0,.55);
}
.chat-vers-le-bas:hover { filter: brightness(1.08); }
.chat-vers-le-bas:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.chat-vers-le-bas svg { flex: none; }
/* ── « ÉCRIRE À » (fondateur, 11/10/2026) ───────────────────────────────────
   Deux interlocuteurs : un choix segmenté au-dessus de la saisie, le prénom en
   gras, le rôle dessous. Un seul (le responsable partenariat) : la même ligne,
   figée. /!\ « Écrire à » a SA ligne et chaque pastille deux lignes (prénom,
   rôle) : sur une seule, à 384 px, « chargé de clientèle » et « responsable
   partenariat » se coupaient tous deux (vu à l'écran le 11/10/2026). */
.chat-destinataire {
  display: flex; flex-direction: column; align-items: stretch; gap: 5px;
  margin: 0 0 8px;
}
.chat-destinataire-titre {
  flex: none; font-size: var(--text-xs); color: var(--muted-foreground);
}
.chat-destinataire-choix {
  flex: 1; min-width: 0; display: flex; gap: 4px; padding: 3px;
  background: var(--muted); border: 1px solid var(--border);
  border-radius: 999px;
}
.chat-destinataire-option {
  flex: 1; min-width: 0; position: relative; cursor: pointer;
  border-radius: 999px;
}
.chat-destinataire-option input {
  position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none;
}
.chat-destinataire-option > span {
  display: flex; flex-direction: column; align-items: center; gap: 0;
  padding: 4px 10px; border-radius: 999px; min-width: 0; line-height: 1.25;
  font-size: var(--text-xs); color: var(--muted-foreground);
  transition: background var(--motion-base) var(--ease-out),
              color var(--motion-base) var(--ease-out);
}
.chat-destinataire-option b {
  flex: none; font-weight: 600; color: var(--foreground);
}
.chat-destinataire-option small {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 0.92em;
}
.chat-destinataire-option:hover > span { color: var(--foreground); }
.chat-destinataire-option input:checked + span {
  background: var(--accent-wash); color: var(--accent-hi, var(--accent));
  box-shadow: inset 0 0 0 1px var(--accent-ring-strong);
}
.chat-destinataire-option input:focus-visible + span {
  outline: 2px solid var(--ring); outline-offset: 1px;
}
.chat-destinataire-fixe { cursor: default; flex: 0 1 auto; align-self: flex-start; }
.chat-destinataire-fixe > span {
  flex-direction: row; align-items: baseline; gap: 6px; padding: 4px 12px;
  background: var(--muted); border: 1px solid var(--border);
}
/* Dans le fil : à qui ce message du client était adressé. */
.chat-destinataire-msg {
  display: block; margin-bottom: 3px;
  font-size: var(--text-xs); color: var(--muted-foreground);
}
.chat-boite-saisie {
  background: var(--muted); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 6px 8px 7px;
  transition: border-color var(--motion-base) var(--ease-out),
              box-shadow var(--motion-base) var(--ease-out);
}
.chat-composeur:focus-within .chat-boite-saisie {
  border-color: var(--accent-ring-strong);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
.chat-composeur textarea {
  width: 100%; display: block; resize: none; min-height: 34px; max-height: 120px;
  background: transparent; color: var(--foreground);
  border: none; padding: 5px 4px;
  font-family: inherit; font-size: var(--text-base); line-height: 1.45;
}
/* /!\ L'anneau est porté par la BOÎTE, pas par le champ : deux anneaux
   concentriques à trois pixels l'un de l'autre. */
.chat-composeur textarea:focus-visible { outline: none; }
.chat-actions {
  display: flex; align-items: center; gap: 8px; margin-top: 4px;
}
.chat-actions .chat-envoyer { margin-left: auto; }
.chat-fichier-label {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  color: var(--muted-foreground); font-size: var(--text-xs);
  padding: 4px 8px; border-radius: var(--radius-md);
  border: 1px solid transparent;
  transition: background var(--motion-base) var(--ease-out),
              color var(--motion-base) var(--ease-out);
}
.chat-fichier-label:hover { color: var(--foreground); background: rgba(255,255,255,0.06); }
/* Seul le sélecteur de FICHIER est caché (le bouton natif est illisible) :
   la case à cocher « note interne », elle, doit rester visible. */
.chat-fichier-label input[type="file"] { display: none; }
.chat-fichier-label input[type="checkbox"] { margin: 0; accent-color: var(--warning); }
.chat-fichiers-choisis {
  font-size: var(--text-xs); color: var(--accent); margin-top: 6px;
}
.chat-erreur {
  margin: 0 0 8px; padding: 8px 10px; border-radius: var(--radius-md); font-size: var(--text-sm);
  background: rgba(248,113,113,0.10); border: 1px solid rgba(248,113,113,0.35);
  color: var(--error);
}

/* La note interne se signale AVANT d'être écrite : la boîte change de couleur.
   Un CSM ne doit jamais découvrir après coup qu'il a écrit au client. */
.chat-composeur.chat-mode-note .chat-boite-saisie {
  background: rgba(251,191,36,0.07);
  border-color: rgba(251,191,36,0.38);
}
.chat-composeur.chat-mode-note textarea { color: var(--warning-text); }

/* ── La boîte de réception de l'équipe ───────────────────────────────────── */

.chat-boite {
  display: grid; grid-template-columns: 320px 1fr; gap: 0;
  height: calc(var(--fenetre) - 190px); min-height: 420px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 12px; overflow: hidden;
}
.chat-liste { border-right: 1px solid var(--border); overflow-y: auto; min-height: 0; }
.chat-onglets {
  display: flex; gap: 2px; padding: 8px; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; background: var(--card); z-index: 1; flex-wrap: wrap;
}
.chat-onglet {
  padding: 5px 9px; border-radius: 6px; font-size: var(--text-xs);
  color: var(--muted-foreground); text-decoration: none; white-space: nowrap;
}
.chat-onglet:hover { background: var(--muted); color: var(--foreground); }
.chat-onglet.actif { background: rgba(180,168,255,0.12); color: var(--accent); font-weight: 500; }
.chat-onglet-n { opacity: .6; }

.chat-item {
  display: block; padding: 11px 14px; border-bottom: 1px solid var(--border);
  text-decoration: none; color: var(--foreground);
}
.chat-item:hover { background: var(--muted); }
.chat-item.actif { background: rgba(180,168,255,0.10); border-left: 2px solid var(--accent); padding-left: 12px; }
.chat-item-tete { display: flex; align-items: baseline; gap: 8px; }
.chat-item-nom { font-size: var(--text-base); font-weight: 500; }
.chat-item.non-lu .chat-item-nom { font-weight: 700; }
.chat-item-date { margin-left: auto; font-size: var(--text-2xs); color: var(--disabled-foreground); }
.chat-item-apercu {
  margin: 3px 0 0; font-size: var(--text-xs); color: var(--muted-foreground);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-item-agent { font-size: var(--text-2xs); color: var(--accent); }
.chat-item-point {
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
  display: inline-block; flex-shrink: 0;
}

.chat-panneau-equipe { display: flex; flex-direction: column; min-height: 0; }
.chat-contexte {
  padding: 12px 16px; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; flex-shrink: 0;
}
.chat-contexte-nom { font-size: var(--text-md); font-weight: 600; }
.chat-contexte-fait {
  font-size: var(--text-xs); color: var(--muted-foreground);
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border);
}
.chat-contexte-outils { margin-left: auto; display: flex; gap: 6px; align-items: center; }
.chat-nouveau { display: flex; gap: 6px; align-items: center; }
.chat-nouveau select,
.chat-contexte select {
  height: 26px; font-size: var(--text-xs); background: var(--muted);
  color: var(--foreground); border: 1px solid var(--border);
  border-radius: 6px; padding: 0 6px; font-family: inherit; max-width: 220px;
}
.chat-nouveau select { height: 28px; }

@media (max-width: 900px) {
  .chat-boite { grid-template-columns: 1fr; }
  .chat-liste { display: none; }
  .chat-boite.chat-sans-selection .chat-liste { display: block; }
  .chat-boite.chat-sans-selection .chat-panneau-equipe { display: none; }
}

/* ── Les questions rapides, dans l'etat vide de la bulle (2026-09-13) ────────
   /!\ Elles n'existent QUE fil vide : le fragment ne les rend plus des qu'un
   message existe. Rien ne les « cache », donc rien ne peut oublier de le faire. */
.chat-suggestions {
  display: flex; flex-direction: column; gap: 7px;
  padding: 2px 14px 14px;
}
.chat-suggestion {
  width: 100%; text-align: left; padding: 9px 12px;
  border-radius: 11px; cursor: pointer;
  font-family: inherit; font-size: var(--text-sm); line-height: 1.4;
  color: var(--foreground);
  background: rgba(255,255,255,.035);
  border: 1px solid var(--border);
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.chat-suggestion:hover {
  background: var(--accent-ring); border-color: var(--accent-ring-strong);
  color: var(--accent);
}
.chat-suggestion:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.chat-suggestion[disabled] { opacity: .5; cursor: default; }

/* /!\ **LES STYLES DE L'AMORCE D'ACCUEIL SONT PARTIS le 2026-09-15**, avec le
   bloc qu'ils habillaient : « peux retirer le message qui pop sur le chatbot
   lorsqu'on se connecte ». Plus aucun noeud ne porte `.chat-amorce`. */

/* /!\ **LA CARTE DE RENDEZ-VOUS A ETE RETIREE le 2026-09-14**, avec ses styles,
   sur demande du fondateur : « ca prend trop de place, je n'en veux plus ». Elle
   occupait le tiers haut de la bulle sur chaque page de l'espace client.
   Le rendez-vous vit desormais dans la carte de mise en route. */

/* ── « L'ASSISTANT IA ÉCRIT… » (TVNI-27, 2026-09-18) ────────────────────────
   Une bulle de plus, à la suite du fil, du côté de celui qui va répondre : c'est
   là que la réponse arrivera, et c'est là qu'on la guette. Trois points qui
   respirent l'un après l'autre ; immobiles si la personne a demandé moins de
   mouvement. C'est le serveur qui décide de l'afficher (`indicateur.py`). */
.chat-ecrit .chat-bulle-msg {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px; font-size: var(--text-sm); color: var(--muted-foreground);
}
.chat-ecrit-points { display: inline-flex; gap: 3px; }
.chat-ecrit-points i {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent); opacity: .55;
}
@media (prefers-reduced-motion: no-preference) {
  .chat-ecrit-points i { animation: chat-ecrit-rebond 1.2s ease-in-out infinite; }
  .chat-ecrit-points i:nth-child(2) { animation-delay: .15s; }
  .chat-ecrit-points i:nth-child(3) { animation-delay: .3s; }
}
@keyframes chat-ecrit-rebond {
  0%, 60%, 100% { transform: translateY(0); opacity: .45; }
  30%           { transform: translateY(-3px); opacity: 1; }
}

/* ── LES LIENS D'UNE RÉPONSE (TVNI-29) ──────────────────────────────────────
   Seules les pages de la liste fermée deviennent des liens
   (`bibliotheque/adresses.py`) : un lien ici mène TOUJOURS dans l'application. */
.chat-lien {
  color: var(--accent); font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
}
.chat-lien:hover { color: var(--foreground); }
.chat-lien-refuse { color: var(--disabled-foreground); font-size: var(--text-xs); }

/* ── LA PASTILLE TOMBE À L'OUVERTURE (TVNI-28) ──────────────────────────────
   Ouverte, la bulle montre les messages eux-mêmes : un compteur à côté dirait
   qu'il reste quelque chose à lire alors qu'on le lit. `chat.js` la vide aussi
   dans le même geste ; cette règle tient le cas où la relecture échoue. */
.chat-ouvert .chat-lanceur .chat-pastille { display: none; }

/* ── PLUSIEURS CONVERSATIONS (A4b, 23/09/2026) ───────────────────────────────
   /!\ **LA LISTE PREND LA PLACE DU FIL** : en mode liste, le fil, son titre et
   le composeur se retirent ; la liste occupe tout le corps du panneau. Les
   classes sont `chat-convs*`, jamais `chat-liste` : ce nom-là est déjà la
   colonne de gauche de la boîte de l'équipe, et une règle posée ici l'aurait
   restylée en silence. */

/* Le médaillon de l'en-tête devient le bouton « Conversations ». */
button.chat-marque { cursor: pointer; padding: 0; font: inherit; }
button.chat-marque:hover { background: rgb(180 168 255 / 0.20); }
button.chat-marque:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }
.chat-vers-fil-icone { display: none; }
.chat-mode-liste .chat-vers-fil-icone { display: inline-flex; }
.chat-mode-liste .chat-vers-liste-icone { display: none; }
.chat-vers-liste-icone, .chat-vers-fil-icone { align-items: center; }
.chat-vers-liste-icone { display: inline-flex; }

.chat-convs { display: none; }
.chat-mode-liste .chat-convs {
  display: flex; flex-direction: column; flex: 1; min-height: 0; overflow-y: auto;
}
.chat-mode-liste .chat-messages,
.chat-mode-liste .chat-composeur,
.chat-mode-liste .chat-conv-bandeau { display: none; }

/* Le titre de la conversation ouverte, en une ligne sous l'en-tête. */
.chat-conv-bandeau {
  flex-shrink: 0; padding: 6px 14px; border-bottom: 1px solid var(--border);
  font-size: var(--text-xs); color: var(--muted-foreground);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chat-conv-bandeau:has(#chat-conv-titre:empty) { display: none; }

.chat-convs-tete { padding: 12px 14px 8px; display: flex; align-items: center; gap: 8px; }
.chat-convs-nouvelle { width: 100%; justify-content: center; }
.chat-convs-titre { font-size: var(--text-sm); font-weight: 600; }
.chat-convs-retour, .chat-convs-archivees {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 6px;
  background: none; border: 0; border-radius: var(--radius-sm); cursor: pointer;
  font: inherit; font-size: var(--text-xs); color: var(--muted-foreground);
}
.chat-convs-retour:hover, .chat-convs-archivees:hover { color: var(--foreground); background: var(--muted); }

.chat-convs-liste { list-style: none; margin: 0; padding: 0 6px; }
.chat-conv { display: flex; align-items: center; border-radius: var(--radius-md); }
.chat-conv:hover { background: var(--muted); }
.chat-conv-ouvrir {
  flex: 1; min-width: 0; text-align: left; padding: 10px 8px; cursor: pointer;
  background: none; border: 0; font: inherit; color: var(--foreground);
  display: flex; flex-direction: column; gap: 3px;
}
.chat-conv-ligne { display: flex; align-items: center; gap: 7px; min-width: 0; }
.chat-conv-titre {
  flex: 1; min-width: 0; font-size: var(--text-sm);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chat-conv--non-lu .chat-conv-titre { font-weight: 600; }
.chat-conv-date { flex: none; font-size: var(--text-2xs); color: var(--disabled-foreground); }
.chat-conv-point {
  width: 7px; height: 7px; flex: none; border-radius: 50%; background: var(--accent);
}
.chat-conv-etat { font-size: var(--text-2xs); color: var(--accent); }
/* « Archiver » : un geste discret, qui ne se montre franchement qu'au survol
   (toujours visible au toucher, où le survol n'existe pas). */
.chat-conv-archiver {
  flex: none; margin-right: 4px; padding: 6px; border-radius: var(--radius-sm);
  background: none; border: 0; cursor: pointer; color: var(--disabled-foreground);
  opacity: .55; display: inline-flex;
}
.chat-conv:hover .chat-conv-archiver, .chat-conv-archiver:focus-visible { opacity: 1; }
.chat-conv-archiver:hover { color: var(--foreground); background: var(--card); }
@media (hover: none) { .chat-conv-archiver { opacity: 1; } }
.chat-convs-vide { padding: 18px 10px; font-size: var(--text-sm); color: var(--muted-foreground); }
.chat-convs-pied { margin-top: auto; padding: 10px 14px 14px; }

/* La phrase sur la relecture : une ligne sobre, jamais un avertissement. */
.chat-info-relecture {
  margin: 8px 0 0; font-size: var(--text-2xs); line-height: 1.5;
  color: var(--muted-foreground);
}
.chat-vide p.chat-info-relecture { font-size: var(--text-2xs); margin-top: 10px; }

/* ── Écran de l'équipe : une ligne par conversation, son état (A4b) ──────── */
.chat-item-titre {
  margin: 3px 0 0; font-size: var(--text-xs); color: var(--foreground);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-item-etats { display: flex; flex-wrap: wrap; gap: 5px; margin: 5px 0 3px; }
.chat-etat {
  font-size: var(--text-2xs); padding: 1px 7px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--muted-foreground); white-space: nowrap;
}
.chat-etat--attente { color: var(--warning-text); border-color: var(--warning); }
.chat-etat--equipe { color: var(--accent); border-color: var(--accent-ring); }
.chat-etat--archivee { font-style: italic; }
.chat-onglet-aide {
  margin: 0; padding: 6px 14px 8px; font-size: var(--text-2xs);
  color: var(--muted-foreground); border-bottom: 1px solid var(--border);
}
/* /!\ Le formulaire « Écrire à un client » PASSE À LA LIGNE sur un téléphone :
   sélecteur, premier message et bouton ne tiennent pas sur 390 px (mesuré). */
.chat-nouveau { flex-wrap: wrap; max-width: 100%; }
.chat-nouveau-texte {
  height: 28px; font-size: var(--text-xs); min-width: 0; flex: 1 1 180px;
  background: var(--muted); color: var(--foreground);
  border: 1px solid var(--border); border-radius: 6px; padding: 0 8px;
}
.chat-ses-conversations { flex-basis: 100%; font-size: var(--text-xs); }
.chat-ses-conversations summary { cursor: pointer; color: var(--muted-foreground); }
.chat-ses-conversations ul { list-style: none; margin: 6px 0 0; padding: 0; }
.chat-ses-conversations li a {
  display: flex; align-items: center; gap: 8px; padding: 5px 8px;
  border-radius: 6px; color: var(--foreground); text-decoration: none;
}
.chat-ses-conversations li a:hover { background: var(--muted); }
.chat-ses-conversations li.actif a { background: rgba(180,168,255,0.10); }
.chat-sc-titre { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-sc-date { color: var(--disabled-foreground); font-size: var(--text-2xs); }

/* ── LES RÉFÉRENCES « @ » DE LA BULLE (A4d, 23/09/2026) ──────────────────────
   Le composeur réutilise le champ à étiquettes d'A3 (`champ-consigne.js`, mode
   bulle) : la zone prend l'allure de l'ancienne `textarea`, la liste « @ »
   s'ouvre AU-DESSUS du composeur (en dessous, elle sortirait du panneau), et
   au téléphone elle reste une feuille (règle d'A3). Les étiquettes d'un fil sont
   la `.ref-etiquette` de la charte ; cliquables, elles se soulignent au survol. */
.chat-composeur .champ-ref-zone {
  min-height: 34px !important; max-height: 120px; padding: 5px 30px 5px 4px;
  font-size: var(--text-base); line-height: 1.45; color: var(--foreground);
  /* La boîte est celle du composeur (`.chat-boite-saisie`) : pas un second cadre. */
  background: transparent; border: 0; box-shadow: none; border-radius: 0;
}
.chat-composeur .champ-ref-zone--vide::before { color: var(--muted-foreground); }
.chat-composeur .champ-ref-liste:not(.champ-ref-liste--feuille) {
  position: absolute; left: -8px; right: -8px; bottom: calc(100% + 10px);
  margin: 0; z-index: 5; max-height: 260px;
}
.chat-corps .ref-etiquette, .chat-reference-posee .ref-etiquette {
  display: inline; padding: 0 5px; border-radius: 5px; font-size: .95em;
  white-space: normal; overflow-wrap: anywhere;
}
a.ref-etiquette { text-decoration: none; }
a.ref-etiquette:hover { text-decoration: underline; }
.ref-etiquette.ref-indisponible {
  color: var(--muted-foreground);
  background: var(--muted); border-color: var(--border);
}
.chat-reference-posee {
  margin: 10px 14px 0; font-size: var(--text-sm); color: var(--muted-foreground);
  text-align: center;
}


/* ── LES ANCIENNES CONVERSATIONS D'ANALYSE (A4d, D9) ─────────────────────────
   En lecture seule dans la bulle : pas de composeur (la classe est posée par
   `chat.js` tant que le fragment d'archive est affiché), un en-tête qui dit ce
   qu'elles sont, et trois gestes en pied. */
.chat-mode-archive .chat-composeur { display: none; }
.chat-archive { display: flex; flex-direction: column; gap: 8px; }
.chat-archive-tete {
  margin: 4px 0 6px; padding: 10px 12px; border-radius: var(--radius-lg);
  background: var(--muted); border: 1px solid var(--border);
  font-size: var(--text-sm); color: var(--muted-foreground);
}
.chat-archive-tete p { margin: 4px 0 0; }
.chat-archive-marque {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--text-xs); font-weight: 600; color: var(--foreground);
}
.chat-archive-perimetre { font-size: var(--text-xs); }
.chat-archive-vide { text-align: center; color: var(--muted-foreground); }
.chat-archive-pied {
  display: flex; flex-direction: column; align-items: stretch; gap: 8px;
  margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--border);
}
.chat-archive-gestes { display: flex; justify-content: space-between; gap: 8px; }
.chat-archive-gestes form { margin: 0; }
.chat-conv--archive .chat-conv-etat { color: var(--muted-foreground); }

/* ── Les E-MAILS de la boîte Messages (e-mails dans TVNI, T5) ─────────────────
   /!\ Le texte d'un e-mail est du TEXTE échappé : ses retours à la ligne se
   rendent ici (`pre-wrap`), jamais par des balises. Les classes sont `em-*`,
   pour ne rien hériter des bulles du chat. */
.em-sens { color: var(--muted-foreground); display: inline-flex; flex-shrink: 0; }
.em-item .chat-item-nom { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.em-item .chat-item-date { white-space: nowrap; flex-shrink: 0; }
.em-vide-liste { padding: 18px 14px; white-space: normal; }
.em-pages { display: flex; gap: 8px; justify-content: center; padding: 12px; flex-wrap: wrap; }
.em-retour {
  display: none; align-items: center; gap: 5px; flex-basis: 100%;
  font-size: var(--text-xs); color: var(--muted-foreground); text-decoration: none;
}
.em-fil {
  flex: 1; min-height: 0; overflow-y: auto; padding: 14px 16px;
  display: flex; flex-direction: column; gap: 12px;
}
.em-message {
  border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px;
  background: var(--card); min-width: 0;
}
.em-message--envoye { background: rgba(180,168,255,0.05); }
.em-tete { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px; }
.em-quand {
  margin-left: auto; font-size: var(--text-2xs); color: var(--disabled-foreground);
  white-space: nowrap;
}
.em-qui {
  display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; margin: 0 0 10px;
  font-size: var(--text-xs); color: var(--muted-foreground);
}
.em-qui dt { color: var(--disabled-foreground); }
.em-qui dd { margin: 0; overflow-wrap: anywhere; }
.em-objet { margin: 0 0 8px; font-size: var(--text-sm); font-weight: 600; }
.em-texte {
  white-space: pre-wrap; overflow-wrap: anywhere; font-size: var(--text-sm);
  line-height: 1.55; color: var(--foreground);
}
.em-motif { margin: 8px 0 0; font-size: var(--text-xs); color: var(--warning-text); }
.em-pieces {
  list-style: none; margin: 10px 0 0; padding: 10px 0 0;
  border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 6px;
}
.em-pieces a {
  display: inline-flex; align-items: center; gap: 6px; font-size: var(--text-xs);
  color: var(--accent); text-decoration: none; overflow-wrap: anywhere;
}
.em-pieces small { font-size: var(--text-2xs); color: var(--disabled-foreground); }
.em-piece-absente {
  max-width: 560px; display: flex; flex-direction: column; gap: 8px; align-items: flex-start;
}
@media (max-width: 900px) {
  .em-retour { display: inline-flex; }
}

/* ── ÉCRIRE un e-mail (e-mails dans TVNI, T6) ─────────────────────────────────
   Une colonne, comme un e-mail : De, À, Copie, Objet, puis le texte. Au
   téléphone, les étiquettes passent au-dessus de leur champ. */
.em-ecrire { max-width: 760px; }
.em-ecrire-retour {
  display: inline-flex; align-items: center; gap: 5px; margin: 0 0 10px;
  font-size: var(--text-xs); color: var(--muted-foreground); text-decoration: none;
}
.em-ecrire-retour:hover { color: var(--foreground); }
.em-ecrire-titre { margin: 0 0 16px; font-size: var(--text-xl); font-weight: 500; }
.em-ecrire-carte { padding: 16px 18px; }
.em-ecrire-brancher { display: flex; gap: 14px; align-items: flex-start; }
.em-ecrire-icone { color: var(--accent); display: flex; flex: none; margin-top: 2px; }
.em-ecrire-fort { margin: 0 0 4px; font-weight: 600; }
.em-ecrire-doux { margin: 0 0 12px; font-size: var(--text-sm); color: var(--muted-foreground); line-height: 1.5; }
.em-ecrire-lignes {
  display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: center;
  gap: 10px 12px; margin: 0 0 14px;
}
.em-ecrire-lignes dt { font-size: var(--text-xs); color: var(--muted-foreground); }
.em-ecrire-lignes dd { margin: 0; min-width: 0; font-size: var(--text-sm); overflow-wrap: anywhere; }
.em-ecrire-de { color: var(--muted-foreground); }
.em-ecrire .saisie.em-ecrire-champ { padding: 9px 12px; font-family: inherit; font-size: var(--text-sm); }
.em-ecrire-lignes .liste--compact { max-width: 100%; }
.em-ecrire-texte {
  display: block; min-height: 220px; font-family: inherit; font-size: var(--text-base);
  line-height: 1.55;
}
.em-ecrire-signature { margin: 6px 0 0; font-size: var(--text-xs); }
.em-ecrire-accord {
  display: flex; gap: 8px; align-items: flex-start; margin: 0 0 12px;
  padding: 8px 10px; border-radius: var(--radius-md);
  background: rgba(251,191,36,0.07); border: 1px solid rgba(251,191,36,0.30);
  font-size: var(--text-xs); line-height: 1.5; color: var(--warning-text);
}
.em-ecrire-accord svg { flex: none; margin-top: 2px; }
.em-ecrire-pied {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px;
}
.em-ecrire-pied .btn-ghost { margin-left: auto; }
.em-ecrire-fichiers {
  font-size: var(--text-xs); color: var(--accent); min-width: 0; overflow-wrap: anywhere;
}
.em-ecrire-cite {
  margin: 0 0 12px; padding: 10px 14px; border-left: 3px solid var(--border-strong);
  border-radius: 0 var(--radius-md) var(--radius-md) 0; background: rgba(255,255,255,0.02);
}
.em-ecrire-cite-tete {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: var(--text-xs); color: var(--muted-foreground); margin-bottom: 4px;
}
.em-ecrire-cite-texte { margin: 0; font-size: var(--text-sm); color: var(--muted-foreground); overflow-wrap: anywhere; }
/* « Répondre » : à la place du composeur du chat, sur la même surface. */
.em-repondre {
  display: flex; justify-content: flex-end; flex-shrink: 0;
  padding: 10px 12px 11px; border-top: 1px solid var(--border); background: var(--card);
}
@media (max-width: 560px) {
  .em-ecrire-lignes { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .em-ecrire-lignes dd { margin-bottom: 8px; }
  .em-ecrire-carte { padding: 14px; }
  .em-ecrire-pied .btn-primary { flex: 1 1 100%; justify-content: center; order: 5; }
  .em-ecrire-pied .btn-ghost { margin-left: auto; }
}
