/* ==========================================================================
   Cockpit Step Dream : systeme visuel commun a toutes les pages.

   L'ADN reprend celui de Vay_AI : fond sombre legerement teinte, panneaux en
   verre depoli, un accent unique, angles genereux, transitions souples avec
   la meme courbe d'attenuation.

   Ce qui donne son identite propre au cockpit, et l'eloigne de la page
   generique : un titrage en serif editorial (Instrument Serif) face a une
   interface en sans-serif, un second accent or reserve a la marque et a la
   navigation active, et un grain leger sur tout le fond. Le grain est ce qui
   se voit le moins et change le plus : il casse l'aplat parfait qui fait
   "genere".
   ========================================================================== */

:root {
  /* Fond : noir tres legerement chaud, pas un gris neutre. */
  --fond: #0B0A0D;
  --fond-relief: #100E14;
  --panneau: rgba(255, 255, 255, 0.038);
  --panneau-fort: rgba(255, 255, 255, 0.065);
  --ligne: rgba(255, 255, 255, 0.075);
  --ligne-forte: rgba(255, 255, 255, 0.13);

  /* Encre chaude plutot que blanc pur : moins clinique. */
  --encre: #EDEBE6;
  --encre-douce: #B3AFB8;
  --encre-faible: #7E7A87;

  --violet: #6D5DF6;
  --violet-clair: #A99CFF;
  --or: #C9A227;
  --or-clair: #E3C367;
  --vert: #34D399;
  --ambre: #FBBF24;
  --rouge: #F87171;

  --r: 16px;
  --r-petit: 10px;
  --barre: 248px;
  --souple: cubic-bezier(0.23, 1, 0.32, 1);

  --serif: "Instrument Serif", Georgia, "Times New Roman", serif;
  --sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, Menlo, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  /* Ceinture : plus aucun decalage lateral vers du vide. */
  overflow-x: hidden;
  width: 100%;
  background: var(--fond);
  color: var(--encre);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

/* Grain : bruit fige, tres faible, applique au-dessus de tout mais
   transparent aux clics. C'est le detail qui enleve l'aspect plastique. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Halo unique, tres diffus, ancre en haut a gauche derriere la navigation. */
body::before {
  content: "";
  position: fixed;
  top: -22vh;
  left: -12vw;
  width: 70vw;
  height: 70vh;
  pointer-events: none;
  z-index: 0;
  opacity: 0.5;
  filter: blur(110px);
  background: radial-gradient(circle at 40% 40%,
              rgba(109, 93, 246, 0.42) 0%,
              rgba(109, 93, 246, 0.10) 45%,
              rgba(11, 10, 13, 0) 72%);
}

/* ---------------------------------------------------------------- Navigation */

.barre-laterale {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--barre);
  z-index: 20;
  display: flex;
  flex-direction: column;
  padding: 26px 16px 18px;
  background: rgba(10, 9, 12, 0.72);
  backdrop-filter: blur(22px);
  border-right: 1px solid var(--ligne);
}

.marque {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 0 8px 24px;
  text-decoration: none;
  color: inherit;
}
/* Le sigle reprend le logo Step Dream : trois barres qui montent en marches.
   Redessine en SVG plutot qu'importe en image, pour rester net a toute taille
   et prendre la couleur du theme. */
.sigle { width: 36px; height: 30px; flex: none; display: block; }
.sigle svg { width: 100%; height: 100%; display: block; }
.marque .nom { font-family: var(--serif); font-size: 18px; letter-spacing: 0.01em; }
.marque .sous {
  font-size: 9.5px; letter-spacing: 0.19em; text-transform: uppercase;
  color: var(--encre-faible); margin-top: 1px;
}

