/*  Worms Finder — l'onglet « Get in the game » et l'en-tête de la room.
 *
 *  🔑 POURQUOI UNE FEUILLE À PART, ET POURQUOI TOUT EST SOUS UN IDENTIFIANT.
 *  `style.css` et `decor.css` sont retravaillés en parallèle (lisibilité,
 *  typographie). Écrire ici plutôt que là-bas évite de se marcher dessus, et
 *  préfixer chaque sélecteur par `#vue-match` ou `#onglet-match` lui donne la
 *  spécificité d'un identifiant : ces règles gagnent quel que soit l'ordre des
 *  feuilles, donc elles ne dépendent pas d'une cascade en cours de réparation.
 *
 *  ⚠️ Cette feuille est chargée APRÈS style.css et decor.css, mais elle ne
 *  s'appuie pas sur cet ordre — voir ci-dessus. Elle réutilise en revanche
 *  leurs variables (--jaune, --bord, --texte-doux…) : on ne redéfinit aucune
 *  couleur ici, la palette reste au même endroit pour tout le monde.
 */

/* ==========================================================================
   L'ONGLET : LE LIEN RÉSEAU, ET LE TÉLÉPHONE QUI SONNE
   ==========================================================================
   🔑 L'ONGLET N'APPARAÎT QUE QUAND IL Y A UNE PARTIE À LANCER, ET IL DOIT SE
   VOIR À CET INSTANT-LÀ. Les quatre onglets sont typographiquement identiques ;
   celui-ci surgit au milieu d'une session. Un sprite du jeu devant le libellé
   le fait remarquer sans changer ni sa police ni la hauteur de la barre.

   🔑 DEUX SPRITES, UNE SEULE PLACE, ET JAMAIS LES DEUX EN MÊME TEMPS.
     · AU REPOS : `Misc/netbreak.png`, deux vers reliés par un éclair. Deux
       images qui alternent lentement — l'icône « connecté » du jeu.
     · PENDANT L'ALERTE : le téléphone du lobby WormNET (`Misc/phone.png`,
       vingt images) REMPLACE le lien, tant que quelqu'un a parlé dans la room
       et qu'on n'est pas venu voir.

   ⚠️ POURQUOI REMPLACER ET NON AJOUTER À CÔTÉ. Deux animations côte à côte sur
   une barre d'onglets de 21 px, c'en est une de trop : rien ne dit plus laquelle
   est le signal, et une alerte qu'on ne distingue pas du décor n'est plus une
   alerte. Le remplacement donne trois choses d'un coup — une seule chose bouge
   à la fois ; le CHANGEMENT D'ICÔNE est lui-même le signal, donc il survit à
   `prefers-reduced-motion` (voir tout en bas) ; et une boîte de taille fixe
   garantit que l'onglet ne bouge pas d'un pixel quand l'un prend la place de
   l'autre.

   Les sprites sont DÉCORATIFS : `aria-hidden` dans le HTML, rien à annoncer.
   « Get in the game » est écrit juste à côté et dit déjà où l'on va. Ce qui est
   annoncé, lui, est plus bas : `#onglet-match-neuf` et `#alerte-room`.

   ⚠️ Le bâton de dynamite qui occupait cette place a disparu, et son outil
   `outils/extraire-dynamite.js` avec lui : plus rien ne le référençait. */

/*  🚨 `display` SUR UN ÉLÉMENT QUE LE JAVASCRIPT CACHE AVEC `hidden`.
 *  file.js fait `$('onglet-match').hidden = !enCours`. Une règle d'auteur qui
 *  pose un `display` bat la feuille du navigateur, et l'onglet resterait
 *  visible en permanence — le même piège que la modale « Match found », déjà
 *  documenté dans style.css. On le referme explicitement ici plutôt que de
 *  compter sur le `[hidden] { display: none !important }` d'une autre feuille. */
#onglet-match {
    display: inline-flex; align-items: center; gap: .45rem;
    white-space: nowrap;

    /*  🔑 LES COTES DES DEUX BANDES, RECOPIÉES DE `outils/extraire-onglet.js`
     *  (il les imprime à chaque exécution, à la ligne « valeurs à reporter »).
     *  Elles sont posées sur le BOUTON et non sur l'icône parce que le calque
     *  du téléphone est un `::after` qui doit hériter des deux jeux de cotes
     *  pour se centrer dans la boîte du lien.
     *  ⚠️ Relancer l'outil avec une autre hauteur cible oblige à revenir ici ET
     *  à revoir `margin-block` ci-dessous : les deux se répondent. */
    --icone-h: 21px;
    --lien-l: 49px;   --lien-n: 2;      /* onglet-netbreak.png — 2 x 49 = 98 */
    --tel-l:  23px;   --tel-n: 20;      /* onglet-phone.png   — 20 x 23 = 460 */
}
#onglet-match[hidden] { display: none; }

