/* La bulle de chat de la vitrine (2026-08-30).

   Dessinée sur le widget de l'espace client (`src/trading/static/css/chat.css`) :
   même médaillon, même en-tête teintée à liseré d'accent, mêmes bulles de
   message, même boîte de saisie qui s'allume au focus. Les deux surfaces sont
   le même produit, elles doivent se ressembler.

   ⚠️ Feuille AUTONOME, sans dépendance a une variable de charte quelconque.
   Cette bulle est chargée sur CINQ pages qui ne partagent pas les mêmes jetons
   de couleur (index.html/decisions.html en définissent un jeu, legal.css un
   autre, avec des noms différents) : lire l'un d'eux ferait dépendre le rendu
   de la page qui l'a chargée. Toutes les variables sont posées ICI.

   ⚠️ **LE DÉFAUT QUI A DÉFIGURÉ CETTE BULLE, ET QUI RECOMMENCERA.**
   `landing/index.html` applique `section { padding: clamp(72px,12vh,140px)
   clamp(20px,4vw,48px) }`, une règle de TAG, pensée pour les sections de la
   page de vente. Le panneau était un `<section>` : il héritait de 140 px de
   rembourrage, son en-tête flottait au milieu du vide et son contenu était
   décalé de 48 px. Vu à l'écran par le fondateur, jamais par un test.
   Deux protections, et il faut les DEUX :
     1. la bulle n'emploie plus aucun tag que la vitrine style au tag
        (plus de `section`, plus de `header`) ;
     2. le bloc de remise à zéro ci-dessous neutralise ce qui pourrait arriver
        demain sur `form`, `p`, `input`, `button` ou `ol`.
   Préfixer les CLASSES ne suffit pas quand le voisin style des TAGS.

   ⚠️ Pas de `zoom` : c'est un artefact de la charte de l'application, pas de la
   vitrine, qui n'a jamais eu ce problème. Les longueurs sont donc nues. */

.tv-chat {
  --tv-bg:        #14161F;
  --tv-bg-soft:   #1B1E29;
  --tv-border:    rgba(255,255,255,0.10);
  --tv-border-fort: rgba(255,255,255,0.16);
  --tv-fg:        #F5F4F0;
  --tv-fg-muted:  rgba(245,244,240,0.66);
  --tv-fg-dim:    rgba(245,244,240,0.42);
  --tv-accent:    #B4A8FF;
  --tv-accent-doux: rgba(180,168,255,0.16);
  --tv-accent-bord: rgba(180,168,255,0.32);
  --tv-erreur:    #F87171;
  --tv-ok:        #4ADE80;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
  font-size: 14px;
  line-height: 1.5;
}

/* La remise à zéro défensive : voir l'avertissement en tête de fichier.
   ⚠️ Elle ne touche QUE l'intérieur de `.tv-chat`, jamais la page.

   ⚠️ **`:where()` N'EST PAS UNE COQUETTERIE : il pèse ZÉRO en spécificité.**
   Écrite `.tv-chat div { background: none }`, cette remise à zéro vaut (0,1,1)
   et bat `.tv-chat-panneau { background: … }` qui ne vaut que (0,1,0) : le
   panneau s'affichait SANS AUCUN FOND, la page de vente au travers, les bulles
   transparentes et toutes les tailles de texte ramenées à celle du parent.
   Vu à l'écran, jamais par un test. Enveloppée dans `:where()`, la règle ne
   pèse plus rien et tout ce qui suit la reprend sans se battre. */
.tv-chat, .tv-chat *, .tv-chat *::before, .tv-chat *::after {
  box-sizing: border-box;
}
:where(.tv-chat) :where(div, p, ol, li, form, input, textarea, button,
                        strong, span, svg) {
  margin: 0; padding: 0; border: 0; background: none;
  font: inherit; color: inherit; list-style: none; text-align: left;
}

/* ⚠️ `display:` écrase l'attribut `hidden` : un `display: flex` posé plus bas
   gagnerait contre `hidden` et le panneau resterait visible. Cette règle doit
   rester la SEULE à fixer `display` sur ce qui porte `hidden` dans la bulle. */