.menu { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.menu .groupe {
  font-size: 9.5px; letter-spacing: 0.17em; text-transform: uppercase;
  color: var(--encre-faible); padding: 16px 10px 7px;
}
.menu a {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px;
  border-radius: var(--r-petit);
  color: var(--encre-douce);
  text-decoration: none;
  font-size: 13.5px;
  transition: background 0.22s var(--souple), color 0.22s var(--souple);
}
.menu a:hover { background: var(--panneau); color: var(--encre); }
.menu a.actif { background: var(--panneau-fort); color: var(--encre); }
/* Le filet or a gauche : seul repere de position, discret mais net. */
.menu a.actif::before {
  content: "";
  position: absolute; left: -16px; top: 50%;
  width: 2px; height: 17px;
  transform: translateY(-50%);
  border-radius: 0 2px 2px 0;
  background: var(--or);
}
.menu a svg { width: 16px; height: 16px; flex: none; opacity: 0.75; }
.menu a.actif svg { opacity: 1; }
.menu a .compteur {
  margin-left: auto;
  font-family: var(--mono); font-size: 10.5px;
  color: var(--encre-faible);
}

.pied-barre { display: flex; flex-direction: column; gap: 9px; padding-top: 14px; border-top: 1px solid var(--ligne); }
.etat-synchro { font-family: var(--mono); font-size: 10px; color: var(--encre-faible); line-height: 1.65; padding: 0 4px; }
.point { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--vert); margin-right: 6px; vertical-align: middle; }
.point.vieux { background: var(--ambre); }
.point.actif { background: var(--violet); animation: pulse 1.1s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: 0.25; } }

/* ------------------------------------------------------------------ Contenu */

.contenu { position: relative; z-index: 1; margin-left: var(--barre); padding: 30px 34px 64px; max-width: 1500px; }

.entete { display: flex; justify-content: space-between; align-items: flex-end; gap: 22px; flex-wrap: wrap; margin-bottom: 26px; }
.sur-titre { font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--encre-faible); }
h1 { font-family: var(--serif); font-weight: 400; font-size: 36px; line-height: 1.1; margin: 7px 0 0; letter-spacing: -0.01em; }
h1 .accent { color: var(--or-clair); }
.chapo { color: var(--encre-douce); font-size: 13.5px; margin-top: 7px; max-width: 62ch; line-height: 1.6; }

/* -------------------------------------------------------------- Composants */

/* Relief des blocs.

   Trois couches qui se cumulent pour donner l'epaisseur, sans jamais dessiner
   une "boite 3D" caricaturale :
   1. un degrade tres leger du haut vers le bas, comme une surface eclairee
      par le dessus ;
   2. un liseré clair d'un pixel sur l'arete superieure (box-shadow inset),
      c'est le reflet de la lumiere sur le bord du panneau ;
   3. une ombre portee large et basse, qui decolle le bloc du fond.
   Au survol, le bloc se souleve et son ombre s'allonge. */
.carte, .kpi-carte {
  background:
    linear-gradient(180deg, rgba(255,255,255,0.055) 0%, rgba(255,255,255,0.022) 100%);
  border: 1px solid var(--ligne);
  border-radius: var(--r);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.075),
    0 1px 2px rgba(0, 0, 0, 0.4),
    0 14px 30px -16px rgba(0, 0, 0, 0.85);
  transition: transform 0.3s var(--souple), box-shadow 0.3s var(--souple),
              border-color 0.3s var(--souple);
}
.carte { padding: 20px 22px; }
.carte:hover, .kpi-carte:hover {
  transform: translateY(-2px);
  border-color: var(--ligne-forte);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 2px 4px rgba(0, 0, 0, 0.45),
    0 22px 42px -18px rgba(0, 0, 0, 0.95);
}
.carte h2 { font-family: var(--serif); font-weight: 400; font-size: 19px; margin: 0 0 3px; }
.carte .legende { font-size: 12px; color: var(--encre-faible); margin-bottom: 16px; }

.grille { display: grid; gap: 14px; }
/* Bretelle, et vraie cause du debordement : par defaut un enfant de grille
   refuse de retrecir sous la largeur de son contenu (`min-width: auto`). Un
   tableau large poussait donc sa colonne au-dela de l'ecran au lieu de
   defiler dans son cadre. */