/*  🔑 UNE BANDE HORIZONTALE ET `steps()` SUR `background-position-x`, comme
 *  `.sprite` dans decor.css. C'est la décision structurante du projet et on ne
 *  s'en écarte pas : l'animation ne touche jamais `transform`, qui reste libre.
 *
 *  🔑 HAUTEUR IMPOSÉE, LARGEUR LIBRE — et 21 px, la hauteur qu'avait déjà la
 *  dynamite. Les deux bandes SORTENT DE L'OUTIL À CETTE TAILLE : la réduction
 *  (63 px et 25 px de haut dans le rip) est faite une fois, hors ligne, par
 *  moyenne de bloc. Le navigateur affiche donc du 1:1, sans le moindre
 *  rééchantillonnage — exactement la propriété qu'avait la dynamite avec ses
 *  8x21 natifs, et la raison pour laquelle on ne laisse pas `pixelated` réduire
 *  lui-même : au plus proche voisin, une réduction au tiers jette deux pixels
 *  sur trois et le combiné du téléphone part en confettis.
 *
 *  `image-rendering: pixelated` reste indispensable malgré le 1:1 : c'est du
 *  pixel art, et le lissage par défaut du navigateur en fait de la bouillie dès
 *  qu'un zoom ou un écran haute densité change l'échelle. Même raison que
 *  .marque-mascotte, les drapeaux et les pierres tombales.
 *
 *  `flex: none` parce que l'onglet est un conteneur flex : sans ça la boîte se
 *  ferait comprimer en largeur quand la barre manque de place, et le sprite
 *  serait tronqué.
 *
 *  ⚠️ Les marges négatives ne sont pas de la coquetterie : 21 px, c'est plus
 *  haut que la ligne de texte d'un onglet (0,9 rem). Sans elles, l'image
 *  agrandirait la boîte de CE bouton, donc — les onglets étant des éléments
 *  flex étirés — toute la barre. Elles retirent la hauteur excédentaire du
 *  calcul ; l'image déborde alors dans le padding du bouton, qui est large.
 *
 *  `position: relative` porte le calque du téléphone. (`filter` en ferait déjà
 *  un bloc conteneur, mais compter là-dessus serait un piège : retirer l'ombre
 *  déplacerait le téléphone dans un coin de la page.) */
#onglet-match-icone {
    flex: none;
    position: relative; display: block;
    width: var(--lien-l); height: var(--icone-h);
    margin-block: -3px;
    background-image: url(/assets/onglet-netbreak.png);
    background-repeat: no-repeat;
    background-size: calc(var(--lien-l) * var(--lien-n)) var(--icone-h);
    image-rendering: pixelated;
    /*  1,6 s pour deux images : 800 ms chacune. Volontairement LENT — cette
        animation-là tourne en permanence dès que l'onglet existe, et un
        clignotement nerveux en haut de l'écran se remarque au mauvais sens du
        terme. Le téléphone, lui, va cinq fois plus vite : c'est ce contraste de
        cadence qui fait qu'une alerte se voit.
        ⚠️ Les quatre propriétés séparées et pas le raccourci : `steps()` reçoit
        une variable, et c'est sous cette forme longue que decor.css l'utilise
        déjà pour tous les sprites du décor. On ne prend pas le risque d'une
        autre. */
    animation-name: onglet-lien;
    animation-duration: 1.6s;
    animation-timing-function: steps(var(--lien-n));
    animation-iteration-count: infinite;
    /*  La même ombre dure que la mascotte : sans elle, un sprite posé sur la
        barre d'onglets flotte au-dessus du décor alors que les lettres, qui
        portent --ombre-texte, s'y posent. */
    filter: drop-shadow(0 1px 0 rgba(0, 0, 0, .55));
}
@keyframes onglet-lien {
    to { background-position-x: calc(var(--lien-l) * var(--lien-n) * -1); }
}