.tv-chat [hidden] { display: none !important; }

/* ── Le lanceur ────────────────────────────────────────────────────────────
   Une pastille qui PARLE, contrairement à celle de l'espace client qui n'a
   qu'une icône : sur une page de vente, un rond muet ne dit pas ce qu'il fait.
   Le reste est repris tel quel : accent translucide, liseré, halo. */
.tv-chat-lanceur {
  position: fixed; bottom: 20px; right: 20px; z-index: 999;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 18px; border-radius: 999px;
  background: rgba(180,168,255,0.18);
  border: 1px solid var(--tv-accent-bord);
  color: var(--tv-accent);
  font-size: 14px; font-weight: 600; cursor: pointer;
  box-shadow: 0 10px 30px -10px rgba(139,127,224,0.55), 0 2px 8px rgba(0,0,0,.35);
  transition: background .18s ease, border-color .18s ease,
              color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.tv-chat-lanceur:hover {
  background: rgba(180,168,255,0.28);
  border-color: rgba(180,168,255,0.52);
  color: #FFFFFF;
  box-shadow: 0 14px 34px -10px rgba(139,127,224,0.75), 0 2px 8px rgba(0,0,0,.35);
}
.tv-chat-lanceur:focus-visible { outline: 2px solid var(--tv-accent); outline-offset: 3px; }
@media (prefers-reduced-motion: no-preference) {
  .tv-chat-lanceur:hover { transform: translateY(-2px); }
}
/* 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. Règle reprise
   telle quelle de l'espace client. */
.tv-chat--ouvert .tv-chat-lanceur {
  background: var(--tv-bg-soft);
  border-color: var(--tv-border-fort);
  color: var(--tv-fg-muted);
  box-shadow: 0 4px 14px rgba(0,0,0,.35);
}
.tv-chat--ouvert .tv-chat-lanceur:hover {
  background: var(--tv-bg-soft); color: var(--tv-fg);
  border-color: rgba(255,255,255,0.24);
}
.tv-chat-lanceur-icone { flex-shrink: 0; }

/* ── Le panneau ──────────────────────────────────────────────────────────── */
.tv-chat-panneau {
  position: fixed; bottom: 88px; right: 20px; z-index: 999;
  width: 384px; max-width: calc(100vw - 40px);
  height: 540px; max-height: calc(100vh - 140px);
  background: var(--tv-bg);
  border: 1px solid var(--tv-border-fort);
  border-radius: 22px; overflow: hidden;
  box-shadow: 0 28px 70px -14px rgba(0,0,0,.62), 0 4px 14px rgba(0,0,0,.35);
  display: flex; flex-direction: column;
}

/* Sur téléphone, ancrée aux DEUX bords : pas de largeur propre à défendre.
   ⚠️ Deux ancrages plutôt qu'un `max-width` calculé, comme dans l'espace
   client. ⚠️ Non recetté sur un vrai téléphone : Chrome sans interface plafonne
   sa fenêtre autour de 500 px, donc une capture « 375 px » est un recadrage
   d'un rendu de 500 et la requête média n'y mord jamais. */
@media (max-width: 480px) {
  .tv-chat-panneau {
    left: 12px; right: 12px; width: auto; max-width: none;
    top: 12px; bottom: 84px; height: auto; max-height: none;
  }
}

/* ── L'en-tête : surface teintée, liseré d'accent, 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 ce panneau n'en est pas une. */
.tv-chat-entete {
  position: relative; flex-shrink: 0;
  display: flex; align-items: center; gap: 11px;
  padding: 14px 14px 13px 16px;
  background: linear-gradient(158deg, rgba(180,168,255,0.13) 0%, rgba(255,255,255,0.015) 72%);
  border-bottom: 1px solid var(--tv-border);
}
.tv-chat-entete::before {
  content: ""; position: absolute; left: 0; right: 32%; top: 0; height: 1px;
  background: linear-gradient(90deg, var(--tv-accent-bord), transparent);
}
.tv-chat-medaillon {
  flex-shrink: 0; width: 32px; height: 32px; border-radius: 11px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--tv-accent-doux);
  border: 1px solid var(--tv-accent-bord);
  color: var(--tv-accent);
}
.tv-chat-qui { min-width: 0; flex: 1; }
.tv-chat-qui strong {
  display: block; font-size: 13.5px; font-weight: 600; color: var(--tv-fg);
}
.tv-chat-qui p {
  margin-top: 2px; font-size: 11.5px; color: var(--tv-fg-muted);
}
.tv-chat-fermer {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--tv-fg-muted); cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.tv-chat-fermer:hover { background: rgba(255,255,255,0.07); color: var(--tv-fg); }
.tv-chat-fermer:focus-visible { outline: 2px solid var(--tv-accent); outline-offset: 1px; }

