/* ==========================================================================
   aj-bot.css, Abdeljalil Hcham
   ABDEL.EXE : la fenetre de discussion, en pastille flottante sur les pages
   du site et en pleine largeur sur interview.php.

   --------------------------------------------------------------------------
   Un seul fichier pour les deux affichages. Ce n'est pas de l'economie de
   fichiers, c'est une garantie : le personnage doit etre exactement le meme
   des deux cotes, et deux feuilles separees divergent au troisieme
   ajustement. Ce qui change entre les deux modes tient dans une classe sur
   le conteneur, .ajb--dock ou .ajb--page, et dans une trentaine de lignes
   tout en bas.

   Aucune couleur en dur : tout vient des variables du theme (--colorPrimary,
   --ajPanel, --ajMuted...). Si la charte bouge, le robot suit sans qu'on y
   touche.

   Prefixe .ajb_ et pas .aj_ : ce fichier est charge sur toutes les pages, y
   compris celles ou custom.css definit deja une centaine de .aj_. Un
   prefixe distinct evite d'avoir a verifier, a chaque ajout, qu'un nom n'est
   pas deja pris ailleurs.
   ========================================================================== */

/* Les variables sont posees sur :root et non sur .ajb, parce que le visage
   du robot apparait aussi hors de la fenetre de discussion : dans le bloc
   d'invitation en bas de la FAQ, par exemple. Un jeu de variables enferme
   dans .ajb laisserait ces visages sans couleur. Le repli entre parentheses
   rend le fichier autonome s'il est un jour charge sans custom.css. */