/*  Le calque du téléphone. Il existe en permanence mais n'est rendu que pendant
 *  l'alerte : un `::after` coûte moins qu'un second élément dans le HTML, et
 *  match.css reste une feuille d'identifiants.
 *  ⚠️ Il est CENTRÉ dans la boîte du lien, qui est la plus large des deux —
 *  d'où le calcul plutôt qu'un décalage écrit en dur, qui se désaccorderait à
 *  la première regénération des bandes. Le centrage passe par `left` et non par
 *  `transform` : `transform` reste libre, règle du projet. */
#onglet-match-icone::after {
    content: ''; display: none;
    position: absolute; top: 0;
    left: calc((var(--lien-l) - var(--tel-l)) / 2);
    width: var(--tel-l); height: var(--icone-h);
    background-image: url(/assets/onglet-phone.png);
    background-repeat: no-repeat;
    background-size: calc(var(--tel-l) * var(--tel-n)) var(--icone-h);
    image-rendering: pixelated;
}
@keyframes onglet-sonnerie {
    to { background-position-x: calc(var(--tel-l) * var(--tel-n) * -1); }
}

/*  ÇA SONNE. `room.js` pose `data-sonnerie` sur le bouton et l'enlève dès qu'on
 *  vient voir. Le lien s'efface — `background-image: none` plutôt que
 *  `opacity` : rien à composer, et son animation s'arrête vraiment. */
#onglet-match[data-sonnerie] #onglet-match-icone {
    background-image: none;
    animation-name: none;
}
#onglet-match[data-sonnerie] #onglet-match-icone::after {
    display: block;
    /*  1 s pour vingt images : 50 ms chacune, soit les 20 images/s d'une
        animation d'interface du jeu. C'est la cadence qui rend la sonnerie
        lisible comme une sonnerie et non comme un scintillement. */
    animation-name: onglet-sonnerie;
    animation-duration: 1s;
    animation-timing-function: steps(var(--tel-n));
    animation-iteration-count: infinite;
}

/*  🔑 L'ANIMATION EST DÉCORATIVE, L'INFORMATION NE L'EST PAS.
 *  Deux éléments visuellement cachés, et ils ne font pas la même chose :
 *    · `#onglet-match-neuf` est DANS le bouton : tant que ça sonne, le nom
 *      accessible de l'onglet devient « Get in the game — new activity ». C'est
 *      un ÉTAT, qu'on retrouve en tabulant, à n'importe quel moment.
 *    · `#alerte-room` est une région live : c'est l'ÉVÉNEMENT, annoncé une
 *      seule fois par alerte (voir room.js). Deux mécanismes parce qu'un état
 *      ne s'annonce pas tout seul, et qu'un événement ne se relit pas.
 *  ⚠️ La recette du masquage visuel : surtout PAS `display: none` ni
 *  `visibility: hidden`, qui retirent le contenu de l'arbre d'accessibilité —
 *  une région live ainsi cachée n'annonce plus rien du tout. */
#onglet-match-neuf,
#alerte-room {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip-path: inset(50%);
    white-space: nowrap;
}
/*  Même piège que `#onglet-match` : room.js bascule cet élément avec `hidden`,
    et la règle ci-dessus pose déjà `position`, pas `display` — mais on referme
    explicitement, sinon un `display` ajouté un jour au bloc ci-dessus laisserait
    « new activity » collé au nom de l'onglet en permanence. */
#onglet-match-neuf[hidden] { display: none; }

/*  🔑 ON COUPE LE MOUVEMENT, PAS LE SIGNAL. Le téléphone reste AFFICHÉ à la
 *  place du lien, figé sur sa première image : c'est le CHANGEMENT D'ICÔNE qui
 *  dit qu'il se passe quelque chose, et il se voit sans qu'un pixel ne bouge.
 *  C'est aussi pour ça que le téléphone remplace le lien au lieu de s'ajouter
 *  à côté — une alerte qui ne tiendrait qu'à une animation disparaîtrait
 *  purement et simplement ici. Le nom du bouton et la région live, eux, ne
 *  dépendent d'aucune animation et sont inchangés.
 *
 *  🚨 LE SÉLECTEUR EST RÉPÉTÉ AVEC `[data-sonnerie]`, ET CE N'EST PAS UNE
 *  MALADRESSE. Un simple `#onglet-match-icone::after` pèse moins lourd que
 *  `#onglet-match[data-sonnerie] #onglet-match-icone::after` qui pose
 *  l'animation du téléphone : il perdrait la cascade, et le seul cas où couper
 *  le mouvement compte vraiment — la sonnerie — resterait animé. Le genre de
 *  panne qu'on ne voit jamais, puisqu'il faut activer « réduire les animations »
 *  ET faire sonner l'onglet pour la constater. */