.grille > *, .carte, .defile { min-width: 0; }
.defile { max-width: 100%; }
.grille.kpi { grid-template-columns: repeat(auto-fit, minmax(178px, 1fr)); }
.grille.deux { grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); align-items: start; }

.kpi-carte { padding: 17px 19px; }
.kpi-carte .etiq { font-size: 10px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--encre-faible); }
.kpi-carte .val { font-family: var(--mono); font-size: 29px; font-weight: 500; margin-top: 9px; letter-spacing: -0.035em; }
.kpi-carte .note { font-size: 11.5px; color: var(--encre-faible); margin-top: 4px; }
.kpi-carte.alerte .val { color: var(--rouge); }
.kpi-carte.attention .val { color: var(--ambre); }
.kpi-carte.bien .val { color: var(--vert); }
.kpi-carte a { color: inherit; text-decoration: none; display: block; }

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th { text-align: left; font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--encre-faible); font-weight: 500; padding: 0 12px 10px 0; white-space: nowrap; }
td { padding: 11px 12px 11px 0; border-top: 1px solid var(--ligne); color: var(--encre-douce); vertical-align: top; }
tbody tr { transition: background 0.18s var(--souple); }
tbody tr:hover { background: rgba(255, 255, 255, 0.022); }
td strong { color: var(--encre); font-weight: 500; }
.num { text-align: right; font-family: var(--mono); }
.defile { overflow-x: auto; }

.jeton { display: inline-block; font-size: 10px; padding: 2.5px 8px; border-radius: 999px; border: 1px solid var(--ligne-forte); color: var(--encre-faible); white-space: nowrap; }
.jeton.violet { border-color: rgba(109, 93, 246, 0.5); color: var(--violet-clair); }
.jeton.or { border-color: rgba(201, 162, 39, 0.5); color: var(--or-clair); }
.jeton.vert { border-color: rgba(52, 211, 153, 0.42); color: var(--vert); }
.jeton.ambre { border-color: rgba(251, 191, 36, 0.45); color: var(--ambre); }
.jeton.rouge { border-color: rgba(248, 113, 113, 0.45); color: var(--rouge); }
.jeton.mono { font-family: var(--mono); }

button, .bouton {
  font-family: inherit; font-size: 12.5px; color: var(--encre-douce);
  background: var(--panneau); border: 1px solid var(--ligne);
  border-radius: 999px; padding: 8px 15px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 7px; text-decoration: none;
  transition: background 0.22s var(--souple), color 0.22s var(--souple), border-color 0.22s var(--souple);
}
button:hover, .bouton:hover { background: var(--panneau-fort); color: var(--encre); border-color: var(--ligne-forte); }
button:disabled { opacity: 0.45; cursor: not-allowed; }
button.principal { background: rgba(109, 93, 246, 0.16); border-color: rgba(109, 93, 246, 0.45); color: var(--encre); }
button.principal:hover { background: rgba(109, 93, 246, 0.26); }
button.actif { background: rgba(201, 162, 39, 0.14); border-color: rgba(201, 162, 39, 0.45); color: var(--or-clair); }
.bouton-large { width: 100%; justify-content: center; }

input, select {
  font-family: inherit; font-size: 13px; color: var(--encre);
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--ligne); border-radius: var(--r-petit);
  padding: 9px 12px; outline: none;
  transition: border-color 0.22s var(--souple), background 0.22s var(--souple);
}
input:focus, select:focus { border-color: rgba(109, 93, 246, 0.55); background: rgba(255, 255, 255, 0.05); }
input::placeholder { color: var(--encre-faible); }
select option { background: #15131A; color: var(--encre); }

.filtres { display: flex; gap: 9px; flex-wrap: wrap; align-items: center; margin-bottom: 16px; }
.filtres input[type=search] { flex: 1; min-width: 210px; }

.pagination { display: flex; gap: 9px; align-items: center; justify-content: space-between; margin-top: 16px; font-size: 12px; color: var(--encre-faible); }

.jauge { height: 5px; background: rgba(255, 255, 255, 0.06); border-radius: 999px; overflow: hidden; margin-top: 7px; }
.jauge div { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--violet), var(--violet-clair)); transition: width 0.5s var(--souple); }