:root {
  --ajbPrimary: var(--colorPrimary, #c7d300);
  --ajbPanel: var(--ajPanel, #121309);
  --ajbPanel2: var(--ajPanel2, #0f100a);
  --ajbMuted: var(--ajMuted, rgba(177, 177, 177, 0.75));
  --ajbText: var(--colorBodyText, rgba(177, 177, 177, 1));
  --ajbWhite: var(--colorWhite, #ffffff);
  --ajbBlack: var(--colorBlack, #0c0c08);
  --ajbLine: rgba(255, 255, 255, 0.09);
  --ajbError: #ff7a68;
}

.ajb {
  font-family: var(--bodyFont, "Spline Sans", sans-serif);
}

/* ==========================================================================
   LE VISAGE

   C'est de l'art ASCII : sans police a chasse fixe, le cadre se disloque a
   la premiere lettre. `white-space: pre` conserve les espaces, et surtout
   `font-variant-ligatures: none` empeche les polices de programmation
   modernes (Fira Code, JetBrains Mono, Cascadia) de transformer « |> » ou
   « -- » en un seul glyphe : une ligature, c'est un caractere de moins, donc
   une colonne de decalage, donc un robot tordu.
   ========================================================================== */
.ajb_face {
  margin: 0;
  padding: 0;
  /* La liste est longue exprès, et l'ordre compte. Les trois dernières
     entrées avant `monospace` sont celles d'Android : Roboto Mono, Droid
     Sans Mono et DejaVu Sans Mono contiennent toutes les caractères de
     filet, alors que le `monospace` générique d'un téléphone ne les a pas
     forcément. Le script mesure de toute façon le résultat et bascule sur un
     cadre ASCII si un glyphe manque (voir boxDrawingFits dans aj-bot.js) :
     cette liste sert à ce que la bascule soit rarement nécessaire. */
  font-family: ui-monospace, "SFMono-Regular", "Menlo", "Consolas",
    "Liberation Mono", "Roboto Mono", "Droid Sans Mono", "DejaVu Sans Mono",
    monospace;
  font-variant-ligatures: none;

  /* iOS agrandit tout seul le texte de certains blocs pour le rendre
     lisible. Sur un paragraphe c'est une bonne idée ; sur un dessin dont
     chaque colonne doit tomber juste, c'est un robot qui déborde de son
     en-tête. On refuse l'ajustement, ici seulement. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  font-size: 12px;
  line-height: 1.12;
  letter-spacing: 0;
  white-space: pre;
  color: var(--ajbPrimary);
  text-shadow: 0 0 12px rgba(199, 211, 0, 0.25);
  transition: color linear 0.3s;
  user-select: none;

  /* Ces deux lignes corrigent une barre de defilement horizontale qui
     apparaissait sous le robot dans la pastille.

     La cause : le visage est un enfant de conteneur flexible, et un enfant
     flexible peut retrecir sous la largeur de son contenu (`flex-shrink`
     vaut 1 par defaut). Quand l'en-tete manquait de place, la boite du
     visage se comprimait, l'art ASCII debordait, et le navigateur ajoutait
     un ascenseur pour du texte qui doit precisement ne jamais bouger.

     `flex: 0 0 auto` interdit la compression : le visage garde sa largeur
     naturelle et c'est le texte a cote qui cede, ce qui est le bon ordre de
     priorite. `overflow: hidden` est la ceinture : meme comprime de force
     par un cas que je n'ai pas prevu, il ne fabriquera pas d'ascenseur. */
  flex: 0 0 auto;
  overflow: hidden;
}

/* Les yeux et la bouche sont les seuls elements a changer plusieurs fois par
   seconde. Les isoler dans leur propre span evite de reecrire tout le bloc a
   chaque image, et permet de leur donner une couleur legerement differente :
   le regard doit accrocher avant le cadre. */
.ajb_face b {
  font-weight: inherit;
  color: var(--ajbWhite);
}

/* --- Les etats -----------------------------------------------------------
   Le mouvement est ici, pas dans le JavaScript : une transformation CSS est
   composee par le GPU et ne coute rien, alors qu'animer la position depuis
   un setInterval fait travailler le processeur en continu pour un resultat
   moins fluide. Le script ne change que la classe. */
.ajb_face[data-state="idle"] {
  animation: ajb_float 4.2s ease-in-out infinite;
}

.ajb_face[data-state="listen"] {
  animation: ajb_float 2.1s ease-in-out infinite;
}

.ajb_face[data-state="think"] {
  animation: ajb_think 0.9s ease-in-out infinite;
}

.ajb_face[data-state="talk"] {
  animation: ajb_talk 0.42s ease-in-out infinite;
}

.ajb_face[data-state="happy"] {
  animation: ajb_hop 0.55s ease-out 2;
}

.ajb_face[data-state="error"] {
  color: var(--ajbError);
  text-shadow: 0 0 12px rgba(255, 122, 104, 0.3);
  animation: ajb_glitch 0.32s steps(2, end) infinite;
}

.ajb_face[data-state="error"] b {
  color: var(--ajbError);
}

.ajb_face[data-state="sleep"] {
  opacity: 0.55;
  animation: ajb_breathe 4.5s ease-in-out infinite;
}

@keyframes ajb_float {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-2px);
  }
}

@keyframes ajb_think {
  0%,
  100% {
    transform: rotate(-1.2deg) translateY(0);
  }
  50% {
    transform: rotate(1.2deg) translateY(-1px);
  }
}

@keyframes ajb_talk {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.035);
  }
}

@keyframes ajb_hop {
  0% {
    transform: translateY(0);
  }
  35% {
    transform: translateY(-6px);
  }
  100% {
    transform: translateY(0);
  }
}

@keyframes ajb_glitch {
  0% {
    transform: translate(0, 0);
  }
  25% {
    transform: translate(-2px, 1px);
  }
  50% {
    transform: translate(2px, -1px);
  }
  75% {
    transform: translate(-1px, -1px);
  }
  100% {
    transform: translate(0, 0);
  }
}

@keyframes ajb_breathe {
  0%,
  100% {
    opacity: 0.4;
  }
  50% {
    opacity: 0.7;
  }
}

/* ==========================================================================
   LA PASTILLE FLOTTANTE
   ========================================================================== */
.ajb--dock {
  position: fixed;
  right: 50px;
  bottom: 50px;
  z-index: 9998;
}

.ajb_launcher {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 18px 10px 14px;
  background: var(--ajbPanel);
  border: 1px solid rgba(199, 211, 0, 0.32);
  border-radius: 44px;
  cursor: pointer;
  font-family: inherit;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.45);
  /* Entree differee : le robot ne doit pas etre la premiere chose que le
     visiteur voit bouger. Le script retire .is_hidden apres le premier
     defilement, la transition fait le reste. */
  opacity: 1;
  transform: translateY(0) scale(1);
  transition: opacity 0.35s ease, transform 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.2),
    border-color 0.25s linear;
}