@media (prefers-reduced-motion: reduce) {
    #onglet-match #onglet-match-icone,
    #onglet-match[data-sonnerie] #onglet-match-icone,
    #onglet-match[data-sonnerie] #onglet-match-icone::after { animation-name: none; }
}

/* ==========================================================================
   L'EN-TÊTE DE LA ROOM
   ==========================================================================
   🔑 CE QU'ON DOIT LIRE EN UN COUP D'ŒIL, ET DANS CET ORDRE : à quel jeu, sur
   quelle plateforme, dans quel mode et quel format, et avec qui. C'était une
   ligne de texte concaténé (« Worms Armageddon · Intermediate · 1v1 ») ; le jeu
   a un logo, la plateforme a un glyphe, et les deux se reconnaissent plus vite
   qu'ils ne se lisent. */

#vue-planifiee .room-entete,
#vue-match .room-entete {
    display: flex; align-items: flex-start; flex-wrap: wrap;
    gap: .5rem .9rem;
}
#vue-planifiee .room-identite { flex: 1 1 16rem; min-width: 0; }
#vue-match .room-identite { flex: 1 1 16rem; min-width: 0; }
/*  Les tags d'intention filent à droite, et repassent sous le bloc quand la
    carte devient étroite plutôt que d'écraser le nom du jeu. */
#vue-planifiee .room-entete .etiquettes { margin-left: auto; }
#vue-match .room-entete .etiquettes { margin-left: auto; }

/* ------------------------------------------------------- la plaque du jeu */

/*  🔑 LE MÊME MÉCANISME QUE LA GRILLE DE RECHERCHE, PAS UN SECOND.
 *  L'URL du logo vient du catalogue (`/api/catalogue`, champ `logo`), résolue
 *  côté serveur parce que lui seul sait quelle extension existe réellement —
 *  exactement ce dont se sert `dessinerJeux()` dans file.js. La couleur du jeu
 *  arrive de la même source, posée en `--teinte` sur la plaque comme elle l'est
 *  sur `.jeu-case`.
 *
 *  ⚠️ TAILLE VOLONTAIREMENT PLAFONNÉE. Deux vignettes du dossier sont opaques
 *  et laides — `w2.png` est une jaquette et non un wordmark, `wmd-mobilize.jpg`
 *  une vignette YouTube. C'est un chantier connu et séparé, on ne le règle pas
 *  ici ; mais la plaque ne dépasse pas la taille qu'a déjà une case de la
 *  grille, et son cadre sombre les contient au lieu de les laisser flotter en
 *  plein milieu de la carte. Les agrandir aurait été la seule vraie faute. */
#vue-planifiee .room-plaque,
#vue-match .room-plaque {
    position: relative; flex: none; overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    width: 124px; height: 68px;
    padding: .4rem .4rem .4rem .55rem;
    border: 1px solid var(--bord); border-radius: 8px;
    background: rgba(0, 0, 0, .34);
}
/*  La barre de teinte, reprise de `.jeu-barre` : c'est elle qui distingue les
    jeux entre eux quand le logo, lui, ne le fait pas. */
#vue-planifiee .room-plaque::before,
#vue-match .room-plaque::before {
    content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
    background: var(--teinte, #8a8f9c);
}
#vue-planifiee .room-plaque img,
#vue-match .room-plaque img {
    display: block; max-width: 100%; max-height: 100%; width: auto; height: auto;
    object-fit: contain; object-position: center;
    /*  Les coins arrondis ne se voient que sur les vignettes OPAQUES — les
        wordmarks, eux, sont transparents et n'ont pas de coins. C'est
        exactement pour ces deux-là qu'ils sont posés : un rectangle plein à
        angles vifs au milieu d'une carte a l'air d'y avoir été collé. */
    border-radius: 4px;
    /*  🚨 PAS de image-rendering: pixelated : ce sont les vraies jaquettes des
        boutiques, lissées. Les rendre au plus proche voisin les crénellerait.
        Le pixel art, c'est les sprites de l'onglet et le décor, pas les logos. Même
        raisonnement que `.jeu-logo` dans style.css. */
    filter: saturate(.92);
}
/*  Le repli quand le jeu n'a pas de vignette : sa couleur et son nom court,
    plutôt qu'une icône cassée ou un trou dans la mise en page. */