/* ── Le fil ──────────────────────────────────────────────────────────────── */
.tv-chat-fil {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 16px; display: flex; flex-direction: column; gap: 9px;
  scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.16) transparent;
}
.tv-chat-fil::-webkit-scrollbar { width: 8px; }
.tv-chat-fil::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.14); border-radius: 999px;
}
.tv-chat-message { display: flex; }
.tv-chat-message--client { justify-content: flex-end; }
.tv-chat-message--equipe { justify-content: flex-start; }
.tv-chat-bulle {
  max-width: 84%; padding: 9px 12px; border-radius: 14px;
  font-size: 13px; line-height: 1.55;
  white-space: pre-wrap; word-break: break-word;
}
.tv-chat-message--equipe .tv-chat-bulle {
  background: var(--tv-bg-soft);
  border: 1px solid var(--tv-border);
  color: var(--tv-fg);
  border-bottom-left-radius: 6px;
}
.tv-chat-message--client .tv-chat-bulle {
  background: var(--tv-accent-doux);
  border: 1px solid var(--tv-accent-bord);
  color: var(--tv-fg);
  border-bottom-right-radius: 6px;
}
.tv-chat-auteur {
  display: block; margin-bottom: 3px;
  font-size: 11px; font-weight: 600; color: var(--tv-accent);
}

/* ── La présence : « Marie a vu votre message » / « Marie vous répond… » ──
   Une ligne discrète, au-dessus de la saisie : c'est le fil et le composeur
   qui portent l'attention, pas cette ligne. */
.tv-chat-presence {
  flex-shrink: 0; margin: 0 16px 8px;
  font-size: 11.5px; color: var(--tv-fg-muted);
}
.tv-chat-presence--ecrit { color: var(--tv-accent); }

/* Les trois points de « ... vous répond » : un déroulé sobre, jamais un
   clignotement. Rien ici ne vient du serveur : décoratif, `aria-hidden`. */
.tv-chat-presence-points {
  display: inline-block; overflow: hidden; vertical-align: bottom;
  width: 1.2em;
}
.tv-chat-presence-points::after { content: "..."; }
@media (prefers-reduced-motion: no-preference) {
  .tv-chat-presence-points {
    width: 0;
    animation: tv-chat-points 1.2s steps(4, end) infinite;
  }
}
@keyframes tv-chat-points {
  0%   { width: 0; }
  100% { width: 1.2em; }
}

/* ── Le lien discret vers les coordonnées, quand le serveur ne les demande
   pas : la carte reste toujours ATTEIGNABLE, jamais seulement affichée. ── */
.tv-chat-coord-lien {
  flex-shrink: 0; align-self: flex-start; margin: 0 16px 10px;
  font-size: 11.5px; color: var(--tv-fg-muted);
  text-decoration: underline; text-underline-offset: 2px;
  cursor: pointer;
}
.tv-chat-coord-lien:hover { color: var(--tv-accent); }
.tv-chat-coord-lien:focus-visible { outline: 2px solid var(--tv-accent); outline-offset: 2px; }

