/* La décoration des pages : c'est là qu'on dit à quoi ressemble le site. */

body { font-family: sans-serif; max-width: 35em; margin: 1em auto; padding: 0 1em; }
a { text-decoration: none; color: #007aff; }

/* Le petit chat du site, juste avant le titre de la page d'accueil. Sa hauteur
   est donnée en « em » : elle suit donc la taille des lettres du titre, et le
   logo grandit ou rapetisse toujours avec lui. */
.logo { height: 1.1em; vertical-align: -0.12em; margin-right: 0.15em; }

/* La liste des gens à qui on parle. */
#contacts { list-style: none; padding: 0; }
#contacts li { padding: 0.6em 0; border-bottom: 1px solid #ddd; }

/* La photo d'un contact, à gauche de son nom : un petit rond, découpé au
   milieu de l'image (object-fit : cover) pour qu'elle ne soit pas déformée
   quand elle n'est pas carrée. */
.avatar { width: 2.2em; height: 2.2em; border-radius: 50%;
          object-fit: cover; vertical-align: middle; margin-right: 0.5em; }

/* La même photo, mais en grand : c'est comme ça qu'on la voit sur la page de
   son compte, où on la choisit. */
.avatar.grand { width: 8em; height: 8em; }

/* Un groupe n'a pas de photo : à la place de l'image, on met un petit rond gris
   avec deux bonshommes dessinés dedans. Les deux « center » les mettent bien au
   milieu du rond. */
.avatar.groupe { display: inline-flex; align-items: center;
                 justify-content: center; background: #e5e5ea; }

/* La liste des gens qui sont dans le groupe, écrite en petit tout en haut de sa
   conversation. */
.membres { font-size: 0.85em; color: #666; margin: 0.2em 0; }

/* Quelqu'un est en train de nous appeler en vidéo : c'est écrit en rouge à côté
   de son nom dans la liste des conversations, et sa ligne est passée tout en
   haut. */
.sonne { color: #ff3b30; }

/* Le petit mot d'explication sous le formulaire d'ajout d'un contact. */
.aide { font-size: 0.85em; color: #666; }

/* La ligne du haut de la conversation : le lien pour revenir en arrière, et à
   côté le bouton rond pour appeler la personne en vidéo. Le « space-between »
   les écarte l'un de l'autre, chacun de son côté de la ligne. */
.haut { display: flex; align-items: center; justify-content: space-between; }

/* La boîte qui contient les messages : on ne voit que les derniers messages et
   on remonte dedans (et pas dans toute la page) pour relire les autres. La
   hauteur écrite ici ne sert que si le navigateur ne comprend pas la règle
   d'en dessous : d'habitude, c'est elle qui décide. */
#messages { height: 60vh; overflow-y: auto; border: none;
            border-radius: 0.6em; padding: 0 0.7em; }

/* La page d'une conversation remplit exactement l'écran, du haut jusqu'en bas :
   le titre, la liste des messages, puis la barre où on écrit. Le « :has » veut
   dire « la page qui contient une conversation » — les autres pages, elles, ne
   changent pas.

   Tout est empilé du haut vers le bas (flex, column). On donne à la page la
   hauteur de l'écran (100dvh, la hauteur qui reste vraiment visible sur un
   téléphone, barres du navigateur enlevées) et on dit que c'est la boîte des
   messages qui prend toute la place qui reste (flex : 1) : elle grandit ou
   rapetisse toute seule, et la barre où on écrit reste collée en bas. Le
   « min-height : 0 » est indispensable : sans lui, une boîte de ce genre
   refuse de devenir plus petite que ce qu'elle contient, et déborde. */
body:has(#conversation) { display: flex; flex-direction: column;
                          height: 100vh; height: 100dvh; margin: 0 auto; }
body:has(#conversation) #messages { flex: 1; height: auto; min-height: 0; }

/* Ce qui n'est pas les messages garde juste la place qu'il lui faut, et on
   resserre un peu tout ça pour laisser le plus de hauteur possible aux
   messages. */
body:has(#conversation) > p { margin: 0.3em 0; }

/* Le nom de celui à qui on parle, tout en haut de la conversation : on l'écrit
   petit et serré contre le reste. Sur un téléphone à petit écran, un gros titre
   prend une bonne part de la hauteur, et c'est autant de messages en moins. */
body:has(#conversation) h1 { font-size: 1.2em; margin: 0.2em 0; }
body:has(#conversation) form { flex: none; }
body:has(#conversation) .saisie { margin: 0.5em 0 0.4em; }
body:has(#conversation) .outils { margin: 0 0 0.4em; }

/* La conversation : une bulle par message, à droite quand c'est nous qui
   l'avons envoyé, à gauche quand c'est l'autre. */
#conversation { list-style: none; padding: 0; }
#conversation li { display: flex; margin: 0.4em 0; }
#conversation li.envoye { justify-content: flex-end; }
.bulle { max-width: 75%; padding: 0.5em 0.9em; border-radius: 1.2em; }
.envoye .bulle { background: #007aff; color: white; }
.recu .bulle { background: #e5e5ea; color: black; }
.date { display: block; font-size: 0.7em; opacity: 0.7; margin-top: 0.2em; }

/* Dans un groupe, le nom de celui qui a écrit le message, au-dessus de son
   texte : on est plusieurs à parler, il faut bien savoir qui. */
.auteur { display: block; font-size: 0.75em; font-weight: bold;
          opacity: 0.8; margin-bottom: 0.15em; }

/* La barre où on écrit son message : une grande boîte arrondie, aussi large
   que la page, qui contient la case du texte et le bouton pour envoyer. La
   case n'a ni bord ni fond à elle : elle remplit toute la place qui reste
   (flex : 1) à l'intérieur de la barre, et c'est la barre qu'on voit. Le
   « outline : none » enlève le cadre que le navigateur dessine autour de la
   case quand on écrit dedans, puisque c'est la barre qui s'éclaire à la
   place. */
.saisie { display: flex; align-items: center; gap: 0.4em;
          border: 1px solid #ddd; border-radius: 2em;
          padding: 0.3em 0.3em 0.3em 1em; margin: 0.8em 0;
          background: white; }
.saisie:focus-within { border-color: #007aff; }
.saisie input { flex: 1; min-width: 0; border: none; outline: none;
                background: none; font-size: 1em; font-family: inherit;
                padding: 0.5em 0; }

/* Le bouton pour envoyer : un rond bleu avec une flèche dedans, posé au bout
   de la barre. Il s'assombrit un peu quand la souris passe dessus. */
.saisie button { flex: none; width: 2.2em; height: 2.2em; border: none;
                 border-radius: 50%; background: #007aff; color: white;
                 font-size: 1em; cursor: pointer; }
.saisie button:hover { background: #0062cc; }

/* Les boutons pour joindre quelque chose au message : des ronds gris avec un
   dessin dedans (l'appareil photo, le micro, le caméscope, le trombone). Le
   « inline-flex » avec les deux « center » met le dessin bien au milieu du
   rond. Le rond du trombone est un « label » qui cache la case « fichier » du
   navigateur : on ne veut pas la voir, mais un clic sur le rond l'ouvre quand
   même, puisque c'est ce que fait un label. */
.outils { display: flex; gap: 0.6em; margin: 0.8em 0; }
.rond { display: inline-flex; align-items: center; justify-content: center;
        width: 2.6em; height: 2.6em; border: none; border-radius: 50%;
        background: #e5e5ea; font-size: 1.1em; line-height: 1;
        cursor: pointer; }
.rond:hover { background: #d5d5da; }
.outils input[type="file"] { display: none; }

/* Le rond devient rouge pendant qu'on enregistre un son ou une vidéo : c'est le
   programme de la page qui lui met cette classe, en même temps qu'il remplace
   le dessin par un carré d'arrêt. */
.rond.actif { background: #ff3b30; }

/* Les pièces jointes : les photos et les vidéos se voient directement dans la
   bulle, les sons ont un bouton pour les écouter, et les autres fichiers sont
   un lien sur lequel on clique pour les récupérer. */
.jointe { display: block; max-width: 100%; margin-top: 0.3em; }
img.jointe, video.jointe { border-radius: 0.6em; }
audio.jointe { width: 100%; }
.envoye .fichier { color: white; }

/* La caméra : on ne la voit pas tant qu'on ne l'a pas allumée, et l'aperçu
   n'apparaît qu'une fois la photo prise. C'est le programme de la page qui les
   fait apparaître, en changeant leur « display ». */
#webcam { display: none; }
#camera { display: block; max-width: 100%; max-height: 30vh;
          border-radius: 0.6em; }
#apercu { display: none; max-width: 12em; max-height: 20vh;
          border-radius: 0.6em; }

/* Le micro : le message vocal qu'on vient d'enregistrer, pour se réécouter
   avant de l'envoyer. Comme l'aperçu de la photo, on ne le voit qu'une fois
   qu'il y a quelque chose à écouter. */
#ecoute { display: none; width: 100%; max-width: 20em; }

/* Le caméscope : ce que la caméra est en train de filmer, puis le film qu'on
   vient de tourner, pour se regarder avant de l'envoyer. Comme le reste, ils
   n'apparaissent qu'au moment où il y a quelque chose à voir. */
#film { display: none; max-width: 100%; max-height: 30vh;
        border-radius: 0.6em; }
#regarde { display: none; max-width: 12em; max-height: 20vh;
           border-radius: 0.6em; }

/* L'appel vidéo. La fenêtre de l'appel se dessine par-dessus toute la page,
   comme sur un téléphone : « fixed » avec les quatre bords à zéro (inset) veut
   dire « collée aux quatre coins de l'écran », et le fond noir cache la
   conversation qui est derrière. Le « z-index » la met devant tout le reste.
   Tant qu'il n'y a pas d'appel on ne la voit pas du tout : c'est le programme de
   la page qui la fait apparaître, en remplaçant ce « none » par « flex ». */
#visio { display: none; position: fixed; inset: 0; z-index: 10;
         background: black; flex-direction: column;
         align-items: center; justify-content: center; }

/* L'autre : la grande image, au milieu de l'écran. */
#lui { width: 100%; height: 100%; object-fit: contain; }

/* Nous : la petite image, posée dans un coin par-dessus la grande, pour vérifier
   qu'on est bien dans le cadre. Le « position : absolute » la décolle de la
   pile et permet de la placer où on veut dans la fenêtre. */
#moi { position: absolute; right: 1em; bottom: 6em; width: 8em;
       border-radius: 0.6em; border: 2px solid white; }

/* Où on en est de l'appel (« On appelle Papa… », « Papa t'appelle ! »), écrit en
   blanc tout en haut, puisque le fond est noir. */
#etatvisio { position: absolute; top: 1em; margin: 0; color: white;
             font-size: 1.1em; text-align: center; }

/* Les deux boutons de l'appel, en bas de la fenêtre : décrocher (vert) et
   raccrocher (rouge). Celui de gauche ne se voit que quand ça sonne. */
.boutonsvisio { position: absolute; bottom: 1.5em; margin: 0;
                display: flex; gap: 1em; }
.boutonsvisio button { border: none; border-radius: 2em; color: white;
                       padding: 0.8em 1.6em; font-size: 1em;
                       font-family: inherit; cursor: pointer; }
#decrocher { display: none; background: #34c759; }
#raccrocher { background: #ff3b30; }

/* Les formulaires où l'on remplit des cases : se connecter, créer un compte,
   changer son nom ou son mot de passe. Sans rien, chaque case commence juste
   après son étiquette, et comme les étiquettes n'ont pas toutes la même
   longueur (« Nom : », « Adresse électronique : ») les cases sont en escalier.

   On range donc le formulaire dans une grille de deux colonnes : les étiquettes
   à gauche, les cases à droite. La première colonne prend la largeur de la plus
   longue étiquette (max-content), la seconde toute la place qui reste (1fr) :
   du coup toutes les cases commencent au même endroit, et finissent au même
   endroit. Le « display : contents » veut dire « fais comme si cette boîte-là
   n'était pas là » : les <p> et les <label> s'effacent, et ce sont bien le
   texte de l'étiquette et la case qui deviennent les deux cases de la grille.
   Le <label> continue quand même de faire son travail : on peut cliquer sur le
   texte pour écrire dans la case d'à côté. */
.aligne { display: grid; grid-template-columns: max-content 1fr;
          gap: 0.5em; align-items: center; }
.aligne p, .aligne label { display: contents; }

/* Le bouton, tout en bas : dans la deuxième colonne, sous les cases. Le
   « justify-self : start » l'empêche de s'étirer sur toute la largeur de la
   colonne, comme le font les cases. */
.aligne button { grid-column: 2; justify-self: start;
                 font-size: 1em; font-family: inherit; padding: 0.5em 1.2em;
                 border: none; border-radius: 0.5em;
                 background: #007aff; color: white; cursor: pointer; }
.aligne button:hover { background: #0062cc; }

/* Ce qui n'est pas une étiquette avec sa case — un titre, la photo
   d'aujourd'hui, le choix d'une nouvelle photo — s'étale sur les deux
   colonnes : « 1 / -1 » veut dire « de la première ligne de séparation jusqu'à
   la dernière ». Sans ça, la longue étiquette de la photo obligerait la
   première colonne à être large pour elle toute seule. */
.aligne h2, .aligne .toute { grid-column: 1 / -1; display: block; }

/* Les cases elles-mêmes, avec le même petit cadre arrondi que la barre où l'on
   écrit ses messages, qui devient bleu pendant qu'on écrit dedans. La case du
   fichier, elle, garde l'allure que lui donne le navigateur. */
.aligne input:not([type="file"]) {
  font-size: 1em; font-family: inherit; padding: 0.4em 0.6em;
  border: 1px solid #ddd; border-radius: 0.5em; background: white; }
.aligne input:focus { outline: none; border-color: #007aff; }

/* Sur un téléphone */
@media (max-width: 40em) {
  /* On écrit un peu plus gros — c'est de plus près qu'on le regarde, mais l'écran
     est tout petit — et on colle la page aux bords : chaque millimètre de large
     est bon à prendre. Le titre aussi devient plus petit, sinon il mange la
     moitié de la hauteur. */
  body { font-size: 1.1em; margin: 0.5em auto; padding: 0 0.4em; }
  h1 { font-size: 1.4em; margin: 0.4em 0; }
  /* Mons de marges */
  h2 { margin: 0.2em 0; }
  p { margin: 0; }
  ul { margin: 0; }
  .rond { width: 1.5em; height: 1.5em; }
  /* Dans une conversation, les bulles vont d'un bord à l'autre : sur un
   téléphone, la place est trop précieuse pour la donner à des marges. */
  body:has(#conversation) { max-width: none; padding: 0 0.3em; }
  body:has(#conversation) h1 { font-size: 1em; margin: 0; text-align: center; }
  #messages { padding: 0 0.2em; }
  .bulle { max-width: 85%; }
  .membres { display: none; }

  /* Les formulaires passent sur une seule colonne, l'étiquette au-dessus de sa
     case : sur un écran de téléphone, une colonne pour « Ton mot de passe
     d'aujourd'hui : » ne laisserait presque plus rien pour écrire dedans. */
  .aligne { grid-template-columns: 1fr; gap: 0.2em; }
  .aligne button { grid-column: 1; margin-top: 0.6em; }
}