.ajb_launcher.is_hidden {
  opacity: 0;
  transform: translateY(18px) scale(0.9);
  pointer-events: none;
}

.ajb_launcher:hover {
  border-color: var(--ajbPrimary);
}

.ajb_launcher .ajb_face {
  font-size: 11px;
  line-height: 1.1;
}

.ajb_launcher_txt {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.6px;
  color: var(--ajbWhite);
  white-space: nowrap;
}

.ajb_launcher_txt small {
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--ajbPrimary);
  margin-top: 1px;
}

/* La petite bulle d'invitation. Elle passe une fois, huit secondes, jamais
   deux fois dans la meme session : au-dela c'est de la publicite, et une
   publicite qu'on ne peut pas fermer se fait fermer definitivement. */
.ajb_hint {
  position: absolute;
  right: 0;
  bottom: calc(100% + 12px);
  max-width: 250px;
  padding: 12px 14px;
  background: var(--ajbPrimary);
  color: var(--ajbBlack);
  font-size: 13px;
  font-weight: 600;
  line-height: 19px;
  border-radius: 12px 12px 2px 12px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.4);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.3s linear, transform 0.3s ease;
  pointer-events: none;
}

.ajb_hint.is_on {
  opacity: 1;
  transform: translateY(0);
}

/* ==========================================================================
   LE PANNEAU
   ========================================================================== */
.ajb_panel {
  display: flex;
  flex-direction: column;
  background: var(--ajbPanel);
  border: 1px solid var(--ajbLine);
  border-top: 3px solid var(--ajbPrimary);
}

/* `display: flex` pose ici l'emporte sur le `display: none` que le
   navigateur associe a l'attribut `hidden` : une regle d'auteur bat toujours
   la feuille par defaut, quelle que soit la specificite. Sans cette ligne, le
   panneau reste visible en permanence, attribut `hidden` ou pas. */
.ajb_panel[hidden] {
  display: none;
}

/* --- Les dimensions de la pastille ---------------------------------------
   392 x 560 au depart, ce qui etait la taille d'une fenetre de support
   client. Ce n'en est pas une : ici on lit des reponses de trois a cinq
   lignes, en enfilade, et on relit celle d'avant. A 392 de large, une phrase
   tenait sur trois lignes et le fil ressemblait a une colonne de journal ;
   avec l'en-tete et le pied, il restait moins de la moitie de la hauteur
   pour la conversation elle-meme.

   440 x 640 change le rapport : le texte respire, et le fil occupe environ
   les deux tiers du panneau au lieu de la moitie. C'est encore une pastille,
   pas une fenetre : au-dela de 480 de large elle commence a disputer la page
   au contenu du site, ce qui est exactement ce qu'on ne veut pas.

   La hauteur maximale passe a 100vh - 80px : sur un portable 13 pouces, le
   panneau touche presque le haut de la fenetre, et c'est tant mieux, c'est
   la ou la place manquait le plus. */