#vue-planifiee .room-plaque-court,
#vue-match .room-plaque-court {
    font-size: .78rem; font-weight: 700; line-height: 1.2; text-align: center;
    color: var(--texte-doux);
}

/* ------------------------------------------------------------ les faits */

/*  Les pastilles : plateforme, mode, format. Une par fait, jamais une phrase
    concaténée — on les compare d'un regard au lieu de les lire. */
#vue-planifiee .room-faits,
#vue-match .room-faits {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: .35rem; margin: .35rem 0 .3rem;
}
#vue-planifiee .room-fait,
#vue-match .room-fait {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .22rem .6rem;
    background: rgba(0, 0, 0, .28);
    border: 1px solid var(--bord); border-radius: 999px;
    font-size: .8rem; font-weight: 700; line-height: 1.4;
    color: var(--texte-doux);
}

/*  🚨 LA PLATEFORME N'EST PAS UNE DÉCORATION, ELLE DÉCIDE DU LANCEMENT.
 *  Sur PC c'est un lien `wa://` et WormNET ; sur console c'est une invitation
 *  par la liste d'amis, et rien d'autre ne marche (voir panneauConsole() dans
 *  room.js). Un joueur Switch qui ne la voit pas lit les instructions PC et
 *  n'arrive nulle part. Elle porte donc le jaune des caisses — le MÊME que la
 *  plateforme choisie sur l'écran de recherche (`.plateforme--choisie`), pour
 *  qu'on reconnaisse le choix qu'on vient de faire.
 *  ⚠️ Le texte est --ciel-haut et non `var(--fond)`, qui n'existe pas dans la
 *  palette : sur jaune il faut une couleur sombre, explicitement. */
#vue-planifiee .room-fait--plateforme,
#vue-match .room-fait--plateforme {
    color: var(--ciel-haut, #0a1830);
    background: var(--jaune); border-color: var(--jaune);
}

/*  Les glyphes de plateforme sont les SVG en ligne écrits pour l'écran de
    recherche (ICONES_PLATEFORME dans file.js) : on les réutilise tels quels,
    on ne les redessine pas.
    ⚠️ Ces quatre lignes recopient `.plateforme svg` de style.css. C'est
    volontaire : un SVG sans `stroke` ni dimensions ne s'affiche pas, et cette
    feuille ne doit pas dépendre du fait que la classe `.plateforme` soit posée
    ici — elle ne l'est pas, ce n'est pas un bouton mais une pastille. */
#vue-planifiee .room-fait svg,
#vue-match .room-fait svg {
    width: 15px; height: 15px; flex: none;
    fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
/*  Les touches PlayStation sont des formes pleines, pas des traits. */
#vue-planifiee .room-fait[data-plateforme="psn"] svg path:first-of-type,
#vue-match .room-fait[data-plateforme="psn"] svg path:first-of-type,
#vue-planifiee .room-fait[data-plateforme="psn"] svg path:nth-of-type(2) { fill: currentColor; }
#vue-match .room-fait[data-plateforme="psn"] svg path:nth-of-type(2) { fill: currentColor; }

/* ------------------------------------------------------------ avec qui */

/*  ⚠️ IL N'Y A PLUS DE LIGNE « Playing with X », donc plus de règle pour elle.
    Elle répétait la liste des occupants qui la suivait immédiatement, et elle
    la répétait FAUX : elle ne nommait qu'un adversaire, donc à trois ou quatre
    dans la salle elle en taisait deux. La liste (`.joueurs`, dans style.css)
    dit la même chose pour tout le monde, présence comprise. */

/* ------------------------------------------------------------- mobile */

@media (max-width: 640px) {
    /*  La plaque rétrécit avec la carte. On garde le rapport 124x68 : une
        plaque plus carrée recadrerait les logos larges en timbre-poste. */
    #vue-planifiee .room-plaque { width: 98px; height: 54px; }
    #vue-match .room-plaque { width: 98px; height: 54px; }
    #vue-planifiee .room-identite { flex: 1 1 12rem; }
    #vue-match .room-identite { flex: 1 1 12rem; }
    /*  Les tags reviennent à gauche : collés à droite sur 375 px, ils se
        retrouvaient seuls sur une ligne à moitié vide. */
    #vue-planifiee .room-entete .etiquettes { margin-left: 0; }
    #vue-match .room-entete .etiquettes { margin-left: 0; }
    /*  La barre d'onglets défile horizontalement ici : on resserre pour ne pas
        pousser les onglets suivants hors de vue plus tôt que nécessaire. */
    #onglet-match { gap: .35rem; }
}