/* ── L'avis (une panne, un refus, un accusé) ─────────────────────────────── */
.tv-chat-avis {
  flex-shrink: 0; margin: 0 16px 10px; padding: 9px 11px;
  border-radius: 10px; font-size: 12px; line-height: 1.5;
  background: rgba(248,113,113,0.10);
  border: 1px solid rgba(248,113,113,0.28);
  color: #FCA5A5;
}
.tv-chat-avis--ok {
  background: rgba(74,222,128,0.10);
  border-color: rgba(74,222,128,0.28);
  color: #86EFAC;
}

/* ── Les coordonnées : le geste demandé APRÈS le premier message ──────────
   Une carte posée au-dessus du composeur, pas une fenêtre par-dessus le fil :
   la conversation doit rester lisible pendant qu'on la remplit. */
.tv-chat-coordonnees {
  flex-shrink: 0; padding: 13px 16px 14px;
  border-top: 1px solid var(--tv-border);
  background: linear-gradient(180deg, rgba(180,168,255,0.07), transparent 90%);
  display: flex; flex-direction: column; gap: 7px;
}
.tv-chat-coordonnees p {
  font-size: 12.5px; font-weight: 600; color: var(--tv-fg); margin-bottom: 2px;
}
.tv-chat-coordonnees input {
  width: 100%; padding: 9px 11px; border-radius: 10px;
  background: rgba(255,255,255,0.035);
  border: 1px solid var(--tv-border);
  color: var(--tv-fg); font-size: 13px;
}
.tv-chat-coordonnees input::placeholder { color: var(--tv-fg-dim); }
.tv-chat-coordonnees input:focus {
  outline: none;
  border-color: var(--tv-accent-bord);
  background: rgba(255,255,255,0.055);
}
.tv-chat-bouton {
  align-self: flex-end; padding: 8px 16px; border-radius: 10px;
  background: var(--tv-accent-doux);
  border: 1px solid var(--tv-accent-bord);
  color: var(--tv-accent); font-size: 12.5px; font-weight: 600; cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.tv-chat-bouton:hover {
  background: rgba(180,168,255,0.26); color: #FFFFFF;
  border-color: rgba(180,168,255,0.52);
}
.tv-chat-bouton:focus-visible { outline: 2px solid var(--tv-accent); outline-offset: 2px; }
.tv-chat-bouton[disabled] { opacity: .5; cursor: default; }

/* ── Le composeur : UNE boîte, qui s'allume au focus ──────────────────────
   Reprise exacte du geste de l'espace client : séparés, le champ et son bouton
   se lisaient comme deux objets pour un seul geste. */
.tv-chat-envoi {
  flex-shrink: 0; padding: 12px 16px 14px;
  border-top: 1px solid var(--tv-border);
}
.tv-chat-saisie {
  display: flex; align-items: flex-end; gap: 8px;
  padding: 8px 8px 8px 12px; border-radius: 14px;
  background: rgba(255,255,255,0.035);
  border: 1px solid var(--tv-border);
  transition: border-color .15s ease, background .15s ease;
}
.tv-chat-envoi:focus-within .tv-chat-saisie {
  border-color: var(--tv-accent-bord);
  background: rgba(255,255,255,0.055);
}
.tv-chat-envoi textarea {
  flex: 1; min-width: 0; resize: none; max-height: 96px;
  color: var(--tv-fg); font-size: 13px; line-height: 1.5;
}
.tv-chat-envoi textarea::placeholder { color: var(--tv-fg-dim); }
.tv-chat-envoi textarea:focus-visible { outline: none; }
.tv-chat-envoyer {
  flex-shrink: 0; width: 34px; height: 34px; border-radius: 11px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--tv-accent-doux);
  border: 1px solid var(--tv-accent-bord);
  color: var(--tv-accent); cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.tv-chat-envoyer:hover {
  background: rgba(180,168,255,0.28); color: #FFFFFF;
  border-color: rgba(180,168,255,0.52);
}
.tv-chat-envoyer:focus-visible { outline: 2px solid var(--tv-accent); outline-offset: 2px; }
.tv-chat-envoyer[disabled] { opacity: .5; cursor: default; }