.ajb--dock .ajb_panel {
  position: fixed;
  right: 50px;
  bottom: 50px;
  width: 440px;
  max-width: calc(100vw - 40px);
  height: 640px;
  max-height: calc(100vh - 80px);
  z-index: 9999;
  box-shadow: 0 26px 60px rgba(0, 0, 0, 0.55);
  transform-origin: 100% 100%;
  opacity: 0;
  transform: translateY(14px) scale(0.96);
  transition: opacity 0.22s linear, transform 0.22s cubic-bezier(0.2, 0.9, 0.3, 1.1);
}

.ajb--dock .ajb_panel.is_open {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* --- En-tete ------------------------------------------------------------ */
.ajb_head {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--ajbLine);
  background: var(--ajbPanel2);
  flex: 0 0 auto;
}

.ajb_id {
  flex: 1 1 auto;
  min-width: 0;
}

.ajb_id h2 {
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 0.8px;
  color: var(--ajbWhite);
  margin: 0 0 3px;
  line-height: 1.2;
}

.ajb_id p {
  font-size: 11px;
  line-height: 16px;
  color: var(--ajbMuted);
  margin: 0 0 6px;
}

.ajb_state {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ajbPrimary);
}

.ajb_state i {
  width: 6px;
  height: 6px;
  background: var(--ajbPrimary);
  display: inline-block;
}

.ajb.is_busy .ajb_state i {
  animation: ajb_pulse 1s ease-in-out infinite;
}

.ajb.is_error .ajb_state,
.ajb.is_error .ajb_state i {
  color: var(--ajbError);
  background-color: var(--ajbError);
}

@keyframes ajb_pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.2;
  }
}

.ajb_head_actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}

.ajb_icon_btn {
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid transparent;
  color: var(--ajbMuted);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
  text-decoration: none;
  transition: color linear 0.2s, border-color linear 0.2s;
}

.ajb_icon_btn:hover {
  color: var(--ajbPrimary);
  border-color: rgba(199, 211, 0, 0.35);
}

/* --- Le fil -------------------------------------------------------------- */
.ajb_log {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 20px 18px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  scrollbar-width: thin;
  scrollbar-color: rgba(199, 211, 0, 0.35) transparent;
}

.ajb_log::-webkit-scrollbar {
  width: 7px;
}

.ajb_log::-webkit-scrollbar-thumb {
  background: rgba(199, 211, 0, 0.3);
}

/* La couleur du texte est posee explicitement. Le theme colore `p`, `span` et
   les titres, jamais `body` : un `div` de message heriterait donc du noir par
   defaut du navigateur, sur fond noir. Invisible, et invisible de la pire
   facon, celle qu'on ne voit pas non plus dans l'inspecteur. */
.ajb_msg {
  max-width: 88%;
  font-size: 14px;
  line-height: 23px;
  color: var(--ajbText);
  animation: ajb_in 0.24s ease-out;
}

@keyframes ajb_in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.ajb_msg.bot {
  align-self: flex-start;
  border-left: 2px solid var(--ajbPrimary);
  padding-left: 14px;
}

.ajb_msg.user {
  align-self: flex-end;
  background: var(--ajbPanel2);
  border: 1px solid rgba(255, 255, 255, 0.1);
  padding: 11px 14px;
  color: var(--ajbWhite);
}

.ajb_who {
  display: block;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--ajbMuted);
  margin-bottom: 6px;
}

.ajb_msg.bot .ajb_who {
  color: var(--ajbPrimary);
}

.ajb_msg strong {
  color: var(--ajbWhite);
  font-weight: 700;
}

.ajb_msg ul {
  margin: 8px 0 0;
  padding-left: 17px;
  list-style: disc;
}

.ajb_msg li {
  margin-bottom: 4px;
}

.ajb_msg a {
  color: var(--ajbPrimary);
  border-bottom: 1px solid rgba(199, 211, 0, 0.4);
}

.ajb_msg.is_error {
  border-left-color: var(--ajbError);
}

.ajb_msg.is_error .ajb_who {
  color: var(--ajbError);
}