/* ================================ L'ÉTAT DE LA SALLE, EN PIED D'EN-TÊTE
 *
 *  🔑 L'EN-TÊTE PORTE L'ÉTAT, LA CARTE DU BAS PORTE LES DÉCISIONS. C'est la
 *  règle demandée par le propriétaire, et elle REMPLACE celle de la version
 *  précédente : « We're starting », le repli de format et « Leave » avaient
 *  quitté la carte de la liste des salles pour venir se coller ici, à ce qui
 *  les motive. Le remède avait son propre défaut — DEUX boutons « Leave » à
 *  l'écran (celui-ci et celui de la carte du bas, avec « We played » et « It
 *  didn't work »), et une rangée de boutons plantée entre les gens présents et
 *  le mode d'emploi de lancement. Ne restent donc ici que les deux choses qui se
 *  LISENT : le remplissage « ●●○○ 2/4 » et l'état de départ de la partie.
 *
 *  ⚠️ Ces deux objets-là ne sont PAS restylés ici : leurs règles vivent dans
 *  salles.css, dont les groupes de sélecteurs ont été étendus à
 *  `#room-controles`. Le même fait doit se lire pareil dans la liste et dans la
 *  room ; deux jeux de règles finiraient par diverger.
 */

#room-controles {
    margin-top: .9rem;
    padding-top: .8rem;
    border-top: 1px solid var(--wa-cadre);
    display: grid;
    gap: .5rem;
}

/*  ------------------------------------------- LA SALLE PLANIFIÉE (§4.5)
 *
 *  🔑 LE MÊME ONGLET, LA MÊME PAGE, LE MÊME CHAT — un créneau prend le chemin
 *  d'une salle ordinaire, parce que c'est le même objet dans un autre état.
 *  Ce bandeau est tout ce qui change dans l'en-tête : il dit QUAND, dans le
 *  fuseau du lecteur, et il dit que rien n'a encore commencé.
 *
 *  ⚠️ Il vit dans `#room-controles`, qui porte ce qui se LIT (le remplissage,
 *  l'état de départ), et non dans la carte des décisions du bas : ce n'est pas
 *  un geste, c'est un état. Même partage que dans la liste des salles.
 */
/*  🚨 SURTOUT PAS `display: grid` ICI. Mesuré à l'écran : la grille met chaque
    ENFANT sur sa propre ligne, y compris les morceaux de texte nus, et le
    bandeau se lisait sur trois lignes — « Scheduled », puis « · Starts Sun
    30 Aug, 14:41 (CEST) · », puis « in 3 h ». Une date coupée en trois est
    exactement ce que cette section existe pour éviter. Un bloc ordinaire garde
    la phrase entière, et la laisse se replier là où elle veut. */
#room-controles .room-creneau {
    border-left: 3px solid var(--jaune);
    padding: .35rem 0 .35rem .7rem;
    font-size: .88rem;
    color: var(--texte-doux);
    line-height: 1.45;
}
#room-controles .room-creneau b { color: var(--jaune); }
/*  « Nothing starts yet » sur sa propre ligne : c'est la phrase qui empêche
    d'attendre devant l'écran une partie qui est dans huit jours. */
#room-controles .room-creneau-quoi {
    display: block;
    font-size: .82rem;
    opacity: .85;
    margin-top: .1rem;
}

#room-controles .room-controles-rangee {
    display: flex;
    align-items: center;
    gap: .8rem;
    flex-wrap: wrap;
}

/*  🚨 PLUS AUCUNE RÈGLE DE BOUTON SOUS `#room-controles`, ET C'EST LE POINT.
 *  Un bouton reposé ici recréerait le doublon de « Leave » qu'on vient de
 *  retirer ; les quatre gestes de la salle sont dans la carte du bas, ensemble.
 *
 *  « We're starting » y est seul dans son bloc : il ne fait pas partie de la
 *  même phrase que « When you're done », qui le suit. `:not(:empty)` parce que
 *  room.js vide ce bloc pour un ancien occupant — une marge sous un conteneur
 *  vide laisserait un trou que personne n'expliquerait. */
#vue-planifiee .room-depart:not(:empty) { margin-bottom: .9rem; }
#vue-match .room-depart:not(:empty) { margin-bottom: .9rem; }