.vide { color: var(--encre-faible); font-size: 13px; padding: 26px 0; text-align: center; }

/* --------------------------------------------------------------- Connexion */

.page-connexion { display: grid; place-items: center; min-height: 100vh; padding: 24px; position: relative; z-index: 1; }
.boite-connexion { width: 100%; max-width: 372px; background: var(--panneau); border: 1px solid var(--ligne); border-radius: 22px; padding: 34px 30px; }
.boite-connexion .marque { justify-content: center; padding-bottom: 22px; }
.boite-connexion h1 { font-size: 27px; text-align: center; margin-bottom: 5px; }
.boite-connexion p { text-align: center; color: var(--encre-faible); font-size: 12.5px; margin: 0 0 22px; }
.boite-connexion input { width: 100%; margin-bottom: 12px; text-align: center; letter-spacing: 0.1em; }
.erreur { color: var(--rouge); font-size: 12px; text-align: center; min-height: 17px; margin-top: 11px; }

/* ------------------------------------------------------------------ Mobile */

.bouton-menu { display: none; }

/* Voile sous le menu ouvert. Sans lui, sur telephone, on ouvre le menu et
   il n'y a aucun endroit evident ou appuyer pour le refermer : c'est
   exactement ce qui bloquait. */
.voile {
  position: fixed; inset: 0; z-index: 19;
  background: rgba(6, 5, 8, 0.66);
  backdrop-filter: blur(2px);
  opacity: 0; pointer-events: none;
  transition: opacity 0.3s var(--souple);
}
.voile.visible { opacity: 1; pointer-events: auto; }

@media (max-width: 900px) {
  .barre-laterale {
    transform: translateX(-100%);
    transition: transform 0.32s var(--souple);
    width: min(84vw, 300px);
  }
  .barre-laterale.ouverte { transform: none; box-shadow: 0 0 60px rgba(0, 0, 0, 0.7); }
  .contenu { margin-left: 0; padding: 68px 14px 48px; }

  /* Le bouton du menu passe AU-DESSUS du menu ouvert (z-index 40 contre 20),
     sinon il devient inatteignable des que le panneau est deploye et on ne
     peut plus refermer. */
  .bouton-menu {
    display: inline-flex; position: fixed; top: 12px; left: 12px; z-index: 40;
    width: 42px; height: 42px; padding: 0; justify-content: center;
    font-size: 17px; line-height: 1;
    background: rgba(18, 16, 22, 0.94); backdrop-filter: blur(12px);
    border-color: var(--ligne-forte);
  }

  h1 { font-size: 25px; }
  .chapo { font-size: 13px; }
  .contenu { max-width: 100%; }
  .entete { margin-bottom: 18px; gap: 12px; }

  /* Deux tuiles par ligne : une seule gaspille l'ecran, trois sont illisibles. */
  .grille.kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .kpi-carte { padding: 13px 14px; }
  .kpi-carte .val { font-size: 22px; }
  .kpi-carte .etiq { font-size: 9px; letter-spacing: 0.1em; }
  .kpi-carte .note { font-size: 10.5px; }

  .grille.deux { grid-template-columns: minmax(0, 1fr); }
  .carte { padding: 16px 15px; }
  .carte h2 { font-size: 17px; }

  /* Les filtres passent en colonne : cote a cote ils depassaient. */
  .filtres { flex-direction: column; align-items: stretch; }
  .filtres input[type=search], .filtres select, .filtres button { width: 100%; }

  table { font-size: 12.5px; }
  th, td { padding-right: 10px; }

  .pagination { flex-direction: column; align-items: stretch; gap: 10px; }
  .pagination span { justify-content: center; }

  .barre-h { grid-template-columns: 92px 1fr 50px; font-size: 11.5px; }
  .bulle { max-width: 88%; }
  .info-courbe { display: none; }
}