/* Le curseur de frappe, pendant que le texte arrive en flux. Il disparait
   des le dernier caractere : un curseur qui reste clignoter fait croire que
   la reponse n'est pas finie. */
.ajb_caret {
  display: inline-block;
  width: 7px;
  margin-left: 1px;
  color: var(--ajbPrimary);
  animation: ajb_caret 0.9s steps(1, end) infinite;
}

@keyframes ajb_caret {
  0%,
  49% {
    opacity: 1;
  }
  50%,
  100% {
    opacity: 0;
  }
}

/* Les trois points d'attente. Meme filet que les reponses, pour que le texte
   ne saute pas de deux pixels en arrivant. */
.ajb_wait {
  align-self: flex-start;
  border-left: 2px solid var(--ajbPrimary);
  padding-left: 14px;
  font-size: 14px;
  line-height: 23px;
  color: var(--ajbMuted);
  font-style: italic;
}

.ajb_wait span {
  display: inline-block;
  animation: ajb_dot 1.1s ease-in-out infinite;
}

.ajb_wait span:nth-child(2) {
  animation-delay: 0.14s;
}

.ajb_wait span:nth-child(3) {
  animation-delay: 0.28s;
}

@keyframes ajb_dot {
  0%,
  60%,
  100% {
    opacity: 0.25;
  }
  30% {
    opacity: 1;
  }
}

/* --- Suggestions ---------------------------------------------------------- */
.ajb_chips {
  flex: 0 0 auto;
  padding: 14px 18px 0;
  border-top: 1px solid var(--ajbLine);
}

.ajb_chips[hidden] {
  display: none;
}

.ajb_chips h6 {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--ajbMuted);
  margin: 0 0 9px;
}

.ajb_chips ul {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ajb_chips button {
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  color: var(--ajbText);
  background: var(--ajbPanel2);
  border: 1px solid rgba(255, 255, 255, 0.12);
  padding: 6px 11px;
  cursor: pointer;
  transition: color linear 0.2s, background linear 0.2s, border-color linear 0.2s;
}

.ajb_chips button:hover:not(:disabled) {
  color: var(--ajbBlack);
  background: var(--ajbPrimary);
  border-color: var(--ajbPrimary);
}

.ajb_chips button:disabled {
  opacity: 0.4;
  cursor: default;
}

/* --- Saisie --------------------------------------------------------------- */
.ajb_form {
  flex: 0 0 auto;
  display: flex;
  gap: 9px;
  align-items: stretch;
  padding: 14px 18px 8px;
}

.ajb_form input {
  flex: 1 1 auto;
  min-width: 0;
  font-family: inherit;
  font-size: 14px;
  color: var(--ajbWhite);
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.14);
  padding: 11px 13px;
  outline: none;
  transition: border-color linear 0.2s;
}

.ajb_form input:focus {
  border-color: var(--ajbPrimary);
}

.ajb_form input::placeholder {
  color: rgba(177, 177, 177, 0.45);
}

.ajb_send {
  flex: 0 0 auto;
  width: 44px;
  font-family: inherit;
  font-size: 15px;
  font-weight: 700;
  color: var(--ajbBlack);
  background: var(--ajbPrimary);
  border: 1px solid var(--ajbPrimary);
  cursor: pointer;
  transition: opacity linear 0.2s;
}

.ajb_send:disabled {
  opacity: 0.4;
  cursor: default;
}

.ajb_foot {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 18px 14px;
}

.ajb_note {
  font-size: 10px;
  line-height: 15px;
  color: rgba(177, 177, 177, 0.45);
  margin: 0;
}

.ajb_note a {
  color: rgba(199, 211, 0, 0.75);
}

.ajb_reset {
  flex: 0 0 auto;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--ajbMuted);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
  transition: color linear 0.2s;
}

.ajb_reset:hover {
  color: var(--ajbPrimary);
}

/* Le bouton « remonter » du theme est fixe a 50px du bas, exactement la ou
   se pose la pastille. On le monte d'un cran plutot que de deplacer le
   robot : la discussion se cherche en bas a droite, c'est la convention, et
   une convention respectee est une explication qu'on n'a pas a donner. */
.progress-wrap {
  bottom: 122px !important;
}

/* La bulle d'invitation se deploie vers le haut, c'est-a-dire exactement la
   ou vient de monter le bouton « remonter ». Plutot que de repousser encore
   le bouton (il finirait au milieu de l'ecran), on l'efface pendant les huit
   secondes d'affichage de la bulle. Il reprend sa place ensuite, et le
   visiteur qui voulait remonter n'a rien perdu : la bulle se ferme au
   premier clic ailleurs. */
body.ajb_hint_on .progress-wrap {
  opacity: 0 !important;
  visibility: hidden !important;
}

/* Panneau ouvert : le bouton « remonter » tombe pile dans le bord droit de
   la fenetre de discussion, et il est declare plus haut que tout le reste
   par le theme (z-index 10000). Le monter au-dessus du panneau reviendrait a
   poser une fleche flottante au milieu d'une conversation. On le retire tant
   que la discussion est ouverte : la page ne defile pas derriere, il ne sert
   a rien pendant ce temps-la. */
body.ajb_open .progress-wrap {
  opacity: 0 !important;
  visibility: hidden !important;
}

/* ==========================================================================
   L'INVITATION DANS LA PAGE

   La pastille flottante suffit a rendre le robot accessible, pas a le rendre
   evident : un coin d'ecran se regarde une fois et s'oublie. Ce bloc se pose
   la ou la question se pose vraiment, au bas de la FAQ, juste apres la
   derniere reponse ecrite. Le visiteur qui a lu six reponses et cherche la
   septieme tombe dessus au bon moment.

   Il ne s'affiche que si le script a demarre (la classe est posee en JS) :
   proposer d'ouvrir une discussion qui ne peut pas s'ouvrir serait pire que
   de ne rien proposer.
   ========================================================================== */
.ajb_invite {
  display: none;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
  margin-top: 38px;
  padding: 26px 28px;
  background: var(--ajbPanel);
  border: 1px solid var(--ajbLine);
  border-left: 3px solid var(--ajbPrimary);
}

body.ajb_ready .ajb_invite {
  display: flex;
}

.ajb_invite .ajb_face {
  flex: 0 0 auto;
  font-size: 13px;
}

.ajb_invite_text {
  flex: 1 1 300px;
  min-width: 0;
}

.ajb_invite_text h6 {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--ajbPrimary);
  margin: 0 0 8px;
}

.ajb_invite_text p {
  font-size: 15px;
  line-height: 25px;
  color: var(--ajbText);
  margin: 0;
}

.ajb_invite_btn {
  flex: 0 0 auto;
  font-family: var(--bodyFont, "Spline Sans", sans-serif);
  cursor: pointer;
}

@media (max-width: 575.98px) {
  .ajb_invite {
    padding: 20px;
    gap: 16px;
  }

  .ajb_invite .ajb_face {
    font-size: 11px;
  }

  .ajb_invite_btn {
    width: 100%;
  }
}

/* ==========================================================================
   MODE PAGE (interview.php)
   ========================================================================== */
.ajb--page {
  display: block;
  max-width: 860px;
  margin: 0 auto;
}

.ajb--page .ajb_panel {
  height: auto;
}

.ajb--page .ajb_head {
  padding: 22px 26px;
  gap: 22px;
}

.ajb--page .ajb_face {
  font-size: 14px;
}

.ajb--page .ajb_id h2 {
  font-size: 20px;
}

.ajb--page .ajb_id p {
  font-size: 13px;
  line-height: 20px;
}

.ajb--page .ajb_log {
  height: 48vh;
  min-height: 330px;
  padding: 26px;
  gap: 20px;
}