@media (max-width: 420px) {
  .grille.kpi { grid-template-columns: minmax(0, 1fr); }
  h1 { font-size: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ====================================================================== */
/* Transitions de page                                                     */
/*                                                                         */
/* Le site fait plusieurs pages, chacune rechargee par le navigateur. Sans  */
/* rien, le passage est un clignotement sec. On enchaine donc deux temps :  */
/* le contenu monte doucement a l'arrivee, et disparait avant de partir     */
/* (classe posee par le script sur le lien clique).                        */
/* ====================================================================== */

@keyframes entree-page {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
@keyframes entree-barre {
  from { opacity: 0; transform: translateX(-10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes entree-bloc {
  from { opacity: 0; transform: translateY(14px) scale(0.995); }
  to   { opacity: 1; transform: none; }
}

.contenu { animation: entree-page 0.42s var(--souple) both; }
.barre-laterale { animation: entree-barre 0.4s var(--souple) both; }

/* Les blocs arrivent en cascade, un decalage par rang. Le retard reste
   court : au-dela de quelques dixiemes de seconde, ce n'est plus une
   animation, c'est une attente. */
.grille.kpi > *, .grille.deux > *, .contenu > .carte {
  animation: entree-bloc 0.44s var(--souple) both;
}
.grille.kpi > *:nth-child(1) { animation-delay: 0.03s; }
.grille.kpi > *:nth-child(2) { animation-delay: 0.06s; }
.grille.kpi > *:nth-child(3) { animation-delay: 0.09s; }
.grille.kpi > *:nth-child(4) { animation-delay: 0.12s; }
.grille.kpi > *:nth-child(5) { animation-delay: 0.15s; }
.grille.kpi > *:nth-child(6) { animation-delay: 0.18s; }
.grille.deux > *:nth-child(2) { animation-delay: 0.08s; }

body.sortie .contenu { opacity: 0; transform: translateY(-8px);
  transition: opacity 0.16s ease, transform 0.16s ease; }

/* ====================================================================== */
/* Infobulle du graphique                                                  */
/* ====================================================================== */

.info-courbe {
  position: fixed;
  z-index: 60;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -118%);
  transition: opacity 0.14s var(--souple);
  background: rgba(18, 16, 23, 0.97);
  border: 1px solid var(--ligne-forte);
  border-radius: 9px;
  padding: 8px 11px;
  box-shadow: 0 12px 28px -10px rgba(0, 0, 0, 0.9);
  white-space: nowrap;
}
.info-courbe.visible { opacity: 1; }
.info-courbe .jour { font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase; color: var(--encre-faible); }
.info-courbe .valeur { font-family: var(--mono); font-size: 17px; margin-top: 2px; }
.info-courbe .detail { font-size: 11px; color: var(--encre-douce); margin-top: 1px; }

.zone-survol { fill: transparent; cursor: crosshair; }
.trait-survol { stroke: rgba(169, 156, 255, 0.35); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0; }
.trait-survol.visible { opacity: 1; }
.pastille-survol { fill: #A99CFF; stroke: var(--fond); stroke-width: 2.5; opacity: 0; }
.pastille-survol.visible { opacity: 1; }

/* ====================================================================== */
/* Barres horizontales (analytique)                                        */
/* ====================================================================== */

.barres-h { display: flex; flex-direction: column; gap: 10px; }
.barre-h { display: grid; grid-template-columns: 128px 1fr 62px; gap: 11px; align-items: center; font-size: 12.5px; }
.barre-h .nom { color: var(--encre-douce); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.barre-h .piste { height: 22px; background: rgba(255, 255, 255, 0.045); border-radius: 6px; overflow: hidden; }
.barre-h .piste div {
  height: 100%; border-radius: 6px;
  background: linear-gradient(90deg, rgba(109,93,246,0.85), rgba(169,156,255,0.65));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.14);
  transition: width 0.6s var(--souple);
}
.barre-h .valeur { text-align: right; font-family: var(--mono); color: var(--encre); }

.colonnes-heures { display: flex; align-items: flex-end; gap: 3px; height: 110px; }
.colonnes-heures .h {
  flex: 1; border-radius: 4px 4px 2px 2px; min-height: 2px;
  background: linear-gradient(180deg, rgba(109,93,246,0.9), rgba(109,93,246,0.28));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.16);
  position: relative;
}
.colonnes-heures .h.pic { background: linear-gradient(180deg, var(--or-clair), rgba(201,162,39,0.3)); }
.etiquettes-heures { display: flex; gap: 3px; margin-top: 6px; }
.etiquettes-heures div { flex: 1; text-align: center; font-family: var(--mono); font-size: 8.5px; color: var(--encre-faible); }

/* ====================================================================== */
/* Formulaires de saisie                                                   */
/* ====================================================================== */

.champ { margin-bottom: 15px; }
.champ label { display: block; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--encre-faible); margin-bottom: 6px; }
.champ input, .champ select, .champ textarea { width: 100%; }
.champ textarea {
  font-family: inherit; font-size: 13px; color: var(--encre); min-height: 84px; resize: vertical;
  background: rgba(255,255,255,0.035); border: 1px solid var(--ligne);
  border-radius: var(--r-petit); padding: 10px 12px; outline: none;
}
.champ .aide { font-size: 11.5px; color: var(--encre-faible); margin-top: 5px; line-height: 1.5; }
.choix-sources { display: flex; flex-wrap: wrap; gap: 7px; }
.message { border-radius: var(--r-petit); padding: 11px 14px; font-size: 13px; margin-top: 14px; }
.message.ok { background: rgba(52,211,153,0.1); border: 1px solid rgba(52,211,153,0.35); color: var(--vert); }
.message.ko { background: rgba(248,113,113,0.1); border: 1px solid rgba(248,113,113,0.35); color: var(--rouge); }

/* ====================================================================== */
/* Fil de conversation                                                     */
/*                                                                         */
/* Codes visuels de la messagerie : le client a gauche, nous a droite,     */
/* pour que le sens de l'echange se lise sans rien decrypter.              */
/* ====================================================================== */

.fil {
  display: flex; flex-direction: column; gap: 9px;
  max-height: 460px; overflow-y: auto;
  padding: 4px 6px 4px 2px;
}
.bulle {
  max-width: 74%;
  padding: 9px 13px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.55;
  position: relative;
  word-break: break-word;
  animation: entree-bloc 0.3s var(--souple) both;
}
.bulle .qui {
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--encre-faible); margin-bottom: 3px;
}
.bulle .heure {
  font-family: var(--mono); font-size: 9.5px;
  color: var(--encre-faible); margin-top: 4px; text-align: right;
}
/* Le client : a gauche, teinte neutre. */
.bulle.entrant {
  align-self: flex-start;
  background: rgba(255, 255, 255, 0.055);
  border: 1px solid var(--ligne);
  border-bottom-left-radius: 4px;
}
/* Nous : a droite, teinte de la marque. */
.bulle.sortant {
  align-self: flex-end;
  background: rgba(109, 93, 246, 0.16);
  border: 1px solid rgba(109, 93, 246, 0.4);
  border-bottom-right-radius: 4px;
}
.bulle.media { font-style: italic; color: var(--encre-faible); }

.fil-entete {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 14px; margin-bottom: 14px;
}
tbody tr.choisie { background: rgba(109, 93, 246, 0.1); }
tbody tr.cliquable { cursor: pointer; }