.ajb--page .ajb_msg,
.ajb--page .ajb_wait {
  font-size: 15px;
  line-height: 26px;
}

.ajb--page .ajb_msg {
  max-width: 82%;
}

.ajb--page .ajb_chips,
.ajb--page .ajb_form,
.ajb--page .ajb_foot {
  padding-left: 26px;
  padding-right: 26px;
}

.ajb--page .ajb_chips {
  padding-top: 18px;
}

.ajb--page .ajb_form input {
  font-size: 15px;
  padding: 14px 16px;
}

.ajb--page .ajb_send {
  width: 54px;
  font-size: 17px;
}

/* ==========================================================================
   TELEPHONE

   Sur un petit ecran, une fenetre de 392px posee dans un coin devient une
   fenetre de 392px posee sur toute la page. Autant l'assumer : le panneau
   prend l'ecran, avec une marge en haut pour laisser voir qu'il y a un site
   dessous et donner ou revenir.
   ========================================================================== */
@media (max-width: 575.98px) {
  .ajb--dock {
    right: 16px;
    bottom: 16px;
  }

  .ajb_launcher {
    padding: 9px 14px 9px 11px;
    gap: 9px;
  }

  .ajb_launcher_txt {
    font-size: 12px;
  }

  /* --- Le visage sur téléphone ------------------------------------------
     Le même dessin qu'au bureau, dans un en-tête deux fois moins large. À
     12px il occupait 82 pixels sur les 343 disponibles, et écrasait la
     colonne du nom contre les deux boutons d'action : tout se touchait.

     À 10px il en prend 68, la baseline respire, et le halo est réduit
     parce qu'une ombre portée de 12 pixels autour de caractères de 10
     pixels sur un écran à haute densité donne une bouillie lumineuse
     plutôt qu'un effet. */
  .ajb--dock .ajb_head {
    padding: 13px 15px;
    gap: 13px;
  }

  .ajb--dock .ajb_head .ajb_face {
    font-size: 10px;
    text-shadow: 0 0 7px rgba(199, 211, 0, 0.22);
  }

  /* La signature disparaît : elle tient sur une ligne de 134 pixels au prix
     d'une troncature, et le nom plus l'état disent déjà tout ce qu'elle
     disait. */
  .ajb--dock .ajb_id p {
    display: none;
  }

  .ajb--dock .ajb_panel {
    right: 8px;
    left: 8px;
    bottom: 8px;
    top: 64px;
    width: auto;
    max-width: none;
    height: auto;
    max-height: none;
  }

  .ajb_hint {
    max-width: 200px;
    font-size: 12px;
  }

  .progress-wrap {
    bottom: 84px !important;
  }
}

@media (max-width: 767.98px) {
  .ajb--page .ajb_head {
    padding: 18px;
    gap: 14px;
  }

  .ajb--page .ajb_face {
    font-size: 11px;
  }

  .ajb--page .ajb_log {
    padding: 20px 18px;
    height: 54vh;
  }

  .ajb--page .ajb_msg {
    max-width: 94%;
  }

  .ajb--page .ajb_chips,
  .ajb--page .ajb_form,
  .ajb--page .ajb_foot {
    padding-left: 18px;
    padding-right: 18px;
  }
}

/* ==========================================================================
   MOUVEMENT REDUIT

   Le visiteur qui a demande moins d'animations a de bonnes raisons : troubles
   vestibulaires, migraines, ou simplement une preference. Le robot garde son
   visage, il arrete de bouger. Le script lit la meme preference et coupe
   aussi le rendu image par image, sinon le texte continuerait de s'ecrire
   lettre a lettre.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .ajb_face,
  .ajb_state i,
  .ajb_wait span,
  .ajb_caret,
  .ajb_msg {
    animation: none !important;
  }

  .ajb_launcher,
  .ajb--dock .ajb_panel,
  .ajb_hint {
    transition: none;
  }
}
