/* Phase 6 : le jeu devient interactif. Portrait d'abord, comme le demande
   CLAUDE.md — le plateau garde toujours la plus grande part de l'ecran ;
   la barre de statut reste fine et n'empiete pas dessus. */

/* Seuil de bascule telephone/ordinateur (phase 11, regle CLAUDE.md : "un
   seul seuil de bascule ... choisi une fois pour tout le projet"). 700px
   est plus large que n'importe quel telephone tenu en portrait, plus
   etroit que la plupart des ecrans d'ordinateur : au-dela, on considere
   qu'il y a la place d'afficher une barre laterale a demeure. Les phases
   d'interface suivantes (ex. phase 22, reglages) doivent reutiliser ce
   meme seuil plutot qu'en choisir un autre. */

:root {
  /* ===== REGLAGE : hauteur des boutons, champs et lignes a cocher =====
     Decide par saab (2026-09-24) : la place a l'ecran prime — "on perd de la
     place inutilement". 44px est le minimum conseille par Apple pour un doigt
     (ancienne regle de CLAUDE.md) ; 30px est la hauteur des boutons de pied de
     boite, deja validee par saab. LA seule valeur a changer pour tout essayer
     plus grand ou plus petit. */
  --hauteur-commande: 30px;
  /* Une ligne des listes Variantes / Puzzles / Mes parties (et son etoile). */
  --hauteur-ligne-liste: 24px;

  /* ===== REGLAGE : taille de l'apercu dans "Variantes", "Puzzles" et
     "Mes parties" =====
     C'est LA seule valeur a changer pour l'essayer plus grand ou plus
     petit ; elle vaut pour les trois dialogues a la fois et donne un carre
     (largeur = hauteur). Voir #apercu-variante plus bas pour pourquoi cette
     taille est figee et reservee en permanence.
     Reperes : 90px = tres compact, on distingue les camps sans plus ; 140px
     = l'ancienne valeur, lisible mais elle poussait la liste ; 120px est le
     compromis retenu par defaut. En dessous de ~70px, le dessin ne veut
     plus rien dire. */
  --taille-apercu: min(120px, 24vh);
  --taille-apercu: min(120px, 24dvh);

  /* Vert des DEMANDES : tout ce qui attend une reponse de l'utilisateur
     (choix d'une branche, confirmation, abandon/nulle) passe en vert, pour
     qu'on voie qu'il faut agir dessus (saab). Un seul vert, partout. */
  --vert-demande: #1f7a3a;
  /* Une case de piste d'ejection encore vide (.piste-case, et
     .piste-en-attente tant que sa bille vole vers elle). Reglable (saab,
     2026-09-26, "Fond eject") : interface/reglages.js pose ces 4 variables en
     direct depuis moteur/reglages.js, `kaah.*` (sans equivalent KAAWA) ; les
     valeurs ci-dessous sont leurs defauts, repris ici pour que la PREMIERE
     image (avant que ce script n'ait tourne) soit deja la bonne. */
  --fond-case-piste-vide: #8a8a8a;
  --fond-cadre-occurrences: #828282; /* "Fond Occ" */
  --couleur-coordonnee-bord: #cfcfcf; /* "Couleur coord plateau" */
  --couleur-coordonnee-bille: #e4e4e4; /* "Couleur coord bille noire" */
  --couleur-coordonnee-bille-blanche: #1f1f1f; /* "Couleur coord bille blanche" */
  --couleur-case-selectionnee: #c87f32; /* "Couleur bille sélect" */
  --couleur-case-arrivee: #00aa3e; /* "Couleur case arrivée" */
}

html {
  /* Dit au navigateur que cette page gere elle-meme ses couleurs sombres,
     pour qu'il n'essaie pas de les "corriger" tout seul (vu sur Opera :
     un mode sombre automatique qui eclaircit les couleurs a faible
     contraste, rendant les billes noires presque blanches). */
  color-scheme: dark;
}

html,
body {
  margin: 0;
  height: 100%;
  /* `svh` = "small viewport height" : la hauteur de la fenetre quand la
     barre d'adresse du telephone est DEPLOYEE. saab a signale que le bas de
     la page etait rogne par cette barre en portrait — c'est ce que fait
     `100%` (comme `100vh`), qui compte la hauteur SANS elle alors qu'elle
     reste affichee. `svh` est la seule des trois unites a ne jamais rogner
     ni sauter : `lvh` rogne pareil, `dvh` suit la barre et fait bouger toute
     la mise en page pendant qu'on fait defiler. `height: 100%` juste
     au-dessus reste comme repli pour un navigateur trop ancien pour `svh`
     (avant Safari 15.4 / Chrome 108). */
  height: 100svh;
  /* rappelle le bois sombre du plateau physique ; reglable (phase 22,
     board.app_bg_color, "fond de la fenetre") — voir index.html, ou cette
     variable est posee une fois a la construction, jamais en direct. */
  background: var(--couleur-fond-fenetre, #595959);
}

/* Bug trouve par saab : glisser sur un bandeau de titre (une simple ligne
   de texte, jamais concue pour etre selectionnee) demarre une SELECTION
   DE TEXTE plutot qu'un vrai glisser-deposer — celle-ci peut s'etendre
   sur toute la page (plateau, navigation...) et, combinee a une capture
   de pointeur restee engagee ailleurs (voir interface/sequence.js,
   activerRedimensionnementLargeur/Hauteur), a fini par bloquer tout clic
   nulle part, jusqu'au rechargement complet. Aucune de ces bandes n'a de
   texte utile a selectionner : autant empecher la selection d'y demarrer
   du tout, plutot que de compter uniquement sur le correctif de capture. */
h2,
button,
#etat-sauvegarde,
#position-copiable,
#arbre-entete,
#arbre-poignee-hauteur,
#arbre-poignee-largeur,
.nom-joueur,
.pendule-camp {
  user-select: none;
}

/* `display` de `body` (grid sur telephone, flex-row sur ordinateur) est
   declare ENTIEREMENT DANS chacune des deux media queries plus bas,
   jamais ici : deux valeurs concurrentes pour la meme propriete sur le
   meme selecteur, meme dans des media queries differentes, se
   departagent par ordre d'apparition dans le fichier plutot que par leur
   condition — piege deja rencontre 3 fois dans ce projet (voir
   #arbre-panneau plus bas). Aucune regle non conditionnelle ici change ce
   risque en certitude. #colonne-gauche, #colonne-principale et
   #arbre-panneau restent les memes elements HTML dans les deux cas :
   seule leur disposition change — et la barre de navigation, elle,
   change reellement de parent (voir interface/disposition.js), pour
   rester au bas du plateau sur telephone (le pouce) mais liberer cette
   hauteur au plateau sur ordinateur, ou elle rejoint le bas du panneau
   Sequence. */

/* Reservee pour de futurs boutons — la barre d'outils a 18 boutons de
   KAAWA doit bien aller quelque part (question ouverte de CLAUDE.md,
   jamais tranchee) ; premier occupant (phase 12) : les boutons de
   sauvegarde.
   Elle a retreci deux fois, toujours pour la meme raison — le plateau
   d'abord. D'abord `flex: 1 1 auto`, qui la faisait grandir TOUT LE TEMPS
   et pas seulement une fois le plateau a son maximum (185px mesures sur un
   ecran de 1000px pour des libelles qui en demandaient 110) ; puis les
   libelles eux-memes, remplaces par des icones dans les DEUX mises en page
   (voir plus bas) — 44px suffisent desormais partout. C'est #colonne-droite
   qui reste collee a droite quand il reste de la place (`margin-left: auto`,
   plus bas). */
#colonne-gauche {
  flex: 0 1 auto;
  min-width: 0;
  padding: 4px; /* reduit deux fois (8 -> 6 -> 4, saab : "diminue les paddings") */
}

/* Espace ENTRE les groupes (voir .groupe-boutons juste apres) : plus large
   que l'espace, resserre, entre deux boutons d'un MEME groupe — c'est ce
   qui fait lire "New" / "Mes parties, Variantes, Puzzles" / "Conseils" /
   "Sequence, Commentaires, Occurrences" / "Exporter, Importer" comme 5
   ensembles distincts plutot qu'une seule liste plate (demande precise de
   saab, avec cet ordre exact). */
#boutons-sauvegarde {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Le cadre visuel d'UN groupe : une bordure discrete, pas un fond distinct
   (la colonne entiere garde le meme fond sombre) — juste assez pour
   separer les groupes au coup d'oeil, meme en mode icones seules
   (telephone/paysage, ou les libelles sont invisibles et l'ordre des
   icones est le seul repere). */
.groupe-boutons {
  display: flex;
  flex-direction: column;
  gap: 4px;
  border: 1px solid #3a3a3a;
  border-radius: 8px;
  padding: 3px;
}

#boutons-sauvegarde button {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 6px;
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
}

/* Signal "actif" en orange, partage par tous les boutons bascule de cette
   colonne qui n'ouvrent pas de panneau propre a leur etat (Menaces,
   Conseils) : un appui montre/dessine, le meme reappui cache/efface (voir
   interface/menaces.js, interface/next-move.js). Meme orange que
   .bouton-favori-actif — un seul signal "actif" dans toute l'appli. */
#boutons-sauvegarde button.bouton-actif {
  background: #cc6a00;
  color: #0a0a0a;
  border-color: #cc6a00;
}

/* Reorganisation des groupes (interface/ordre-colonne.js) : ▲ en haut et ▼ en
   bas de chaque groupe, un ✓ vert en tete de colonne pour terminer — rien de
   tout cela hors du mode. Les vrais boutons, eux, ne repondent plus pendant ce
   temps (on deplace les groupes, on ne s'en sert pas). Selecteurs par
   #colonne-gauche : l'emportent sur `#boutons-sauvegarde button` (hauteur 36,
   flex) quel que soit l'ordre du fichier. */
#colonne-gauche .fleche-groupe {
  display: none;
  width: 100%;
  min-height: var(--hauteur-ligne-liste);
  padding: 0;
  background: #2a2a2a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 4px;
  font-size: 12px;
  cursor: pointer;
}

#colonne-gauche.colonne-en-reorganisation .fleche-groupe {
  display: block;
}

/* Colle en haut de la colonne pendant tout le defilement (bogue signale par
   saab, 2026-09-27) : sur telephone en paysage la colonne defile, on y
   descend pour atteindre Reglages, et le ✓ — seule sortie du mode — restait
   alors hors de l'ecran, au-dessus. */
#colonne-gauche #bouton-fin-reorganisation {
  position: sticky;
  top: 0;
  z-index: 1;
  min-height: var(--hauteur-commande);
  background: var(--vert-demande);
  border-color: var(--vert-demande);
  color: #ffffff;
  font-size: 16px;
}

.colonne-en-reorganisation .groupe-boutons {
  outline: 1px dashed #cc6a00;
}

.colonne-en-reorganisation .groupe-boutons > button:not(.fleche-groupe) {
  pointer-events: none;
  opacity: 0.45;
}

/* Les icones decochees (interface/choix-icones.js) : hors de la colonne, sauf pendant la
   reorganisation, ou tous les groupes se montrent pour que ▲ et ▼ fassent toujours ce qu'on voit. */
#colonne-gauche:not(.colonne-en-reorganisation) .icone-masquee,
#colonne-gauche:not(.colonne-en-reorganisation) .groupe-masque {
  display: none;
}

/* Reglages > Choix des icônes : une case, le dessin de l'icone sur le gris de la colonne, son nom. */
/* Un cadre par groupe, comme dans la colonne ; les cadres de haut en bas, puis la colonne suivante (deux au
   plus, une seule sur telephone) — l'ordre de la barre se lit en descendant. */
.liste-choix-icones {
  columns: 170px 2;
  column-gap: 8px;
  margin: 6px 0;
}

.groupe-choix-icones {
  break-inside: avoid;
  margin-bottom: 4px;
  padding: 0 6px;
  border: 1px solid #3a3a3a;
  border-radius: 8px;
}

.ligne-choix-icone {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: var(--hauteur-commande);
  cursor: pointer;
}

.ligne-choix-icone:has(input:disabled) {
  cursor: default;
  opacity: 0.6;
}

/* Le dessin d'une icone hors de la colonne (interface/choix-icones.js, dessinDeLIcone) : dans le Choix des
   icônes et dans l'Aide, sur le gris de la colonne. Plus petit que dans la colonne : les dessins et les
   hexagones (34 px) ; un emoji (18 px) y tient deja. */
.dessin-icone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 26px;
  height: 26px;
  margin-right: 4px;
  vertical-align: middle;
  background: #3a3a3a;
  border-radius: 4px;
  overflow: hidden;
}

.dessin-icone .icone-bouton:not(.icone-hexagone) svg,
.dessin-icone svg.icone-bouton {
  width: 20px;
  height: 20px;
}

.dessin-icone .icone-hexagone {
  transform: scale(0.72);
}

/* La couleur qu'une icone a par defaut dans la colonne, aussi hors d'elle (saab : « mettre en vert
   l'icone hamberger comme il est dans l'appli » ; « FàF aussi, tous ceux qui ont des couleurs par défaut
   doivent l'avoir dans Aide ») : le vert de ☰ (#bouton-etendre-colonne, sans dessin a copier : son
   caractere) et de Face-à-face tant qu'il n'est pas actif. L'orange d'une icone active, le vert de
   Correspondance en cours disent un etat du moment, pas sa couleur. */
.dessin-icone.dessin-icone-vert,
.dessin-icone[data-copie-de='bouton-face-a-face'] {
  background: var(--vert-demande);
  color: #ffffff;
}

.dessin-icone.dessin-icone-vert {
  font-size: 16px;
}

#bouton-choix-icones.bouton-actif,
#bouton-icones-simple.bouton-actif,
#bouton-icones-labalone.bouton-actif {
  background: #cc6a00;
  border-color: #cc6a00;
  color: #ffffff;
}

/* Face-a-face, seul bouton de la colonne a le signaler AINSI (saab,
   2026-09-25) : vert (le meme vert que toute demande en attente,
   --vert-demande) tant qu'il n'est PAS actif, pour inviter a l'essayer —
   l'orange de .bouton-actif ci-dessus reste la regle une fois actif, cette
   regle-ci ne s'applique donc que quand cette classe est absente. */
#bouton-face-a-face:not(.bouton-actif) {
  background: var(--vert-demande);
  color: #ffffff;
  border-color: var(--vert-demande);
}

.icone-bouton {
  font-size: 18px;
  line-height: 1;
}

/* Correspondance vert des qu'une partie par correspondance est en cours (saab ;
   interface/correspondance.js, actualiserBoutonCorrespondance) — le meme vert
   que tout ce qui attend un geste. L'icone (une enveloppe ouverte qui porte le
   nombre de parties en cours) est dessinee plus grande dans index.html. */
#bouton-correspondance.correspondance-en-cours {
  background: var(--vert-demande);
  color: #ffffff;
  border-color: var(--vert-demande);
}

/* Icone "en hexagone" (Nouvelle partie, Variantes, Puzzles, Mes parties) :
   clin d'oeil au plateau lui-meme, un hexagone fait de cases rondes —
   demande par saab, pour les 4 boutons qui CHOISISSENT ou CHARGENT une
   position de depart (une partie neuve, une variante, un puzzle, une
   partie deja jouee), a la difference des autres boutons de la colonne
   qui sont de simples actions/outils.
   `.icone-bouton.icone-hexagone` (2 classes, pas juste `.icone-hexagone`)
   BUG TROUVE (saab : "les icones sont que sur le haut du grand hexagone
   gris") : `.icone-bouton { display: inline; }` plus bas (regle du mode
   icones seules) a la MEME specificite qu'un `.icone-hexagone` a une
   seule classe et le suit dans le fichier — il l'emportait donc toujours,
   ecrasant le `inline-flex` necessaire au centrage et laissant l'emoji
   suivre le flux normal du texte (colle en haut). Piege de specificite
   deja rencontre plusieurs fois dans ce projet (voir CLAUDE.md) : 2
   classes suffisent a gagner quel que soit l'ordre des regles.
   Taille agrandie deux fois (24 -> 30 -> 34px, emoji 14 -> 22 -> 25px,
   saab la seconde fois : "bien centres mais ne remplissent pas le grand
   hexagone gris, en les agrandissant un peu ça devrait etre bon") pour
   que l'emoji couvre vraiment l'hexagone au lieu d'y laisser du gris
   visible sur les bords — 34px reste sous les 36px de hauteur du bouton
   lui-meme (#boutons-sauvegarde button, plus haut), rien ne deborde. */
/* Icones dessinees a la main de Sequence/Commentaires/Occurrences (voir
   index.html) : de vrais <svg>, pas du texte — `vertical-align` seul
   suffit a les centrer correctement dans le bouton flex, contrairement a
   un emoji qui suit `font-size`/`line-height` (voir .icone-bouton
   au-dessus). */
.icone-bouton.icone-carre {
  vertical-align: middle;
}

/* Fond gris CLAIR (#8a8a8a, signale par saab : "le gris des cases",
   meme couleur que .case sur le plateau) plutot que le gris fonce
   d'origine — desormais partagee par 4 boutons (Nouvelle partie,
   Variantes, Puzzles, Mes parties), les 4 qui CHOISISSENT ou CHARGENT une
   position de depart, jamais les simples actions/outils du reste de la
   colonne. */
.icone-bouton.icone-hexagone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  font-size: 25px;
  line-height: 1;
  background: #8a8a8a;
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}

/* Jauge du nombre de parties enregistrees (phase 12ter,
   interface/jauge-mes-parties.js) : un rectangle CENTRE SUR L'ICONE (pas un
   rond dans un coin, correctif saab) — `.icone-avec-jauge` (l'icone
   elle-meme, 25x25 dans son cadre de 34x34, jamais le bouton entier qui
   s'elargit avec son libelle en colonne deployee) porte `position:
   relative` pour l'ancrer en son centre. NEUTRE (gris, pas vert : "ne pas
   mettre en vert si <= n", saab — le vert suggerait a tort un signal
   positif) tant qu'on reste sous le seuil ; rouge seulement au-dela
   (reglable dans la boite "Mes parties"). */
.icone-avec-jauge {
  position: relative;
}

.badge-mes-parties {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -40%);
  min-width: 16px;
  height: 9px;
  padding: 0 3px;
  box-sizing: border-box;
  border-radius: 3px;
  background: #ffffff00;
  color: #ffffff;
  font: bold 9px sans-serif;
  line-height: 12px;
  text-align: center;
  pointer-events: none; /* ne gene jamais le clic sur le bouton lui-meme */
}

.badge-mes-parties-alerte {
  background: #b3261edd; /* meme rouge que le bouton Abandonner */
  color: #ffffff;
}
/* Le bouton Mes parties, badge rouge : entoure de vert (interface/jauge-mes-parties.js). */
.bouton-mes-parties-alerte {
  outline: 2px solid #45b862;
  outline-offset: -2px;
}

/* UNE BANDE D'ICONES, DANS LES DEUX MISES EN PAGE. Les libelles en toutes
   lettres n'existaient qu'ici, sur ordinateur, et coutaient ~100px de large
   au plateau en permanence pour sept mots qu'on lit une fois. saab a demande
   d'etendre au paysage et au PC le principe deja en place en portrait :
   icones a demeure, libelles a la demande. Le bouton "☰" les deploie
   temporairement PAR-DESSUS le plateau (position:fixed) plutot que
   d'elargir la colonne — sinon le plateau retrecirait a chaque ouverture,
   l'effet inverse de ce qu'on cherche. Le survol, lui, ne suffirait pas :
   un telephone n'a pas de curseur (CLAUDE.md, "rien d'important au survol
   seul") — d'ou un vrai bouton, et un `title` sur chaque icone en plus.
   Rien de tout ceci n'est dans une media query : ces proprietes n'ont
   qu'une seule valeur pour les deux mises en page, et les declarer sans
   condition evite le piege de specificite documente plus haut. */
/* Vert en PERMANENCE (saab, 2026-09-23) : contrairement aux autres boutons
   verts de KAAH (une demande precise en attente), celui-ci attend toujours
   un geste, dans les deux sens — voir les noms des boutons (ferme) ou les
   cacher (ouvert) — donc jamais gris. */
#bouton-etendre-colonne {
  display: block;
  min-height: 36px;
  background: var(--vert-demande);
  color: #ffffff;
  border: 1px solid var(--vert-demande);
  border-radius: 6px;
  font-size: 16px;
  cursor: pointer;
}

#boutons-sauvegarde button {
  justify-content: center;
  padding: 0 2px;
}

.icone-bouton {
  display: inline;
}

.libelle-bouton {
  display: none;
}

#colonne-gauche.colonne-gauche-etendue {
  position: fixed;
  inset: 0 auto 0 0;
  width: 200px;
  z-index: 20;
  box-shadow: 4px 0 12px rgba(0, 0, 0, 0.6);
}

.colonne-gauche-etendue .libelle-bouton {
  display: inline;
}

.colonne-gauche-etendue #boutons-sauvegarde button {
  justify-content: flex-start;
  padding: 0 6px;
}

/* Dialogues (phase 12, "Mes parties" ; phase 13, "Variantes") — classe
   commune plutot que deux blocs identiques : les deux sont des fenetres
   flottantes sur ordinateur (regle CLAUDE.md sur les popups) ; le fond
   assombri (::backdrop) et la fermeture par Echap sont geres par le
   navigateur lui-meme, <dialog> est natif. */
.dialogue {
  border: none;
  border-radius: 8px;
  background: #1a1a1a;
  color: #e4e4e4;
  /* Reduit (16px -> 8px, saab : "trop d'espace vide, ne pas gaspiller") */
  padding: 8px;
  width: 90vw;
  max-width: 480px;
  /* `border-box` : sans lui, la hauteur ne comptait pas le padding et un dialogue
     "plein ecran" depassait de 16 px. `dvh` : la hauteur VISIBLE du telephone (barre
     d'adresse comprise), alors que `vh` compte la page entiere et cachait le bas du
     dialogue — donc son bouton Fermer (saab). Le second `max-height` n'est lu que par
     les navigateurs qui connaissent `dvh`. */
  box-sizing: border-box;
  max-height: 96vh;
  max-height: 96dvh;
  overflow-y: auto;
}

/* Les dialogues a zone defilante (listes, aide, sons, fin de partie) : titre en
   haut, UNE zone qui defile au milieu, dernier element (Fermer) toujours visible en
   bas. `[open]` : sans lui, `display: flex` afficherait la boite meme fermee. */
.dialogue-grand[open] {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.dialogue-grand[open] > * {
  flex-shrink: 0; /* seule la zone defilante retrecit */
}

.dialogue-grand .liste-dialogue,
.dialogue-grand .aide-corps,
.dialogue-grand .options-fin,
.dialogue-grand #liste-sons,
.dialogue-grand .corps-reglages,
.dialogue-grand .corps-creation-partie,
.dialogue-grand .corps-position-my,
.dialogue-grand .corps-correspondance,
.dialogue-grand .corps-permutations,
.dialogue-grand .champ-notes-perso {
  flex: 1 1 auto;
  flex-shrink: 1;
  min-height: 0;
  max-height: none;
  overflow-y: auto;
}

.dialogue::backdrop {
  background: rgba(0, 0, 0, 0.6);
}

.dialogue h2 {
  margin: 0 0 6px;
  font-size: 16px;
}

/* Sous-titres de section (phase 22, Réglages) : plus discret qu'un h2, pas
   de bordure — juste de quoi séparer les groupes au coup d'œil. */
.dialogue h3 {
  margin: 12px 0 4px;
  font-size: 12px;
  color: #9a9a9a;
  text-transform: uppercase;
}

.dialogue h3:first-child {
  margin-top: 0;
}

/* Une ligne de couleur (phase 22) : le nom a gauche, le selecteur natif a
   droite — meme gabarit de 44px que .ligne-reglage. */
/* `display: flex` l'emporterait sinon sur l'attribut hidden (poids de la
   version 2 de l'IA, Reglages). */
.ligne-couleur[hidden] {
  display: none;
}

.ligne-couleur input[type='number'] {
  width: 64px;
  text-align: right;
}

.ligne-couleur {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: var(--hauteur-commande);
}

.ligne-couleur input {
  width: 44px;
  height: 32px;
  padding: 0;
  border: 1px solid #5a5a5a;
  border-radius: 4px;
  background: none;
  cursor: pointer;
}

/* Un curseur de Reglages (taille, transparence — saab, 2026-09-27) : meme
   gabarit que .ligne-couleur, le curseur sur la moitie droite. */
.ligne-curseur {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: var(--hauteur-commande);
}

.ligne-curseur input {
  flex: 0 1 50%;
  min-width: 90px;
}

/* Rubriques repliables de Reglages (saab, 2026-09-27,
   interface/reglages-rubriques.js) : un ▸ fermee, ▾ ouverte, pour voir d'un
   coup d'oeil ce qui est deplie (le triangle natif ne s'affiche pas partout). */
.rubrique-reglages {
  border-top: 1px solid #3a3a3a;
}

.rubrique-reglages[open] {
  padding-bottom: 6px;
}

/* Plus grand que le contenu (saab, 2026-10-04 : « ca ne ressort pas assez par
   rapport a son contenu »). */
.rubrique-reglages > summary {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: var(--hauteur-commande);
  font-size: 1.2em;
  font-weight: bold;
  cursor: pointer;
  list-style: none;
  /* En vert, comme les chapitres de l'Aide (saab, 2026-10-27 : « Mettre les Rubriques blanche en vert, car
     on ne les reconnaît pas bien qd c'est déplié, garder celles en orange ») : l'orange (et le jaune)
     plus bas l'emportent. */
  color: #45b862;
}

.rubrique-reglages > summary::-webkit-details-marker {
  display: none;
}

.rubrique-reglages > summary::before {
  content: '▸';
  width: 1em;
  color: #9a9a9a;
}

.rubrique-reglages[open] > summary::before {
  content: '▾';
}

/* Ce qui differe de Défaut, en orange (phase 31, saab) : la ligne du reglage
   et le titre de sa rubrique (interface/reglages-champs.js,
   marquerReglagesModifies) — le meme orange que .bouton-actif. */
.reglage-modifie,
.legende-modifie,
.rubrique-reglages.rubrique-modifiee > summary {
  color: #cc6a00;
}

/* Profils IA (saab, 2026-09-30, interface/reglages-ia.js) : apres Valider,
   vert pour la derniere validation, jaune pour les plus anciennes. */
.reglage-valide-dernier,
.legende-dernier {
  color: #45b862;
}

.reglage-valide-ancien,
.legende-ancien {
  color: #d9b62b;
}

/* Le profil, hors des rubriques et hors de la zone qui defile : toujours
   visible (saab, 2026-09-27). */
.ligne-profil-fixe {
  margin-bottom: 6px;
}

.barre-reglages-fichier {
  display: flex;
  gap: 8px;
}

.barre-reglages-fichier .bouton-dialogue {
  flex: 1 1 0;
  min-height: var(--hauteur-commande);
  margin-top: 0;
}

/* Choix du profil (phase 22, interface/reglages.js) : la liste a gauche,
   Supprimer a droite (alerte sur "Défaut", jamais supprimable). La liste des
   bases de coups (interface/bases-coups.js) a le meme aspect, sur toute la
   largeur : ses noms de fichier sont longs. */
.ligne-profil {
  display: flex;
  gap: 8px;
  align-items: center;
}

.select-base-coups {
  width: 100%;
  margin-bottom: 6px;
}

#select-profil-reglages,
.select-base-coups {
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--hauteur-commande);
  background: #2a2a2a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  font-size: 14px;
}

/* Boite « Créer une partie » (phase 23, interface/creation-partie.js) : un
   libelle AU-DESSUS de chaque champ (une position ou une suite de coups est
   trop longue pour tenir a cote de son libelle), champs a pleine largeur. */
.ligne-creation {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 10px;
  font-size: 13px;
  color: #c4c4c4;
}

.ligne-creation input,
.ligne-creation textarea {
  box-sizing: border-box;
  width: 100%;
  min-height: var(--hauteur-commande);
  padding: 6px 8px;
  background: #2a2a2a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  font: 14px monospace;
}

.ligne-creation textarea {
  resize: vertical;
}

/* Boite « My » (phase 23bis, interface/formulaire-position-my.js). Le plateau
   de la boite prend toute la largeur disponible, plafonne pour que le
   formulaire reste en vue sur ordinateur : sur telephone (plein ecran), il
   donne aux cases la meme taille que le grand plateau. */
#plateau-position-my {
  display: block;
  width: min(100%, 420px);
  margin: 0 auto;
  cursor: pointer;
}

.ligne-ejections-my {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin-bottom: 10px;
  font-size: 13px;
  color: #c4c4c4;
}

.ligne-ejections-my label {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: var(--hauteur-commande);
}

.types-variante-my {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  margin-bottom: 10px;
}

.ligne-case-type {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--hauteur-commande);
  font-size: 13px;
  color: #c4c4c4;
}

.ligne-case-type input {
  width: 20px;
  height: 20px;
}

.ligne-choix-my {
  align-items: center;
  margin-bottom: 6px;
}

.libelle-choix-my {
  min-width: 70px;
  font-size: 13px;
  color: #c4c4c4;
}

/* Le nom final et la position enregistree, en direct (une ligne chacun). */
.resume-position-my {
  margin: 6px 0 0;
  font: 13px monospace;
  color: #e4e4e4;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* Boites de correspondance (phase 24, interface/correspondance.js et
   interface/code-correspondance.js). */
.ligne-choix-my .bouton-dialogue {
  margin-top: 0;
}

.titre-section-correspondance {
  margin: 10px 0 4px;
  font-size: 14px;
}

/* La liste « En cours » (interface/correspondance-en-cours.js) : une ligne par
   partie, touchee pour l'ouvrir ; elle defile elle-meme si elles sont
   nombreuses, la boite garde sa taille. */
.liste-en-cours-correspondance {
  max-height: 30vh;
  overflow-y: auto;
  margin: 4px 0;
}

.ligne-en-cours-correspondance {
  min-height: var(--hauteur-ligne-liste);
  cursor: pointer;
}

.texte-code-correspondance {
  box-sizing: border-box;
  width: 100%;
  padding: 6px 8px;
  background: #102010;
  color: #e4ffe4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  font: 13px monospace;
  resize: vertical;
  overflow-wrap: anywhere;
}

.texte-code-correspondance[hidden] {
  display: none;
}

/* Popup Permutations (phase 25, interface/permutations.js) : un tableau a 2
   colonnes (Permut / Camp_Permut), comme celui de KAAWA. */
.tableau-permutations {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font: 11px monospace;
}

.ligne-permutation {
  display: flex;
  gap: 6px;
}

.ligne-permutation-entete {
  font: 12px sans-serif;
  font-weight: bold;
  color: #9a9a9a;
  margin-bottom: 4px;
}

.ligne-permutation-entete span {
  flex: 1 1 0;
}

.cellule-permutation {
  flex: 1 1 0;
  min-width: 0;
  padding: 3px 4px;
  background: transparent;
  color: #c4c4c4;
  border: 1px solid transparent;
  border-radius: 4px;
  font: inherit;
  text-align: left;
  overflow-wrap: anywhere;
  cursor: pointer;
}

.cellule-permutation:hover {
  border-color: #5a5a5a;
}

/* La ligne qui correspond a la position CANONIQUE (posRef) — meme orange que
   .bouton-actif/.arbre-courant ailleurs dans KAAH (jamais le jaune de KAAWA,
   deja pris par autre chose ici). */
.cellule-permutation-posref {
  color: #cc6a00;
  font-weight: bold;
}

.posref-permutations {
  margin: 6px 0 0;
  font: 12px monospace;
  color: #cc6a00;
  overflow-wrap: anywhere;
}

/* Apercu d'une permutation (phase 25) : petite barre FIXE en bas de l'ecran,
   non modale (voir index.html, .show() plutot que .showModal()) — le plateau
   derriere doit rester visible et cliquable (Retour excepte, le jeu est
   suspendu pendant l'apercu, interface/saisie.js). */
.dialogue-apercu-permutation {
  position: fixed;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  margin: 0;
  width: min(92vw, 480px);
  max-width: none;
  padding: 8px 10px;
  background: #1a1a1a;
  color: #e4ffe4;
  border: 1px solid #5a5a5a;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
}

.dialogue-apercu-permutation[open] {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

#texte-apercu-permutation {
  font: 12px monospace;
  overflow-wrap: anywhere;
}

.champ-invalide {
  border-color: #e04040 !important;
}

#section-variante-my[hidden],
#section-puzzle-my[hidden] {
  display: none;
}

/* Le rouge des alertes de KAAH (.pendule-alerte) : le coup qui arrete la
   construction, avec son rang. */
.erreur-creation {
  margin: 6px 0 0;
  color: #e04040;
  font-weight: bold;
  font-size: 13px;
}

.note-reglages {
  margin: 2px 0 0;
  font-size: 12px;
  color: #9a9a9a;
}

/* Pied de la boite Réglages (phase 22, corrigee deux fois) : Défaut/
   Annuler/Sauver.../Fermer — TOUJOURS visible (.dialogue-grand, plus haut).
   CORRIGE (saab : "tes boutons sont trop longs... et trop hauts, la ligne
   Exporter touche la ligne Défaut") : largeur au contenu (`flex: 0 0 auto`,
   plus de `min-width` ni de `flex-grow` qui les etirait pour rien), hauteur
   ramenee au gabarit de .bouton-dialogue (30px, comme tous les autres pieds
   de dialogue de KAAH — le 44px d'avant n'etait pas justifie ici) et une
   separation visible (bordure) d'avec la zone qui defile juste au-dessus. */
.pied-reglages {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-top: 8px;
  margin-top: 4px;
  border-top: 1px solid #3a3a3a;
}

.pied-reglages .bouton-dialogue {
  flex: 0 0 auto;
  margin-top: 0;
}

/* Poignee de la boite Réglages (saab : elle masquait le plateau) : son
   propre titre, glisse-le pour la deplacer — voir interface/reglages.js,
   rendreDeplacable. */
#poignee-reglages {
  cursor: move;
  user-select: none;
}

/* Jamais de voile sombre sur CETTE boite (saab : "ca fausse les couleurs
   qu'on regle") — seule exception a .dialogue::backdrop, plus haut. */
#dialogue-reglages::backdrop {
  background: transparent;
}

.bouton-dialogue {
  min-height: var(--hauteur-commande);
  /* 6px : saab, les boutons avaient trop de vide autour du libelle — la place
     est comptee partout. */
  padding: 0 6px;
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  margin-top: 6px;
}

/* Dialogue de confirmation (interface/confirmation.js) : ses deux boutons
   cote a cote plutot qu'empiles l'un sous l'autre (le comportement par
   defaut de .bouton-dialogue, pense pour un seul bouton "Fermer"). */
.boutons-dialogue-cote-a-cote {
  display: flex;
  flex-wrap: wrap; /* 5 boutons dans Variantes/Puzzles : 2 lignes sur telephone plutot qu'un debordement */
  gap: 6px;
}

/* Plein ecran sur telephone, meme si les boutons qui ouvrent ces
   dialogues n'existent encore que sur ordinateur (#colonne-gauche) —
   regle CLAUDE.md ("les popups deviennent des panneaux plein ecran sur
   telephone"), appliquee par avance pour ne pas avoir a y repenser le
   jour ou ces boutons deviennent accessibles sur telephone aussi. */
@media (max-width: 699px) {
  #dialogue-mes-parties,
  #dialogue-variantes,
  #dialogue-puzzles,
  #dialogue-creation-partie,
  #dialogue-position-my,
  #dialogue-correspondance,
  #dialogue-permutations,
  #dialogue-corbeille,
  #dialogue-notes-perso,
  .dialogue-aide {
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    max-width: none;
    max-height: none;
    border-radius: 0;
  }

  /* `[open]` INDISPENSABLE ici, pas seulement `.dialogue` : un <dialog>
     ferme vaut `display:none` par la feuille de style du navigateur, et
     une simple classe (.dialogue) l'emporte sur cette regle-la. Sans
     `[open]`, les TROIS dialogues restaient donc affiches en permanence,
     ouverts ou non — bug signale par saab sur telephone (popup "toujours
     la", meme apres "Fermer", meme apres un rechargement complet ; boutons
     qui s'allument sans effet visible ; apercu des variantes qu'il fallait
     aller chercher en faisant defiler la page, puisque trois boites de
     828 px s'empilaient dans le flux). Introduit au correctif precedent en
     voulant regler le debordement de "Mes parties" ci-dessous : la mise en
     colonne etait bonne, c'est de l'avoir posee sur l'etat FERME aussi qui
     ne l'etait pas.

     Raison d'etre de cette mise en colonne : sans elle, le titre, la liste
     et le bouton s'empilent dans le flux normal — une longue liste peut
     alors depasser les 100vh fixes du dialogue et pousser le haut hors de
     l'ecran. En colonne flex avec overflow cache, seule .liste-dialogue
     (flex:1, voir plus bas) peut deborder, et elle defile toute seule. */
}

/* Liste a l'interieur d'un dialogue (les parties enregistrees, les
   variantes...) : meme comportement de defilement partout. */
.liste-dialogue {
  max-height: 50vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ligne-liste {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 1px 0;
  border-bottom: 1px solid #3a3a3a;
  font-size: 12px;
}

.ligne-liste-texte {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}

.ligne-liste button {
  flex: 0 0 auto;
  min-height: var(--hauteur-ligne-liste);
  padding: 0 5px;
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
}

/* Suppression de plusieurs parties (interface/mes-parties.js) : la barre de
   boutons au-dessus de la liste, et la case a cocher de chaque ligne (assez
   grande pour le doigt : 22 px dans une zone de 44 px de haut). */
.barre-parties {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 4px 0;
}

.barre-parties .bouton-dialogue {
  min-height: var(--hauteur-commande);
  margin-top: 0;
}

.barre-parties .bouton-dialogue:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Saab, 2026-10-04 : Exporter en vert (un geste sans risque), Supprimer en
   rouge (le meme que le bouton Abandonner) des qu'une partie est cochee. */
#bouton-exporter-parties:not(:disabled) {
  background: var(--vert-demande);
  border-color: var(--vert-demande);
}

#bouton-supprimer-parties:not(:disabled) {
  background: #b3261e;
  border-color: #b3261e;
}

.case-partie {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin: 0 4px;
  cursor: pointer;
}

/* Remplace "Tout selectionner"/"Tout deselectionner" (correctif, saab) :
   une case a cocher (comme celles des lignes) + un bouton ▶/▼ qui deplie le
   choix du filtre — voir interface/mes-parties.js. */
.groupe-selection-parties {
  display: flex;
  align-items: center;
  min-height: var(--hauteur-commande);
}

.bouton-repli-parties {
  min-width: 44px;
  min-height: var(--hauteur-commande);
  background: none;
  border: none;
  /* Vert tant qu'on ne s'en est pas servi (saab : "pour bien montrer qu'on doit
     le cliquer pour commencer les selections"), orange tant qu'un filtre cache
     des parties (.filtre-actif, plus bas). */
  color: #3fcf7a;
  font-size: 14px;
  cursor: pointer;
}

/* `:not([hidden])` INDISPENSABLE : `display: flex` sans lui l'emporterait
   sur le `display: none` que `[hidden]` pose (meme piege deja rencontre
   avec les dialogues plein ecran, voir plus haut) — le panneau resterait
   affiche en permanence, replie ou non. */
.panneau-filtre-selection:not([hidden]) {
  display: flex;
  flex-direction: column;
  margin: 0 0 4px;
  padding: 4px 8px;
  background: #2a2a2a;
  border-radius: 6px;
}

.panneau-filtre-selection label {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: var(--hauteur-ligne-liste);
  cursor: pointer;
}

/* Filtre de Mes parties (interface/filtre-parties.js) : une ligne par element
   du titre — case, libelle, champ. */
.filtre-parties-branches {
  display: flex;
  flex-wrap: wrap;
  gap: 0 10px;
}

.panneau-filtre-selection .filtre-parties-ligne {
  display: grid;
  grid-template-columns: auto 6.5em minmax(0, 1fr);
  min-height: var(--hauteur-ligne-liste);
}

.filtre-parties-ligne input[type='text'],
.filtre-parties-ligne input[type='number'] {
  min-width: 0;
  min-height: var(--hauteur-ligne-liste);
  padding: 0 6px;
  background: #1f1f1f;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 4px;
  font-size: 12px;
}

/* Un filtre cache des parties : le bouton ▶/▼ le rappelle, en orange. */
.bouton-repli-parties.filtre-actif {
  color: #e8a33d;
}

.filtre-parties-aide {
  margin: 4px 0;
  color: #9a9a9a;
  font-size: 11px;
}

/* Seuil de la jauge "Mes parties" (correctif, saab : deplace de "Réglages"
   ici) — voir interface/jauge-mes-parties.js. */
.ligne-seuil-jauge {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-height: var(--hauteur-commande);
  font-size: 13px;
  color: #c4c4c4;
}

.ligne-seuil-jauge input {
  width: 50px;
  min-height: 32px;
  font-size: 14px;
  text-align: center;
}

.ligne-partie {
  min-height: var(--hauteur-ligne-liste);
}

/* Une ligne garde la hauteur de son titre (saab, 2026-10-01 : dans Mes
   parties, les titres sur deux lignes se superposaient) : sans cela, quand la
   liste manque de hauteur, la colonne flex ecrase chaque ligne jusqu'a son
   min-height, et le texte deborde sur la suivante. C'est la liste qui defile. */
.liste-dialogue > * {
  flex-shrink: 0;
}

/* Mes parties plus large sur ordinateur (saab : « voir aussi pour elargir le
   champ ») : un titre tient alors le plus souvent sur une ligne. */
@media (min-width: 700px) {
  #dialogue-mes-parties {
    max-width: 760px;
  }
}

/* La partie active (celle qu'on est en train de jouer), ou la variante
   qu'on vient de previsualiser (un premier clic charge un second clic la
   confirme, voir interface/variantes.js) : meme orange que
   .arbre-courant/.au-trait ailleurs dans KAAH, meme signal "c'est ici
   que je suis en ce moment". */
.ligne-partie-active,
.ligne-partie-previsualisee,
.ligne-variante-previsualisee {
  border-left: 3px solid #cc6a00;
  padding-left: 6px;
}

/* Mais la ligne previsualisee se charge (ou se joue) si on la retouche : en VERT, comme ce qui
   attend un geste sans danger (saab, 2026-10-22 : « en vert aussi son label car si on reclic il
   se chargera »). */
.ligne-partie-previsualisee,
.ligne-variante-previsualisee {
  border-left-color: var(--vert-demande);
  color: #3fcf7a;
}

/* Avertissement affiche seulement pendant une confirmation de reprise
   automatique (interface/mes-parties.js, ouvrirPourConfirmationReprise) —
   meme orange que le reste des signaux "c'est ici" de KAAH. */
.message-reprise {
  margin: 0 0 6px;
  padding: 4px 6px;
  border-radius: 6px;
  background: #3a2a10;
  color: #e8a33d;
  font-size: 12px;
  font-weight: bold;
}

/* Le prefixe Br_ du titre de la partie, en violet comme KAAWA (#8000ff,
   kaa_board_widget_ClO_Co.py) : la partie a des branches d'analyse. */
.prefixe-branche {
  color: #8000ff;
  font-weight: bold;
}

/* Rappel "touchez une pendule" (phase 27) : meme vert que ce que les
   pendules demandent elles-memes (--vert-demande, voir CLAUDE.md,
   "tout ce qui attend une reponse de votre part est en vert"), affiche/
   masque par interface/pendules.js (signalerEtatPause). CORRIGE (saab,
   2026-09-25) : toujours place juste apres #navigation par interface/
   disposition.js, jamais au-dessus du plateau (ou apparaitre/disparaitre lui
   faisait changer de taille, #plateau etant en `height: 100%` d'un flex
   item) — `flex: 0 0 auto` pour ne jamais s'etirer ni se comprimer a cote de
   #navigation, marge en HAUT (plus de raison d'en avoir en bas, il n'est
   plus jamais suivi du plateau). Clignote comme "Gagné"/"Perdu" (saab ;
   @keyframes clignoter-fin, plus bas) : relance a chaque reapparition, un
   element masque par `hidden` reprenant son animation depuis le debut. */
.message-demarrage {
  flex: 0 0 auto;
  margin: 6px 0 0;
  padding: 4px 6px;
  border-radius: 6px;
  background: #12321f;
  color: #3fcf7a;
  font-size: 12px;
  font-weight: bold;
  text-align: center;
  animation: clignoter-fin 0.8s ease-in-out 8;
}

.ligne-rappel {
  display: block;
}

.ligne-partie-label {
  flex: 0 0 auto;
  color: #cc6a00;
  font-weight: bold;
}

/* Etoile favori (interface/variantes.js) : ★ et ☆ se confondent presque
   a la taille normale des boutons (signale par saab) — agrandie et
   distinguee surtout par la couleur, pas seulement par le caractere.
   Grise et discrete quand vide, VERTE pleine quand favorite.
   BUG TROUVE (saab : "tu n'as pas agrandi l'etoile ni mis en vert" — la
   toute premiere correction n'avait en realite jamais pris effet) :
   `.ligne-liste button` (element + classe, specificite 0,1,1) l'emportait
   silencieusement sur `.bouton-favori` (classe seule, 0,1,0) pour
   font-size ET color, quel que soit l'ordre du fichier — exactement le
   piege de specificite deja rencontre plusieurs fois dans ce projet.
   `.ligne-liste button.bouton-favori` (element + 2 classes) corrige ca en
   etant, cette fois, reellement plus specifique. */
.ligne-liste button.bouton-favori {
  min-width: var(--hauteur-ligne-liste);
  font-size: 16px;
  line-height: 1;
  color: #8a8a8a;
}

/* 3 classes (pas 2) : garantit de l'emporter sur la regle de base
   ci-dessus quel que soit l'ordre du fichier, meme si les deux ont ici la
   meme specificite "sur le papier" avec seulement 2 classes chacune —
   voir CLAUDE.md, jamais compter sur l'ordre entre regles de meme poids. */
.ligne-liste button.bouton-favori.bouton-favori-actif {
  color: #2ecc55;
  border-color: #2ecc55;
}

/* Apercu de la position previsualisee, dans "Variantes" comme dans
   "Puzzles" (interface/variantes.js, interface/puzzles.js) : un second
   <svg>, independant du plateau principal — jamais anime, jamais partage
   avec lui (voir CLAUDE.md, un seul plateau persistant).
   TAILLE FIGEE, et surtout RESERVEE EN PERMANENCE, meme quand aucun apercu
   n'est affiche : c'est tout l'objet du reglage ci-dessous. Sans ca,
   l'apercu apparaissait au premier clic et poussait toute la liste vers le
   bas — la ligne qu'on venait de choisir partait hors ecran et il fallait
   faire defiler pour la retrouver et la confirmer (signale par saab). Il
   occupe donc sa place des l'ouverture, pleine ou vide, et plus rien ne
   bouge entre les deux clics. */
/* Un apercu montre (pas vide) se touche pour charger : encadre de vert (saab, 2026-10-22 :
   « encadrer les mini plateaux en vert pour savoir qu'on peut cliquer dessus ») ; de meme
   l'image d'un jeu d'Entrainement qui lance le seul sens jouable (interface/entrainement-ceintures.js). */
#apercu-variante:not(:empty),
#apercu-puzzle:not(:empty),
#apercu-partie:not(:empty),
.apercu-cliquable {
  outline: 3px solid var(--vert-demande);
  outline-offset: -1px;
  cursor: pointer;
}

#apercu-variante,
#apercu-puzzle,
#apercu-partie {
  display: block;
  flex: 0 0 auto;
  width: var(--taille-apercu);
  height: var(--taille-apercu);
  margin: 0 auto 6px;
  background: #2b2b2b;
  border-radius: 6px;
  /* Cliquer l'apercu vaut confirmation (idee de saab) : le curseur le dit. */
  cursor: pointer;
}

/* Panneau "Choisir une branche" (interface/embranchement.js) : MEME regle
   que #panneau-conseils juste en dessous (jamais un <dialog> qui recouvre
   le plateau) — voir l'en-tete de ce fichier-la pour l'historique. Premier
   enfant de #colonne-droite dans le HTML : s'affiche donc EN HAUT de cette
   colonne par defaut, au-dessus des autres panneaux (signale par saab,
   "place ta fenetre sur les autres fenetres mais pas sur le plateau"),
   comme le popup de bifurcation de KAAWA lui-meme (positionne en haut a
   droite). `order: -2` sur telephone (voir plus bas) : encore au-dessus du
   `order: -1` de #panneau-conseils, pour rester le plus prioritaire des
   deux si jamais les deux etaient ouverts en meme temps. */
#panneau-embranchement {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: 4px;
  background: #1a1a1a;
  color: #e4e4e4;
  font: 13px/1.2 sans-serif;
  border-bottom: 1px solid #3a3a3a;
}

/* Une demande en attente de reponse : en vert (voir --vert-demande). */
#panneau-embranchement,
#dialogue-confirmation,
#dialogue-fin-de-partie {
  background: var(--vert-demande);
}

#panneau-embranchement h2 {
  margin: 0 0 2px;
  font-size: 14px;
}

#panneau-embranchement[hidden] {
  display: none;
}

/* Une branche par ligne : "▲" (Remonter, invisible si moteur.
   peutRemonterNoeud le refuse — reserve quand meme sa place, meme regle
   que .arbre-repli/.arbre-supprimer dans la Sequence) puis le coup
   lui-meme (Valider), qui prend le reste de la largeur. */
.ligne-embranchement {
  display: flex;
  align-items: center;
  gap: 4px;
}

.ligne-embranchement .bouton-dialogue {
  flex: 1;
  margin-top: 0;
}

/* La branche qu'on vient de "Remonter" (interface/embranchement.js) : un
   encadrement, pas un fond — le meme principe que .arbre-courant (le coup
   actif) ailleurs dans KAAH, mais PAS en orange (signale par saab,
   "l'orange" designant deja autre chose partout dans l'appli) : le gris
   clair des cases du plateau (.case), pour rester un signal neutre de
   "c'est celle-ci qui bouge" plutot qu'un signal de "camp"/"actif". */
.bouton-dialogue-remontee {
  outline: 2px solid #8a8a8a;
  outline-offset: -2px;
}

/* Panneau "Conseils" (phase 15, interface/next-move.js). N'est PLUS une
   popup : il l'a ete (centre, puis colle en bas a droite, puis en haut a
   droite) et c'etait a chaque fois la mauvaise piste — ce panneau sert a
   lire des fleches DESSINEES SUR LE PLATEAU, le recouvrir cache
   exactement ce qu'on veut voir (saab : "le plus important dans cette
   appli c'est de voir le plateau... c'est pas vraiment pratique, non ?").
   Il prend donc sa place DANS la mise en page, comme #arbre-panneau :
   a cote du plateau sur ordinateur, en dessous sur telephone (ou le
   plateau est plafonne a un carre, voir #plateau plus bas — il reste donc
   de la hauteur). Proprietes communes ici, placement dans chacune des deux
   media queries. */
#panneau-conseils {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0; /* sinon la liste interieure pousse le panneau au lieu de defiler */
  padding: 4px; /* resserre (6 -> 4, saab : "le plus serre possible autour du plateau") */
  background: #1a1a1a;
  color: #e4e4e4;
  font: 13px/1.2 sans-serif;
}

#panneau-conseils h2 {
  margin: 0 0 4px;
  font-size: 14px;
}

/* `[hidden]` doit l'emporter sur la regle ci-dessus (specificite d'un ID) :
   sans cette regle-ci, le panneau resterait affiche en permanence — c'est
   exactement le piege qui a fait rester les trois popups a l'ecran sur
   telephone au correctif precedent. */
#panneau-conseils[hidden] {
  display: none;
}

/* Panneau "Occurrences" (phase 18, suite, interface/occurrences.js) : MEME
   traitement que #panneau-conseils juste au-dessus — un panneau docke,
   jamais une popup. */
#panneau-occurrences {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  padding: 4px;
  background: #1a1a1a;
  color: #e4e4e4;
  font: 13px/1.2 sans-serif;
}

#panneau-occurrences h2 {
  margin: 0 0 4px;
  font-size: 14px;
}

/* Meme piege de specificite que #panneau-conseils[hidden] plus haut : voir
   ce commentaire-la, exactement la meme raison. */
#panneau-occurrences[hidden] {
  display: none;
}

#occurrences-entete {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 2px 0 6px;
  flex: 0 0 auto;
}

.compteur-occurrences {
  font-size: 12px;
  font-weight: bold;
  color: #9a9a9a;
}

/* Seuil de nulle atteint (meme SEUIL_NULLE que interface/nulle.js) : la
   couleur d'alerte deja etablie pour un compteur qui approche une regle du
   jeu (voir .piste-alerte, .nom-en-danger). */
.compteur-occurrences-seuil {
  color: #4aa8ff;
}

#liste-occurrences {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ligne-occurrence {
  min-height: 24px;
  padding: 0 6px;
  background: none;
  border: none;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}

.ligne-occurrence:hover {
  background: #2b2b2b;
}

/* Code couleur calque sur KAAWA (kaa_tab_manager_ClO_Co.py,
   setup_occurrences_tab) : PAS le meme code a 4 couleurs que la
   Sequence/Commentaires (courant/origine/chemin/branche, rendu/arbre-ligne.js)
   — ici, KAAWA ne distingue que la SECTION, jamais la branche individuelle
   de chaque ligne. Blanc pour Occ (position exacte), jaune attenue pour
   Ref (posRef seulement) — memes couleurs que la-bas ((1,1,1) et
   (0.8,0.8,0.5)). */
.ligne-occurrence-occ {
  color: #e4e4e4;
}

.ligne-occurrence-ref {
  color: #cccc80;
}

/* Seuil de nulle atteint sur CETTE ligne (son propre rang "oN" >=
   SEUIL_NULLE_PAR_DEFAUT, pas la section) : bleu par-dessus le blanc/jaune
   ci-dessus — demande par saab, "dans Occurrences on passe seulement
   o>=3 en bleu, on garde les couleurs existantes si o<3". 3 classes,
   comme .ligne-liste button.bouton-favori.bouton-favori-actif plus haut :
   l'emporte sur .ligne-occurrence-occ/-ref (2 classes chacune) quel que
   soit l'ordre du fichier. */
.ligne-occurrence-occ.ligne-occurrence-seuil,
.ligne-occurrence-ref.ligne-occurrence-seuil {
  color: #4aa8ff;
}

.separateur-occurrences {
  margin: 4px 0 2px;
  font-size: 11px;
  font-weight: bold;
  /* Meme olive attenue que le separateur "--- Ref ... ---" de KAAWA
     ((0.6, 0.6, 0.3)), pas le gris neutre utilise ailleurs pour ce genre
     de texte secondaire. */
  color: #999933;
}

/* Barre d'outils du mode Commentaires (phase 18, interface/commentaires.js) :
   recherche, tout replier/deplier, copier — masquee en mode Sequence (voir
   interface/saisie.js, `elementsCommentaires.barre`). Meme piege de
   specificite que #panneau-conseils[hidden] plus haut : `[hidden]` doit
   l'emporter sur la regle de disposition ci-dessous. */
#commentaires-barre,
#sequence-barre {
  display: flex;
  gap: 4px;
  padding: 4px 0;
  flex: 0 0 auto;
}

#commentaires-barre[hidden],
#sequence-barre[hidden] {
  display: none;
}

#commentaires-recherche {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 24px;
  padding: 0 6px;
  background: #2b2b2b;
  color: #e4e4e4;
  border: 1px solid #3a3a3a;
  border-radius: 4px;
  font-size: 12px;
}

#commentaires-repli-tout,
#commentaires-copier,
#sequence-barre button {
  flex: 0 0 auto;
  min-height: 24px;
  padding: 0 6px;
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 4px;
  font-size: 12px;
  cursor: pointer;
}

/* Meme conteneur que #arbre (mode Sequence) : les deux vivent cote a
   cote dans #arbre-panneau, un seul visible a la fois (voir
   interface/saisie.js, `basculerPanneauArbre`). */
#commentaires-liste {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 4px;
}

#commentaires-liste[hidden] {
  display: none;
}

.commentaires-lignes {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* UNE SEULE LIGNE par coup — etiquette et commentaire cote a cote, jamais
   l'un au-dessus de l'autre (signale par saab : ca doublait la hauteur de
   chaque ligne, surtout quand le commentaire est vide). */
.ligne-commentaire {
  display: flex;
  align-items: center;
  gap: 4px;
}

.bouton-repli-commentaire,
.bouton-deplier-commentaire {
  flex: 0 0 auto;
  min-width: 18px;
  min-height: 18px;
  padding: 0;
  background: none;
  border: none;
  color: #e4e4e4;
  font-size: 12px; /* comme .arbre-repli de la Sequence */
  cursor: pointer;
}

.bouton-repli-invisible {
  visibility: hidden;
  cursor: default;
}

/* Simple enveloppe d'alignement/troncature desormais : la couleur, le
   curseur et le fond viennent de `.arbre-noeud` + la classe de couleur
   (rendu/arbre-ligne.js, `classeCouleur`) sur le SPAN du coup a
   l'interieur — reconstruit exactement comme la Sequence, voir l'en-tete
   de rendu/commentaires-html.js. Le coup REGARDE EN CE MOMENT y recoit
   donc automatiquement le meme orange que .arbre-courant dans la
   Sequence, sans regle a part ici. */
.etiquette-commentaire {
  flex: 0 0 auto;
  max-width: 40%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-height: 22px;
  display: flex;
  align-items: center;
}

/* Le tag "Occ pN oM"/"Ref pN oM" auto-calcule (rendu/commentaires-html.js,
   interface/commentaires.js), separe du coup ET du commentaire ecrit a la
   main — demande par saab, "coherent avec KAAWA" : le jaune que KAAWA
   utilise pour un compteur Occ/Ref sous son seuil
   (kaa_tab_manager_ClO_Co.py, "[color=FFD700]"). Le bleu du meme fichier
   reste reserve au seuil de nulle atteint ailleurs dans KAAH (voir
   .compteur-occurrences-seuil) : jamais deux signaux bleus differents. */
.etiquette-occurrence-tag {
  color: #ffd700;
  font-size: 11px;
}

/* Seuil de nulle atteint sur CE tag (le compte TOTAL du groupe Occ ou Ref,
   pas le rang affiche) : bleu plutot que jaune, meme convention que KAAWA
   (kaa_tab_manager_ClO_Co.py, header_text, "[color=0080FF]") et que
   .compteur-occurrences-seuil, deja utilisee ailleurs dans KAAH pour ce
   meme signal — jamais un troisieme bleu different quelque part d'autre. */
.etiquette-occurrence-tag-seuil {
  color: #4aa8ff;
}

/* Une seule ligne par defaut ("deployer a la demande si texte long",
   demande par saab) : `rows` (pose en JS, rendu/commentaires-html.js) fixe
   1 ou 3, `resize` reste vertical pour un ajustement fin a la main en plus
   du bouton +/-. */
.texte-commentaire {
  flex: 1 1 auto;
  min-width: 0;
  box-sizing: border-box;
  padding: 2px 6px;
  background: #2b2b2b;
  color: #e4e4e4;
  border: 1px solid #3a3a3a;
  border-radius: 4px;
  font: 12px/1.3 sans-serif;
  resize: vertical;
}

.texte-commentaire-deplie {
  min-height: 48px;
}

/* Tableau des conseils (Coup, Gagne, Nul, Perdu — saab a demande cet ordre
   precis : Nul avant Perdu, "qui montre plus une regression"), en colonnes
   plutot qu'une simple ligne de texte (signale par saab). Une classe a
   part de .ligne-liste (qui reste en flex pour Mes parties/Variantes) :
   seul ce dialogue a besoin de colonnes alignees. */
.ligne-conseil {
  display: grid;
  /* Un coup Nacre fait TOUJOURS 4 caracteres (ex. "a1d4") : 6ch suffit
     largement, inutile de reserver 1fr (signale par saab, "la colonne
     Coup est inutilement trop large"). */
  grid-template-columns: 6ch repeat(3, 28px);
  gap: 4px;
  text-align: right;
}

.ligne-conseil-entete {
  font-weight: bold;
  color: #9a9a9a;
  border-bottom: 1px solid #5a5a5a;
}

.ligne-conseil .ligne-liste-texte {
  text-align: left;
}

/* Couleur du coup lui-meme : la meme que sa fleche sur le plateau (meme
   signal, deux endroits — voir classeDominanceConseil,
   interface/next-move.js). Les 3 colonnes de chiffres, elles, gardent
   CHACUNE sa propre couleur fixe (signale par saab : "les G, P, N avec
   leur propre couleur"), jamais celle de la dominance du coup. */
.texte-conseil-victoire { color: #2ecc55; }
.texte-conseil-defaite { color: #e04040; }
.texte-conseil-nulle { color: #4aa8ff; }
.texte-conseil-egalite { color: #9a9a9a; }

/* Memes couleurs que les fleches de Conseils, reglables avec elles
   (saab, 2026-09-27 : le tableau et les fleches doivent dire la meme chose). */
.valeur-gagne { color: var(--couleur-fleche-conseil-victoire, #2ecc55); font-variant-numeric: tabular-nums; }
.valeur-nul { color: var(--couleur-fleche-conseil-nulle, #4aa8ff); font-variant-numeric: tabular-nums; }
.valeur-perdu { color: var(--couleur-fleche-conseil-defaite, #e04040); font-variant-numeric: tabular-nums; }

/* Fleches sur le plateau principal (rendu/conseils.js). `pointer-events:
   none` : une fleche ne doit jamais voler un clic destine a la case ou a
   la bille en dessous. Plus epaisses que les traits fins deja prevus pour
   les sumitos/ejections (a venir) — signale par saab, comme dans KAAWA ;
   doublees une seconde fois (1.6 -> 3.2, encore trop fines au premier
   essai). Opaque par defaut (voir .fleche-conseil-translucide plus bas :
   ce n'est que dans le contexte de "Tout afficher" qu'une fleche doit
   s'attenuer). */
.fleche-conseil {
  pointer-events: none;
  stroke-width: 3.2;
}

.fleche-conseil-dominante {
  stroke-width: 5.2;
}

/* "Tout afficher" (interface/next-move.js) : toile de fond attenuee pour
   laisser deviner les cases en dessous (signale par saab, en vue d'un
   futur affichage des coordonnees) — sauf le coup qu'on vient de choisir,
   dessine SANS cette classe, opaque, par-dessus les autres. */
/* Leur opacite : le curseur Transparence de Reglages > Fleches Conseils (saab, 2026-10-22 : « le
   curseur au minimum donne un peu trop de transparence » — avant, 0,35 fois la sienne ; a 0 %,
   elles sont maintenant aussi opaques que la fleche choisie, qui l'est toujours). */
.fleche-conseil-translucide {
  opacity: var(--opacite-fleches-conseils, 0.5);
}

/* Couleurs et opacite reglables (saab, 2026-09-27, Reglages > Fleches
   Conseils ; rendu/apparence-reglages.js) — valeurs de repli = l'aspect
   d'avant. Les pointes (<marker>) vivent dans le meme #plateau : elles
   heritent des memes variables. */
.fleche-conseil-victoire, .fleche-conseil-pointe-victoire { stroke: var(--couleur-fleche-conseil-victoire, #2ecc55); fill: var(--couleur-fleche-conseil-victoire, #2ecc55); }
.fleche-conseil-defaite, .fleche-conseil-pointe-defaite { stroke: var(--couleur-fleche-conseil-defaite, #e04040); fill: var(--couleur-fleche-conseil-defaite, #e04040); }
.fleche-conseil-nulle, .fleche-conseil-pointe-nulle { stroke: var(--couleur-fleche-conseil-nulle, #4aa8ff); fill: var(--couleur-fleche-conseil-nulle, #4aa8ff); }
.fleche-conseil-egalite, .fleche-conseil-pointe-egalite { stroke: var(--couleur-fleche-conseil-egalite, #9a9a9a); fill: var(--couleur-fleche-conseil-egalite, #9a9a9a); }

/* Fleches de menaces (phase 19, rendu/menaces.js) : les "traits fins ...
   pour les sumitos/ejections" deja annonces dans le commentaire de
   .fleche-conseil plus haut. Plus fines et plus translucides que les
   fleches de Conseils : elles restent affichees en permanence tant que
   le bouton "!?" est actif, sur potentiellement plusieurs poussees a la
   fois — jamais aussi appuyees qu'une suggestion qu'on regarde seule. */
/* Opacite de base reglable (saab, 2026-09-27, Reglages > Fleches Menaces) :
   0.6 par defaut ; les ejections restent un peu plus appuyees qu'elle (+0.15,
   +0.35 pour celle qui gagne : 0.75 et 0.95 par defaut, comme avant),
   plafonnees a l'opaque. */
.fleche-menace {
  pointer-events: none;
  stroke-width: 1.6;
  opacity: var(--opacite-fleches-menaces, 0.6);
}

/* Vert = poussee du camp AU TRAIT ("ami"), orange = poussee de l'AUTRE
   camp ("ennemi") — code couleur de PLAN.md, memes verts/orange KAAWA
   que .fleche-conseil-victoire et .arbre-courant ailleurs dans KAAH.
   Couleurs reglables (rendu/apparence-reglages.js), repli = l'aspect d'avant. */
.fleche-menace-ami, .fleche-menace-pointe-ami { stroke: var(--couleur-fleche-menace-ami, #2ecc55); fill: var(--couleur-fleche-menace-ami, #2ecc55); }
.fleche-menace-ennemi, .fleche-menace-pointe-ennemi { stroke: var(--couleur-fleche-menace-ennemi, #cc6a00); fill: var(--couleur-fleche-menace-ennemi, #cc6a00); }

/* Rouge = cette poussee ejecte une bille, superposee a la fleche
   ami/ennemi ci-dessus (voir rendu/menaces.js) — plus epaisse et plus
   opaque si l'ejection donnerait la victoire immediate ("fin de partie",
   PLAN.md), exactement comme la "grosse pointe" de KAAWA. */
.fleche-menace-ejection, .fleche-menace-pointe-ejection { stroke: var(--couleur-fleche-menace-ejection, #e04040); fill: var(--couleur-fleche-menace-ejection, #e04040); }
.fleche-menace-ejection {
  stroke-width: 2.2;
  opacity: min(1, calc(var(--opacite-fleches-menaces, 0.6) + 0.15));
}

.fleche-menace-ejection-fin, .fleche-menace-pointe-ejection-fin { stroke: var(--couleur-fleche-menace-ejection-fin, #e04040); fill: var(--couleur-fleche-menace-ejection-fin, #e04040); }
.fleche-menace-ejection-fin {
  stroke-width: 3.6;
  opacity: min(1, calc(var(--opacite-fleches-menaces, 0.6) + 0.35));
}

/* Bandeau d'un puzzle en cours (phase 16, interface/puzzles.js) : l'objectif
   puis le verdict, dans la colonne de droite pour ne prendre aucune hauteur
   au plateau. Masque en permanence hors puzzle — `[hidden]` avec la MEME
   specificite que la regle qui le peint, sans quoi il resterait affiche
   quoi qu'il arrive (piege de specificite deja rencontre cinq fois ici). */
#bandeau-puzzle {
  /* Ne doit JAMAIS peser sur la largeur de sa colonne : `min-width: 0` le
     laisse retrecir sous la taille de son texte, et le texte va alors a la
     ligne au lieu de pousser. Sans les deux, une phrase de verdict un peu
     longue elargissait la colonne et retrecissait le plateau (signale par
     saab, en portrait) — or le plateau reste fixe toute la partie. */
  min-width: 0;
  overflow-wrap: anywhere;
  padding: 4px 6px;
  background: #1a1a1a;
  color: #e4e4e4;
  font: 12px/1.3 sans-serif;
  border-left: 1px solid #3a3a3a;
  border-bottom: 1px solid #3a3a3a;
}

#bandeau-puzzle[hidden] {
  display: none;
}

/* Fin de puzzle (interface/puzzles.js, tonDuPuzzle) : vert pour la solution,
   rouge pour tout "ce n'est pas la solution", orange pour ce qui reste
   incertain (verification en cours, peut-etre, solveur indisponible).
   `#bandeau-puzzle` en tete de chaque regle : sans lui, la couleur de base
   (#bandeau-puzzle, plus haut, un identifiant) l'emportait TOUJOURS — ces
   couleurs ne s'etaient jamais affichees depuis la phase 16. */
#bandeau-puzzle.bandeau-puzzle-solution { color: #2ecc55; }
#bandeau-puzzle.bandeau-puzzle-refus { color: #e04040; }
#bandeau-puzzle.bandeau-puzzle-incertain { color: #e8a33d; }

/* Une fin de puzzle doit SE VOIR (saab : "pas assez visible, le faire
   clignoter") : texte blanc sur fond de la couleur du verdict, plus gros, et
   quelques clignotements — pas indefiniment, on reste parfois longtemps a
   analyser une partie finie. Relances a chaque changement de verdict (la classe
   change). */
#bandeau-puzzle.bandeau-puzzle-final {
  padding: 6px 8px;
  border-radius: 6px;
  color: #ffffff;
  font-size: 14px;
  font-weight: bold;
  animation: clignoter-fin 0.8s ease-in-out 8;
}
#bandeau-puzzle.bandeau-puzzle-final.bandeau-puzzle-solution { background: #1f7a3a; }
#bandeau-puzzle.bandeau-puzzle-final.bandeau-puzzle-refus { background: #a82828; }
#bandeau-puzzle.bandeau-puzzle-final.bandeau-puzzle-incertain { background: #9a5a00; }

@keyframes clignoter-fin {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}

@media (prefers-reduced-motion: reduce) {
  .message-demarrage,
  #bandeau-puzzle.bandeau-puzzle-final,
  .nom-joueur.resultat-fin .nom-tour-cadre,
  .nom-joueur.resultat-fin .nom-tour {
    animation: none;
  }
}

/* L'objectif, a droite du nom dans la liste des puzzles : pousse au bout de
   la ligne (flex, voir .ligne-liste) et un cran plus discret que le nom —
   c'est un renseignement, pas le titre. */
.objectif-puzzle {
  flex: 0 0 auto;
  margin-left: auto;
  padding-left: 8px;
  color: #9a9a9a;
  white-space: nowrap;
}

#colonne-principale {
  display: flex;
  flex-direction: column;
  min-height: 0; /* peut retrecir si #arbre-panneau prend de la place a cote */
  min-width: 0;
}

/* La colonne de droite : Sequence et Conseils EMPILES, jamais de part et
   d'autre du plateau (voir index.html pour le pourquoi). Elle n'a aucune
   largeur propre — ce sont ses deux panneaux qui la donnent, et elle tombe
   donc a zero quand les deux sont replies, rendant toute la largeur au
   plateau. */
#colonne-droite {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

@media (max-width: 699px) {
  /* Grid plutot que flex : #colonne-gauche (icones) et #colonne-principale
     (plateau) cote a cote sur la meme ligne, #arbre-panneau en pleine
     largeur en dessous, apparaissant/disparaissant tout seul selon qu'il
     est visible ou masque (`display:none` sur un item de grid libere sa
     ligne automatiquement, contrairement a un flex-item qu'il aurait
     fallu gerer a la main) — corrige le plateau qui prenait avant toute
     la largeur ET toute la hauteur (les boutons de #colonne-gauche
     restaient invisibles), signale par saab. */
  body {
    display: grid;
    /* 44px (pas 56 — saab : "diminuer la largeur") : le minimum tactile
       de CLAUDE.md, jamais moins pour rester au doigt. Un repli complet
       a une simple poignee a ete essaye puis abandonne (saab : "le
       bouton fonctionne mal, certainement zone trop petite... le plateau
       est assez grand avec des petites icones") — voir JOURNAL.md. */
    /* `minmax(0, 1fr)` et NON `1fr` : un `1fr` nu vaut `minmax(auto, 1fr)`,
       donc il s'elargit pour loger le contenu le plus large de la colonne —
       une phrase un peu longue dans un panneau suffisait a pousser la
       colonne, donc a retrecir le plateau (signale par saab sur le bandeau
       des puzzles). Avec un minimum de 0, la colonne vaut exactement
       "l'ecran moins les icones", quoi qu'on y mette : le plateau, dont la
       largeur en decoule (voir #plateau plus bas), ne peut plus bouger de la
       partie. C'est la protection generale, valable pour tout panneau
       futur — pas un correctif pour le seul bandeau des puzzles. */
    grid-template-columns: 44px minmax(0, 1fr);
    /* Le plateau, de taille fixe (voir #plateau plus bas), laisse de la
       hauteur en dessous : les deux panneaux (Conseils puis Sequence, voir
       #colonne-droite) s'y rangent, sans jamais recouvrir le plateau. */
    grid-template-areas: 'boutons plateau' 'boutons panneaux';
    /* `auto 1fr` et non `auto auto` : la premiere ligne fait exactement la
       hauteur du plateau (fixe, voir #plateau plus bas), la seconde prend
       TOUT le reste — ni plus (les panneaux ne peuvent plus pousser la page
       au-dela de l'ecran) ni moins. Une ligne vide ne coute rien : le
       plateau, lui, ne grandit pas pour autant. */
    grid-template-rows: auto 1fr;
    height: 100%;
    /* La PAGE elle-meme ne doit jamais defiler sur telephone : chaque
       panneau qui peut deborder (colonne d'icones, listes des panneaux
       de droite) a deja son propre `overflow-y: auto` pour defiler SUR
       LUI-MEME. Sans ce `overflow: hidden` ICI, un residu de quelques
       dizaines de pixels reste scrollable au niveau de la page meme quand
       #colonne-gauche gere deja tres bien son propre debordement en
       interne (constate en mesurant `document.documentElement.
       scrollHeight` : plus grand que `window.innerHeight` malgre un
       `#colonne-gauche` par ailleurs correctement borne — un des ecueils
       connus de CSS Grid avec un item qui couvre plusieurs lignes ET son
       propre `overflow:auto`) : n'importe quel geste demarrant en dehors
       d'un panneau a overflow propre pouvait alors faire defiler LA PAGE
       ENTIERE, deplaçant plateau et panneaux avec elle (signale par saab :
       "faire defiler les icones [faisait] bouger les autres fenetres"). */
    overflow: hidden;
  }

  /* `min-height: 0` : MEME piege que #colonne-droite juste en dessous (et
     deja documente ailleurs dans ce fichier) — sans lui, un element de
     grid refuse de descendre sous la hauteur de son CONTENU. `boutons`
     couvre les deux lignes de la grille (voir grid-template-areas
     au-dessus), donc sans ce `min-height`, une colonne d'icones trop
     longue pour l'ecran agrandissait la ligne entiere au lieu de defiler
     sur elle-meme. `overscroll-behavior: contain` en plus : sans lui,
     arriver en bout de liste transmet le geste de defilement plus loin
     (ici sans effet puisque la page ne defile plus du tout, voir le
     `overflow: hidden` de `body` juste au-dessus — garde de secours si ce
     dernier venait a changer). */
  #colonne-gauche {
    display: flex;
    flex-direction: column;
    grid-area: boutons;
    gap: 4px;
    padding: 2px;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: #1a1a1a;
  }

  #colonne-principale {
    grid-area: plateau;
    min-width: 0;
  }

  /* `min-height: 0` : sans lui, un element de grid refuse de descendre sous
     la taille de son contenu et les panneaux repousseraient le bas de la
     page hors de l'ecran. Avec, ils se partagent exactement la ligne que la
     grille leur donne, et ce sont leurs listes qui defilent. */
  #colonne-droite {
    grid-area: panneaux;
    min-height: 0;
  }

  /* Encore au-dessus du `order: -1` de #panneau-conseils juste en dessous :
     un embranchement en cours de choix est plus prioritaire que Conseils
     si jamais les deux etaient ouverts a la fois (voir l'en-tete de
     #panneau-embranchement, styles.css plus haut). */
  #panneau-embranchement {
    order: -2;
  }

  /* Sous le plateau, jamais par-dessus (voir l'en-tete de #panneau-conseils
     plus haut) : c'est toute la raison d'etre du plafonnement du plateau a
     un carre juste en dessous. `order` le fait passer AVANT la Sequence
     dans la colonne, alors qu'il vient apres elle dans le HTML (ou c'est
     l'ordre de l'ordinateur qui compte : Conseils sous la Sequence) —
     ici, ce qui commente le plateau doit rester colle au plateau. */
  #panneau-conseils {
    order: -1;
    flex: 0 1 auto;
    min-height: 0;
    border-top: 1px solid #3a3a3a;
  }

  /* Occurrences reste dans l'ordre naturel du HTML (apres Sequence et
     Conseils) : une information secondaire, pas besoin de la coller au
     plateau comme Conseils.
     `flex: 1 1 auto` (pas juste `0 1 auto` comme les deux autres
     panneaux) : CE panneau-ci absorbe tout ce que Sequence/Commentaires
     et Conseils laissent de libre dans la colonne — sans ca, un plafond
     fixe (`max-height`) le laissait plus petit que l'espace vraiment
     disponible des que les panneaux au-dessus etaient courts, ouvrant un
     VIDE entre eux et lui (signale par saab : "le Occurrence doit coller
     a Sequence/Commentaire ... sinon il y a un vide entre les 2"). Aucun
     plafond ici non plus (saab : "ne pas mettre de limite") : au-dela de
     cet espace libre, seule la poignee (interface/occurrences.js,
     activerRedimensionnementOccurrencesPortrait) peut l'agrandir encore,
     en reduisant Sequence/Commentaires a la place. */
  #panneau-occurrences {
    flex: 1 1 auto;
    min-height: 0;
    border-top: 1px solid #3a3a3a;
  }

  /* EN PORTRAIT, LA LARGEUR COMMANDE : le plateau prend toute la largeur
     que lui laisse la colonne d'icones, et sa hauteur s'en deduit par sa
     proportion (rendu/plateau-svg.js). Il ne peut donc plus ni s'etirer ni
     se tasser selon le nombre de lignes des Conseils ou de la Sequence —
     la demande exacte de saab, "fixer le plateau ... en portrait il prend
     toute la largeur (moins colonne icones)". */
  #plateau {
    flex: 0 0 auto;
    width: 100%;
    height: auto;
    max-width: 100%; /* la poignee ci-dessous peut demander plus que la largeur ne permet, voir interface/sequence.js */
    /* SANS CA, la poignee de hauteur (phase 18) n'avait aucun effet : en
       flex, `align-items: stretch` (herite de #colonne-principale) etire
       un enfant `width:auto` a 100% du conteneur QUEL QUE SOIT
       l'aspect-ratio, au lieu de laisser celui-ci deduire la largeur de la
       hauteur explicite qu'on vient de poser. Sans consequence a
       width:100% (l'etat normal, non redimensionne) : centrer un element
       deja plein-largeur ne change rien a l'oeil. */
    align-self: center;
  }

  /* Fenetre etroite mais COUCHEE (PC en fenetre reduite, saab 2026-10-01) :
     deduite de la largeur, la hauteur du plateau depassait l'ecran, et les
     tableaux en dessous (Reflexion IA, Sequence) passaient par-dessus lui et
     sous Annuler. Le plateau ne depasse plus la hauteur de l'ecran moins le
     titre au-dessus, Annuler et le rappel « Touchez une pendule » en dessous
     (100px) ; les tableaux se reduisent dans ce qui reste, sans deborder. La
     poignee de hauteur du plateau (pensee pour le portrait) n'y a plus de
     sens : la hauteur de l'ecran commande deja. */
  @media (orientation: landscape) {
    #plateau {
      max-height: calc(100vh - 100px);
      max-height: calc(100dvh - 100px);
    }

    #colonne-principale > #plateau-poignee-hauteur {
      display: none;
    }
  }

  /* Poignee de hauteur du plateau (phase 18) : exception assumee a "le
     plateau garde sa taille maximale", demandee par saab lui-meme pour
     voir plusieurs lignes de Commentaires a la fois — jamais pendant une
     partie en cours. `#etat-sauvegarde`/`#plateau`/cette poignee sont tous
     enfants directs de #colonne-principale (flex column, voir plus haut) :
     la reduire libere mecaniquement de la hauteur pour la ligne de grille
     suivante, sans toucher a `grid-template-rows`. */
  /* BUG TROUVE (saab, en test reel sur telephone : "les poignees en
     portrait ne fonctionnent pas") : 14px de haut, c'est bien EN DESSOUS
     du minimum tactile de 44px (CLAUDE.md) — un doigt rate cette bande
     bien plus souvent qu'il ne la touche, ce qui pouvait donner
     l'impression d'une poignee cassee plutot que juste trop fine a
     saisir. `padding` (compte dans le hit-test de l'element, donc dans la
     zone que `poignee.addEventListener('pointerdown', ...)` recoit,
     interface/sequence.js) elargit la zone de PRISE a 44px sans agrandir
     le TRAIT VISIBLE (`background-clip: content-box` ne peint que les
     14px du milieu) — exception assumee a "le plateau garde sa taille
     maximale" (deja acceptee pour cette poignee elle-meme, phase 18) :
     44px de haut pour une poignee reste moins cher que la moitie du
     panneau qu'elle sert a redimensionner. */
  #plateau-poignee-hauteur {
    display: block;
    flex: 0 0 auto;
    height: 14px;
    padding: 15px 0;
    box-sizing: content-box;
    margin-top: 2px;
    border-radius: 3px;
    background: #3a3a3a;
    background-clip: content-box;
    cursor: ns-resize;
    touch-action: none; /* le glisser ne doit pas aussi faire defiler la page */
  }

  /* Poignee de hauteur MAXIMALE d'Occurrences (phase 18, correctif) : meme
     style que #plateau-poignee-hauteur juste au-dessus (zone de prise a
     44px, meme raison), mais EN HAUT du panneau qu'elle controle (dernier
     de la colonne, voir index.html) — voir interface/occurrences.js pour
     le detail et pourquoi. */
  #occurrences-poignee-hauteur {
    display: block;
    flex: 0 0 auto;
    height: 14px;
    padding: 15px 0;
    box-sizing: content-box;
    margin-bottom: 4px;
    border-radius: 3px;
    background: #3a3a3a;
    background-clip: content-box;
    cursor: ns-resize;
    touch-action: none;
  }
}

@media (min-width: 700px) {
  body {
    display: flex;
    flex-direction: row;
  }

  /* Poignee de hauteur du plateau (phase 18) : n'existe qu'EN PORTRAIT
     TELEPHONE (voir la media query max-width, display:block) — aucun sens
     ici, ou c'est deja la hauteur de l'ECRAN qui commande la taille du
     plateau. Declaree ICI, jamais en regle inconditionnelle : deux regles
     `display` de meme specificite pour le meme selecteur se departagent
     par ordre d'apparition dans le fichier plutot que par leur condition —
     piege deja rencontre plusieurs fois dans ce projet (voir la note en
     tete de fichier). */
  #plateau-poignee-hauteur {
    display: none;
  }

  /* Meme raison que #plateau-poignee-hauteur juste au-dessus : n'existe
     qu'en portrait telephone, voir interface/occurrences.js. */
  #occurrences-poignee-hauteur {
    display: none;
  }

  #colonne-principale {
    /* Largeur par defaut confortable plutot qu'une croissance sans
       limite : au-dela, c'est #colonne-gauche qui absorbe l'espace en
       trop (voir plus haut), pas le plateau qui grossit demesurement.
       `flex:1 1 auto` le laisse quand meme grandir jusque-la sur un
       ecran de taille normale, et retrecir sans probleme sur un ecran
       plus etroit (700-900px) ou #colonne-gauche n'a de toute facon rien
       a absorber. */
    flex: 1 1 auto;
    max-width: 900px;
    /* Le plateau ne fait plus toute la largeur de la colonne (sa largeur se
       deduit de sa hauteur, voir #plateau juste en dessous) : sans ca il
       resterait colle a gauche, avec tout le vide d'un seul cote. */
    align-items: center;
  }

  /* EN PAYSAGE, LA HAUTEUR COMMANDE — symetrique du portrait : le plateau
     prend toute la hauteur de l'ecran et sa largeur s'en deduit (saab, "en
     paysage toute la hauteur"). C'est ce qui permet de sortir la barre de
     titre de cette colonne (interface/disposition.js l'envoie en haut a
     droite) : chaque pixel de hauteur rendu ici agrandit vraiment le
     plateau. `max-width: 100%` pour le cas inverse, un ecran plus haut que
     large ou c'est la largeur qui manque : la proportion tient alors par la
     largeur, et la hauteur suit. */
  #plateau {
    flex: 0 0 auto;
    height: 100%;
    width: auto;
    max-width: 100%;
  }

  /* La colonne est une bande d'icones ici aussi desormais (voir plus haut) :
     une largeur figee, la meme qu'en portrait, plutot qu'une largeur "au
     contenu" qui varierait avec les icones. Les boutons gardent leurs 36px
     de haut : cette media query couvre aussi le TELEPHONE COUCHE, ou c'est
     un doigt qui vise, pas une souris. */
  #colonne-gauche {
    /* `border-box` : sans lui, les 4px de padding s'ajoutent aux 44 et la
       bande en fait 52 — la colonne doit mesurer exactement la meme chose
       qu'en portrait, ou c'est une piste de grille de 44px. */
    box-sizing: border-box;
    flex: 0 0 44px;
  }

  /* `flex: 0 0 auto` et AUCUNE largeur a elle : la colonne ne mesure que ce
     que ses deux panneaux mesurent (voir leurs largeurs juste en dessous),
     et tombe donc a zero des que les deux sont replies — toute la largeur
     revient alors au plateau. `align-self` pour qu'elle ne s'etire pas sur
     toute la hauteur pour rien. */
  /* En haut de la colonne de droite sur ordinateur (interface/disposition.js
     l'y monte), plus au-dessus du plateau ou il lui volait de la hauteur.
     `width` FIXE et etroit, jamais `auto` : le nom complet d'une partie
     KAAWA fait facilement 400 caracteres, et une largeur "au contenu"
     elargirait toute la colonne — donc retrecirait le plateau, exactement ce
     qu'on cherche a eviter. Il est donc tronque avec "…", son texte entier
     restant lisible au survol (attribut `title`, voir index.html) ; le
     `min-width: 100%` le laisse quand meme s'etirer a la largeur de la
     Sequence quand elle est ouverte en dessous. */
  #entete-partie,
  #bandeau-puzzle {
    box-sizing: border-box;
    width: 180px;
    min-width: 100%;
  }

  /* Le tableau Reflexion IA a la largeur des tableaux (celle de la Sequence,
     reglable a sa poignee), Sequence ouverte ou non (saab, 2026-10-01 : sans
     tableau, il retombait a 176px et le plateau restait entoure de vide). Et
     le rappel « Touchez une pendule... », une phrase sur une seule ligne, ne
     compte plus dans la largeur de la colonne : avant le depart, il
     l'elargissait et retrecissait le plateau, puis la colonne se resserrait en
     disparaissant. */
  .reflexion-ia {
    box-sizing: border-box;
    width: var(--largeur-sequence, 330px);
    max-width: 100%;
  }

  /* Fenetre basse : le tableau Reflexion IA cede sa hauteur le premier (au
     moins sa ligne d'en-tete et une ligne), pour que la Sequence garde
     toujours quelques coups visibles au-dessus de sa poignee et de sa barre
     de navigation (saab, 2026-10-01 : « des le 1er coup, un tableau disparait
     sous la poignee »). 380px : le titre, la Sequence a sa hauteur minimale,
     Annuler et le rappel. */
  .reflexion-ia .reflexion-ia-defilement {
    max-height: clamp(2.6em, calc(100vh - 380px), 12em);
  }

  #arbre-panneau {
    max-width: 100%;
    min-height: 180px;
  }

  #colonne-droite > .message-demarrage {
    contain: inline-size;
  }

  #etat-sauvegarde,
  #position-copiable {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    border-left: 1px solid #3a3a3a;
    border-bottom: 1px solid #3a3a3a;
  }

  /* Fenetre qu'on retrecit (saab, 2026-10-01 : « sans s'arreter aux limites de
     la fenetre du plateau ») : c'est la colonne des tableaux qui cede la
     premiere (flex-shrink tres superieur a celui du plateau), jusqu'a sa
     largeur minimale ; le plateau ne retrecit qu'ensuite. Ses tableaux suivent
     (max-width: 100%, plus bas) et defilent sur eux-memes. */
  #colonne-droite {
    flex: 0 1000 auto;
    min-width: 176px;
    align-self: flex-start;
    max-height: 100vh;
    /* Reste collee au bord droit meme quand il reste de la place libre
       (plateau deja a sa largeur maximale de 900px, voir
       #colonne-principale) : sans ca, l'espace en trop se poserait APRES
       elle et la decollerait du bord. */
    margin-left: auto;
  }

  /* SOUS la Sequence, dans la meme colonne de droite — jamais a gauche du
     plateau, qui y perdait de la largeur alors qu'il restait de la place
     libre a droite (saab). Pas de largeur propre : il s'etire a celle de la
     colonne, que la Sequence fixe quand elle est ouverte ; `min-width` ne
     sert que pour le cas ou il est seul. */
  #panneau-conseils {
    flex: 0 1 auto;
    min-width: 176px;
    max-height: 50vh;
    /* Les bordures vivent sur les panneaux, jamais sur #colonne-droite :
       celle-ci mesure zero quand les deux sont replies, et un filet de 1px
       resterait sinon a l'ecran sans rien border. */
    border-top: 1px solid #3a3a3a;
    border-left: 1px solid #3a3a3a;
  }

  /* Meme traitement que #panneau-conseils juste au-dessus, troisieme
     panneau de la colonne. */
  #panneau-occurrences {
    flex: 0 1 auto;
    min-width: 176px;
    max-height: 40vh;
    border-top: 1px solid #3a3a3a;
    border-left: 1px solid #3a3a3a;
  }

  /* Sur ordinateur, la sequence RESTE masquable (saab : "penser a
     rajouter le bouton Sequence aussi sur pc et tel paysage, ca peut
     servir" — pour liberer toute la largeur au plateau quand on regarde
     les fleches de "Tout afficher", par exemple). `#arbre-panneau[hidden]`
     doit donc vraiment passer a `display:none` ici aussi — jamais force a
     `display:flex` comme avant. */
  #arbre-panneau {
    display: flex;
    /* 330px : la grille a 10 colonnes (.arbre-lignes) resserree fait 321px
       avec le padding d'#arbre — elle tenait avant en 400px, largeur que
       saab a demande de rendre au plateau ("reduis les espaces inutiles
       dans certaines colonnes du tableau"). `width`, et non plus
       `flex-basis` : ce panneau n'est plus un enfant direct de `body` mais
       de #colonne-droite, une colonne — un flex-basis y reglerait sa
       HAUTEUR. La variable, elle, est posee sur la racine par la poignee de
       largeur (interface/sequence.js) : une variable plutot qu'un
       `style.width` direct, pour qu'une largeur choisie sur ordinateur ne
       vienne pas figer le panneau en passant en portrait, ou il doit
       reprendre toute la largeur de l'ecran. */
    width: var(--largeur-sequence, 330px);
    min-width: 0; /* sinon un texte non coupable (l'en-tete, une longue position compressee) elargit le panneau au-dela de sa largeur fixe */
    /* La moitie de l'ecran par defaut (pas toute la hauteur, comme avant) :
       laisse de la place pour de futures pages en dessous (menaces phase
       19, notes phase 26...) — #arbre-poignee-hauteur, ci-dessous, permet
       de l'ajuster a la main. */
    height: 50vh;
    border-left: 1px solid #3a3a3a;
  }

  /* `[hidden]` (specificite ID+attribut) l'emporte sur la regle ci-dessus
     (specificite ID seule) quel que soit l'ordre du fichier — meme
     technique que #arbre-panneau[hidden] en telephone plus haut. */
  #arbre-panneau[hidden] {
    display: none;
  }

  /* AUCUNE regle pour #bouton-sequence ici, et c'est voulu : il vit en
     PERMANENCE dans la colonne de gauche (index.html), ordinateur comme
     telephone — il prend donc deja exactement l'habillage de ses voisins
     (`#boutons-sauvegarde button`, plus haut), meme taille, meme couleur,
     meme groupe que Commentaires/Occurrences. Deux essais precedents (le
     bouton par defaut du navigateur au bas de #navigation, puis un
     bouton habille a la main en 88x44 sous le plateau) avaient chacun
     leur defaut : invisible pour le premier (saab, "je ne vois presque
     pas le btn Sequence sur telephone paysage en plein ecran"), une bande
     de 52px prise au plateau pour le second — d'ou le regroupement
     definitif dans la colonne d'icones (correctif de disposition,
     phase 18). */

  /* Poignee de hauteur (interface/sequence.js,
     activerRedimensionnementHauteur) : seulement utile sur ordinateur, ou
     la sequence n'occupe qu'une partie de la hauteur. */
  #arbre-poignee-hauteur {
    display: block;
    flex: 0 0 auto;
    height: 10px;
    cursor: ns-resize;
    background: #3a3a3a;
    touch-action: none; /* le glisser ne doit pas aussi faire defiler la page sur un ecran tactile */
  }

  /* Poignee de largeur (interface/sequence.js,
     activerRedimensionnementLargeur) : a cheval sur la bordure gauche du
     panneau (`left: -4px` sur une bordure a 0, voir plus bas) pour une
     zone de prise confortable sans deplacer visuellement rien d'autre.
     Invisible par defaut (fond transparent) : seul le curseur ew-resize la
     revele avant de la saisir, un trait vertical permanent alourdirait la
     bordure existante pour rien. */
  #arbre-poignee-largeur {
    display: block;
  }

  #arbre-poignee-largeur:hover,
  #arbre-poignee-largeur:active {
    background: #3a3a3a;
  }
}

/* `#entete-partie` (index.html) : la position copiable et le nom de la partie,
   empiles, voyagent ensemble entre le haut du plateau et le haut de la
   colonne de droite (interface/disposition.js). */
#entete-partie {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
}

/* Confirmation de la sauvegarde automatique (voir index.html,
   actualiserEtatSauvegarde). Discrete (petit, gris) : une confirmation de
   routine. Le tour, le camp au trait et le resultat de fin de partie —
   qui vivaient avant dans un #statut separe, retire a la demande de saab
   pour rendre cette hauteur au plateau — s'affichent desormais DANS le
   plateau lui-meme, voir rendu/ejections.js. */
#etat-sauvegarde {
  flex: 0 0 auto;
  padding: 2px 6px;
  background: #1a1a1a;
  color: #888;
  font: 11px sans-serif;
  text-align: center;
  /* Un clic le copie (index.html) ; il se selectionne aussi a la souris. */
  cursor: copy;
  user-select: text;
}

/* La notation du Plateau (interface/infos-case.js) : a copier. */
.notation-plateau {
  margin: 2px 0 6px;
  font-family: monospace;
  font-size: 11px;
  color: #c4c4c4;
  word-break: break-all;
  user-select: text;
}

#etat-sauvegarde.etat-sauvegarde-erreur {
  color: #e0a040; /* orange, alerte douce : rien n'est perdu (la partie continue), juste pas enregistre */
}

/* Position copiable (phase 12bis, interface/position-copiable.js) : meme
   gabarit qu'#etat-sauvegarde juste au-dessus, teinte de bleu (couleur
   distincte, jamais confondue avec le nom de la partie) et curseur en main
   pour signaler qu'elle est cliquable — #etat-sauvegarde, elle, ne l'est
   pas. */
#position-copiable {
  flex: 0 0 auto;
  padding: 2px 6px;
  background: #1a1a1a;
  color: #7ab8e8;
  font: 11px sans-serif;
  text-align: center;
  cursor: pointer;
}

/* La TAILLE du plateau se declare entierement dans chacune des deux media
   queries (largeur imposee en portrait, hauteur imposee en paysage), jamais
   ici : une regle sans condition, placee plus bas dans le fichier, gagnerait
   sur les deux — c'est exactement ce qui se passait avant (`flex: 1 1 auto`
   ecrit ici annulait le `flex: 0 1 auto` de la media query telephone, d'ou
   un plateau qui prenait toute la hauteur laissee libre et rebondissait des
   qu'un panneau changeait de taille).
   Sa PROPORTION, elle, est posee une fois pour toutes par
   rendu/plateau-svg.js (fixerProportionsPlateau) : c'est elle qui deduit la
   seconde dimension de la premiere, et qui rend le plateau insensible a
   tout ce qui l'entoure. */
#plateau {
  min-height: 0; /* sans quoi la hauteur disponible est ignoree en SVG */
}


/* Barre de navigation dans l'historique (phase 9). Sur telephone, reste
   au bas de #colonne-principale (regle CLAUDE.md, "les onglets ... en bas
   de l'ecran sur telephone" — la ou le pouce arrive). Sur ordinateur,
   interface/disposition.js la deplace au bas d'#arbre-panneau : meme
   element, memes ecouteurs de clic, juste un autre parent — voir ce
   fichier. Aucune regle CSS specifique a l'un ou l'autre parent : les
   deux sont des colonnes flex, elle s'y comporte pareil. */
#navigation,
#barre-annuler {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap; /* 5 boutons peuvent depasser la largeur d'un telephone etroit */
  justify-content: center;
  gap: 2px;
  padding: 4px;
  background: #1a1a1a;
}

/* Seule la taille change entre telephone et ordinateur (chacune dans sa
   propre media query plus bas, jamais ici — meme discipline que partout
   ailleurs dans ce fichier) : le reste est identique quel que soit le
   parent d'#navigation (voir interface/disposition.js). */
#navigation button,
#barre-annuler button {
  padding: 0 4px;
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
}

#navigation button:disabled,
#barre-annuler button:disabled {
  opacity: 0.35; /* deja au debut ou a la fin : visible sans avoir a cliquer pour le savoir */
}

@media (max-width: 699px) {
  #navigation button {
    min-width: 44px; /* regle des 44 px, CLAUDE.md : precision du doigt, pas de la souris */
    /* DEROGATION ASSUMEE a la regle des 44px de CLAUDE.md, et seulement sur
       la HAUTEUR : saab l'a demandee explicitement ("penser a reduire la
       hauteur des btn de la barre de Navigation"). La largeur reste a 44px,
       et c'est elle qui compte le plus ici — les six boutons sont cote a
       cote sur une seule rangee, un doigt rate un voisin bien plus
       facilement qu'il ne rate la rangee entiere. A remonter a 44 si saab
       trouve la barre moins confortable a l'usage. */
    min-height: 38px;
    /* Police reduite (16 -> 13px, saab : "essaye de reduire la largeur
       pour qu'ils tiennent sur une ligne") : la HAUTEUR minimale de 44px
       reste, seul le texte ("Annuler"...) devient plus etroit, assez
       pour eviter le retour a la ligne des 5 boutons. */
    font-size: 13px;
  }
}

@media (min-width: 700px) {
  #navigation button {
    /* La regle des 44px (CLAUDE.md) vise le confort du doigt sur
       telephone ; a la souris, plus petit suffit et laisse plus de place
       a la sequence, sous laquelle ce bandeau vit desormais sur
       ordinateur (signale par saab, "optimiser le plus d'info en
       hauteur"). */
    min-width: 28px;
    min-height: 24px;
    font-size: 12px;
  }
}

/* Barre laterale Sequence (phase 9 -> 11 : l'arbre des coups). Colonne a
   elle seule : #arbre-entete reste fixe en haut (comme le bouton
   "[ POS. START ]" de KAAWA, toujours visible meme en defilant), #arbre
   defile tout seul. Repliee par defaut sur telephone (attribut `hidden`)
   pour laisser toute la place au plateau. */
/* Seulement les proprietes IDENTIQUES sur telephone et sur ordinateur :
   flex, max-height et border-top/border-left sont chacune reservees a
   une seule des deux media queries (telephone ci-dessous, ordinateur plus
   haut) — jamais ici, voir la note plus haut sur pourquoi les melanger
   avait annule des correctifs precedents. */
#arbre-panneau {
  display: flex;
  flex-direction: column;
  position: relative; /* ancre #arbre-poignee-largeur, positionnee en absolu sur sa bordure gauche */
  background: #1a1a1a;
  color: #e4e4e4;
  /* Interligne resserre (1.4 -> 1.15, saab : "optimiser le plus d'info en
     hauteur") : chaque coup de la sequence prend un peu moins de place,
     plus de coups tiennent sans defiler. */
  font: 14px/1.15 sans-serif;
}

@media (max-width: 699px) {
  /* `flex: 0 1 auto` (plus `1 1 auto` comme avant) : ce panneau ne prend
     QUE ce que son propre contenu demande (et defile si ca depasse),
     jamais plus — c'est desormais #panneau-occurrences, tout en bas de la
     colonne, qui absorbe l'espace libre restant (voir plus bas). Avec
     flex-grow ici, ce panneau s'etirait pour rien des que son contenu
     etait court, repoussant Occurrences plus bas et ouvrant un vide entre
     les deux (signale par saab). Une hauteur choisie a la main par sa
     PROPRE poignee (interface/occurrences.js,
     activerRedimensionnementOccurrencesPortrait, qui reduit CE panneau
     pour agrandir Occurrences) reste bien sur possible : flex-basis
     `auto` respecte un `style.height` pose en ligne, flex-shrink continue
     de s'appliquer si la colonne manque quand meme de place. */
  #arbre-panneau {
    flex: 0 1 auto;
    min-height: 0;
    border-top: 1px solid #3a3a3a;
  }

  /* BUG LATENT trouve en construisant cette meme media query (le plateau
     prenait avant toute la hauteur disponible, masquant sans le vouloir
     ce meme defaut) : la regle non conditionnelle #arbre-panneau plus bas
     fixe `display:flex` avec une specificite d'ID (1 ID), superieure a
     celle de `[hidden] { display:none }` du navigateur (1 attribut) — le
     panneau restait donc TOUJOURS affiche sur telephone, `hidden` ou pas,
     juste ecrase a une hauteur quasi nulle par l'ancienne disposition en
     flex. Il faut au moins la MEME specificite (ID + attribut) pour
     gagner face a la regle non conditionnelle, quel que soit l'ordre des
     regles dans le fichier — meme technique que .nom-joueur-noir.au-trait
     .nom-en-danger plus haut. */
  #arbre-panneau[hidden] {
    display: none;
  }
}

/* Historique de navigation (phase 11bis, interface/saisie.js) : trois petits
   boutons juste au-dessus de "Depart" — meme style que #commentaires-barre,
   toujours visible avec Sequence ET Commentaires (les deux modes de ce
   panneau), grises quand ils n'ont nulle part ou aller. */
#historique-navigation {
  display: flex;
  gap: 4px;
  padding: 4px 4px 0;
  flex: 0 0 auto;
}

#historique-navigation button {
  flex: 1 1 0;
  min-height: 30px;
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
}

#historique-navigation button:disabled {
  opacity: 0.4;
  cursor: default;
}

#arbre-entete {
  flex: 0 0 auto;
  padding: 6px; /* horizontal reduit de 10 a 6 (saab) : la grille en dessous a peu de marge a 400px de large */
  font-weight: bold;
  border-bottom: 1px solid #3a3a3a;
  cursor: pointer;
  /* Une ligne, tronquee avec "…" (saab : "ne pas passer sur 2 [lignes],
     il suffit de tronquer la fin") plutot que de laisser une position
     compressee tres longue elargir le panneau ou passer sur plusieurs
     lignes — le texte complet reste disponible via `title` (voir
     interface/sequence.js), au survol sur ordinateur. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#arbre {
  flex: 1 1 auto;
  overflow-y: auto;
  /* Filet de secours pour #arbre-poignee-largeur : la grille a 10 colonnes
     (.arbre-lignes) fait ~388px de large, mais rien n'empeche saab de
     reduire le panneau en dessous a la main — dans ce cas, un defilement
     horizontal LOCAL a la liste vaut mieux qu'un debordement visuel. */
  overflow-x: auto;
  padding: 6px 4px; /* reduit une seconde fois (8/6 -> 6/4) avec les colonnes elles-memes */
}

/* Cachees sur telephone (la sequence y prend deja toute sa place possible,
   max-height:35vh, rien a redimensionner a la main), visibles sur
   ordinateur (voir la media query plus haut, qui les met a `display:
   block`) — DANS LEUR PROPRE media query, jamais en regle inconditionnelle :
   c'est exactement le piege deja documente plus haut (une regle sans
   condition, plus bas dans le fichier, gagne quelle que soit la media
   query qui entoure l'autre declaration de la meme propriete). Trouve en
   testant la poignee de hauteur elle-meme : invisible sur ordinateur
   malgre le `display: block` de la media query, pour cette raison precise
   — la poignee de largeur, ajoutee plus tard, suit direct le meme moule. */
@media (max-width: 699px) {
  #arbre-poignee-hauteur,
  #arbre-poignee-largeur {
    display: none;
  }
}

/* Poignee de largeur (interface/sequence.js,
   activerRedimensionnementLargeur) : a cheval sur la bordure gauche du
   panneau (voir #arbre-panneau, position:relative) pour une zone de prise
   confortable sans rien deplacer visuellement ; `display` lui-meme est
   regle par les deux media queries ci-dessus/ci-dessous, jamais ici (meme
   piege que partout ailleurs dans ce fichier). */
#arbre-poignee-largeur {
  position: absolute;
  top: 0;
  bottom: 0;
  left: -4px;
  width: 8px;
  cursor: ew-resize;
  touch-action: none; /* le glisser ne doit pas aussi faire defiler la page sur un ecran tactile */
}

/* Grille a 10 colonnes fixes : [repli, numero, coup, suffixes, ✕] pour
   Noir, les 5 memes pour Blanc. Chaque ligne de l'arbre fournit exactement
   ces 10 elements (voir rendu/arbre-html.js, ajouterSegment) : un element
   absent (pas de repli, pas de ✕...) reste quand meme present mais
   invisible (`.invisible`), jamais omis — sinon les colonnes suivantes se
   decalent d'une ligne a l'autre (signale par saab). Memes raisons pour
   l'absence totale d'indentation par profondeur (un premier essai
   imbriquait un niveau par tour, ce qui finissait par sortir de l'ecran) :
   la profondeur se lit dans le numero de tour, une branche dans sa
   couleur et son icone (●/○). La colonne "suffixes" est volontairement
   plus etroite que la date qu'elle affiche parfois (voir .arbre-suffixes
   plus bas) : la date y passe sur deux lignes, ce que (eject)/[fin], plus
   courts, n'ont pas besoin de faire. */
.arbre-lignes {
  display: grid;
  /* La colonne coup NE PEUT PAS etre juste "auto" (essaye, puis annule) :
     .arbre-noeud a `overflow-wrap: anywhere` (utile pour ne jamais faire
     deborder le panneau, voir plus bas), ce qui rend son min-content
     minuscule (le texte peut se couper n'importe ou) — une colonne "auto"
     se base sur ce min-content et s'effondrait, forcant CHAQUE coup sur
     4 ou 5 lignes au lieu d'une. 70px est mesure sur le plus long texte
     reel (icone de branche + prefixe blanc + coordonnees, ex. "○ -h9h8") :
     large plutot que juste, un chiffre pile ajuste re-cassera au moindre
     coup plus long. Les colonnes repli/suppression sont a 22px tout rond,
     la taille min-width des boutons eux-memes (voir plus bas) : un
     chiffre plus petit ferait deborder le bouton de sa colonne, une
     colonne figee ne s'elargit pas pour un contenu qui deborde.

     Resserrees d'un cran (22/24/70/40 -> 18/20/62/34, soit 365px -> 321px)
     a la demande de saab : "reduis les espaces inutiles dans certaines
     colonnes du tableau", pour rendre la difference au plateau. Les 62px de
     la colonne coup restent mesures sur le plus long texte reel ci-dessus,
     avec de la marge ; les 18px des colonnes repli/suppression restent
     egaux au min-width des boutons eux-memes, pour la meme raison qu'avant. */
  grid-template-columns: 18px 20px 62px 34px 18px 18px 20px 62px 34px 18px;
  align-items: center;
  /* Reduit de 2 a 1px (saab : "essaye de reduire un peu la largeur [sur
     telephone], joue sur les espaces entre les colonnes") — les largeurs
     de colonnes elles-memes restent figees, deja mesurees au plus juste
     (voir le commentaire au-dessus). */
  column-gap: 1px;
  row-gap: 1px;
}

/* min-height reduit de 28 a 20px (saab : "optimiser le plus d'info en
   hauteur") : la precision de la souris n'a pas besoin de la regle des
   44px de CLAUDE.md, reservee au doigt sur telephone — ce panneau n'existe
   de toute facon que sur ordinateur. */
.arbre-repli,
.arbre-supprimer {
  min-width: 18px; /* egal a leur colonne dans .arbre-lignes, voir plus haut */
  min-height: 20px;
  background: none;
  border: none;
  font-size: 12px;
  cursor: pointer;
}

.arbre-repli {
  color: #e4e4e4;
}

.arbre-supprimer {
  color: #a33;
  font-size: 13px;
}

/* Garde sa place dans la grille (voir l'en-tete du fichier) sans se voir
   ni reagir au clic. */
.invisible {
  visibility: hidden;
  cursor: default;
}

.arbre-numero {
  color: #888;
  font-size: 13px;
}

.arbre-noeud {
  cursor: pointer;
  padding: 0 3px; /* vertical retire (saab : "optimiser le plus d'info en hauteur") ; horizontal resserre de 6 a 3 avec la colonne */
  border-radius: 4px;
  overflow-wrap: anywhere;
  /* Alignee sur la taille d'.arbre-suffixes (saab : "diminuer la taille
     des coordonnees pour etre comme celle de eject/date") — heritait avant
     des 14px de base d'#arbre-panneau. */
  font-size: 11px;
}

/* Ejection " (b-w)", fin de partie " [N]"/"[T]" et date de creation d'une
   feuille (format KAAWA AAMMJJHHMM, voir interface/sequence.js) : une
   seule colonne, presente meme vide (voir rendu.creerSuffixes /
   creerSuffixesVide). La date, la plus longue des trois, y passe sur deux
   lignes (colonne volontairement etroite, voir .arbre-lignes plus haut). */
.arbre-suffixes {
  color: #999;
  font-size: 11px;
  overflow-wrap: anywhere;
}

/* Quatre couleurs, meme principe et meme ordre de priorite que l'onglet
   Sequence de KAAWA (_render_tree_recursive) : le noeud courant l'emporte
   sur tout le reste, puis l'origine (la partie REELLEMENT jouee), puis le
   chemin qui y mene, une branche d'exploration sinon. */
.arbre-courant {
  background: #cc6a00; /* orange KAAWA */
  color: #0a0a0a;
  font-weight: bold;
}

.arbre-origine {
  color: #2ecc55; /* vert KAAWA : la ligne reellement jouee */
  font-weight: bold;
}

.arbre-chemin {
  color: #e4e4e4; /* blanc KAAWA : menage vers le noeud courant */
}

.arbre-branche {
  color: #b070e0; /* violet KAAWA : une branche d'exploration quelconque */
}

#arbre-entete.arbre-courant {
  background: #cc6a00;
  color: #0a0a0a;
}

.case {
  fill: #8a8a8a;
  stroke: #5a5a5a;
  stroke-width: 0.5;
}

/* Grand cercle de case du plateau PRINCIPAL seulement (phase 19ter,
   rendu/relief-plateau.js pose cette classe EN PLUS de .case, jamais sur
   les apercus qui n'appellent pas cette fonction). CORRIGE (saab : "le
   ratio des cases vides doit etre de 0.5 par rapport aux billes... ca
   cache les triangles") : ce grand cercle RESTE la vraie zone tactile
   (44px, CLAUDE.md) et le support de .case-possible/.case-selectionnee
   ci-dessous, mais devient TRANSPARENT au repos — le petit trou visuel
   (.case-dimple, plus bas, bien plus petit) le remplace a l'oeil, laissant
   voir le relief triangulaire autour. Declaree ici, AVANT .case-possible
   et .case-selectionnee : meme specificite qu'elles, l'ordre du fichier
   leur laisse le dernier mot sans y toucher. */
.case-relief {
  fill: transparent;
  stroke: none;
  /* Sans ca, un cercle a fill/stroke transparents ne recoit plus AUCUN
     clic (SVG, pointer-events par defaut : visiblePainted, qui exige un
     remplissage ou un contour peint) — casserait le clic sur toute case
     vide du plateau principal. */
  pointer-events: all;
}

/* Case surlignee par interface/saisie.js : une destination possible pour
   la bille selectionnee. Declaree apres .case pour l'emporter (meme
   specificite CSS, l'ordre du fichier tranche). */
.case-possible {
  cursor: pointer;
}

/* Case de la bille selectionnee (rendu/selection.js) : un anneau, jamais
   un remplissage — sa propre couleur de case reste visible dessous,
   contrairement a .case-possible. Meme orange cuivre que KAAWA
   (BG_COLOR, kaa_constants_ClO_Co.py : rgb(200, 127, 50)) par defaut,
   reglable depuis Reglages (saab, 2026-09-26, "Couleur bille sélect" —
   moteur/reglages.js, kaah.select_ring_color). Declaree apres .case pour
   l'emporter (meme specificite, l'ordre du fichier tranche — comme
   .case-possible juste au-dessus). */
.case-selectionnee {
  stroke: var(--couleur-case-selectionnee, #c87f32);
  stroke-width: 1.6;
}

.bille-cercle {
  stroke: #000;
  stroke-width: 0.5;
  cursor: pointer;
}

/* Le glissement d'une bille : rendu/animation.js se contente de changer
   style.transform, c'est cette transition qui fait qu'on la voit bouger
   au lieu de sauter. Duree a garder synchronisee avec DUREE_ANIMATION_MS
   dans animation.js (le delai avant de retirer une bille ejectee du DOM). */
.bille {
  transition: transform 300ms ease-out;
}

/* Couleur des billes (phase 22, interface/reglages.js) : `--couleur-bille-*`
   n'est posee QUE sur #plateau (le plateau principal) — sans elle (apercus de
   Mes parties/Variantes/Puzzles, jamais personnalises, simplification
   assumee), `var(...)` retombe sur la couleur par defaut de KAAWA. */
.bille-noir .bille-cercle {
  fill: var(--couleur-bille-noire, #1f1f1f);
}

.bille-blanc .bille-cercle {
  fill: var(--couleur-bille-blanche, #e4e4e4);
}

/* Aspect visuel du plateau PRINCIPAL, phase 19ter (rendu/relief-plateau.js) —
   jamais sur les apercus, qui n'appellent pas dessinerReliefPlateau. Fond
   hexagonal derriere les cases : sa propre ombre portee, un contour
   discret. `fill` posee en ATTRIBUT par rendu/cadre-plateau.js (phase 22,
   board.bg_color), pas ici — une couleur reglable ne peut pas rester une
   valeur fixe dans cette feuille de style (meme raison que .case-fond-trou
   et .relief-dessus, plus bas). */
.fond-plateau {
  filter: url(#ombre-fond-plateau);
}

/* Mode simple (phase 22, rendu/relief-plateau.js) : ni cylindres de relief ni
   trous ne sont crees, donc plus de <defs> a filtrer — le filtre d'ombre du
   fond, lui, referencerait un degrade absent sans cette regle. */
#plateau.mode-simple .fond-plateau {
  filter: none;
}

/* Trous plats du mode simple (rendu/trous-simples.js) : teintes avec le fond
   du plateau, "un seul bloc de matiere" comme le reste du plateau, meme
   contour que l'ancienne case pleine (.case). Jamais cliquables : la case,
   transparente et pleine taille par-dessus (.case-relief), recoit les
   touchers, quelle que soit la taille choisie pour le trou. */
.trou-simple {
  fill: var(--couleur-case-plate, #8a8a8a);
  stroke: #5a5a5a;
  stroke-width: 0.5;
  pointer-events: none;
}

/* Trou perfore au centre de chaque case (phase 19ter, rendu/relief-plateau.js) :
   la PAROI (l'anneau, degrade sombre en haut-gauche, clair en bas-droite) puis
   le FOND, un cercle plus petit en #5A5A5A qui prend l'ombre de la paroi
   (filtre ombre-fond-trou). Jamais cliquables : le grand cercle transparent
   en dessous (.case-relief) recoit les clics. */
.case-dimple {
  fill: url(#degrade-paroi-trou);
  pointer-events: none;
}

/* `fill` posee en ATTRIBUT par rendu/relief-plateau.js (phase 22,
   board.hole_color), pas ici : une couleur reglable ne peut pas rester une
   valeur fixe dans cette feuille de style. */
.case-fond-trou {
  filter: url(#ombre-fond-trou);
  pointer-events: none;
}

/* Relief ENTRE les cases (rendu/relief-cylindres.js) : un cylindre biseaute
   par triangle. Les 3 faces biseautees ET le dessus plat portent leur
   couleur en ATTRIBUT (phase 22, board.bg_color — meme raison que
   .case-fond-trou juste au-dessus) ; ici seulement le contour de cylindre.
   Une seule ombre portee sur tout le groupe. */
.relief-cylindres {
  filter: url(#ombre-relief-plateau);
}

.relief-contour {
  fill: none;
  stroke: #000;
  stroke-opacity: 0.25;
  stroke-width: 0.2;
}

/* Billes du plateau PRINCIPAL uniquement : degrade radial (effet glace,
   eclairage haut-gauche comme le reste du plateau) et ombre portee.
   Selecteur ANCESTRE sur #plateau, jamais une classe posee sur chaque
   bille : couvre aussi bien les billes de depart que celles qui
   reapparaissent plus tard (annuler un coup, rendu/plateau-svg.js,
   synchroniserBilles), sans jamais avoir besoin d'y repenser. Specificite
   volontairement plus forte que .bille-noir/.bille-blanc .bille-cercle
   (un ID en plus) : l'emporte sans dependre de l'ordre du fichier. */
/* `:not(.mode-simple)` sur ces trois regles (phase 22) : en mode simple
   (rendu/relief-plateau.js), ni le filtre `#ombre-bille-plateau` ni les
   degrades `#degrade-bille-*` n'existent — y referer quand meme peindrait
   les billes de la mauvaise couleur (voire invisibles). Les billes y
   gardent alors leur remplissage PLAT (.bille-noir/.bille-blanc
   .bille-cercle, plus haut). */
#plateau:not(.mode-simple) .bille {
  filter: url(#ombre-bille-plateau);
}

/* Contour fin et gris (#646464), pas le trait noir epais des apercus : un
   trait noir ne fait pas realiste sur une bille glacee (signale par saab). */
#plateau .bille-cercle {
  stroke: #646464;
  stroke-width: 0.25;
}

#plateau:not(.mode-simple) .bille-noir .bille-cercle {
  fill: url(#degrade-bille-noir);
}

#plateau:not(.mode-simple) .bille-blanc .bille-cercle {
  fill: url(#degrade-bille-blanc);
}

/* Fin de partie (phase 30, saab) : les billes du perdant — des deux camps pour
   une nulle — a la taille du trou (RAYON_TROU_CENTRAL / RAYON_BILLE,
   rendu/relief-plateau.js), autour de leur propre centre. */
.bille-cercle {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 300ms ease-out;
}

#plateau.perdant-noir .bille-noir .bille-cercle,
#plateau.perdant-blanc .bille-blanc .bille-cercle {
  transform: scale(var(--echelle-bille-perdante, 0.8));
}

/* Pistes des billes ejectees (phase 11, rendu/ejections.js), en haut et en
   bas du plateau : une case vide par ejection possible, remplie de la
   couleur de la bille au fur et a mesure. */
.piste-case {
  fill: var(--fond-case-piste-vide);
  stroke: #5a5a5a;
  stroke-width: 0.4;
}

/* Sa bille vole encore vers elle (rendu/vol-ejection.js) : la case reste
   vide jusqu'a son arrivee, meme une fois le compte mis a jour. 3 classes :
   l'emporte sur .piste-ejection-noir .piste-remplie (2). */
.piste-case.piste-remplie.piste-en-attente {
  fill: var(--fond-case-piste-vide);
}

/* Une bille en vol n'est plus une bille du jeu : on ne la touche pas. */
.bille-en-vol {
  pointer-events: none;
}

/* Le cercle de chaque case de piste est TOUJOURS de la couleur du camp qui
   possede la piste, vide ou remplie ; la case se remplit, elle, de la couleur
   des billes ejectees (saab). Noir joue en bas : la piste du bas, celle des
   billes BLANCHES qu'il a ejectees, a donc un cercle noir, et inversement.
   Couleurs des billes reglees (index.html pose les variables) : comme le
   libelle Bonus, cercles et cases suivent les billes (saab) — seule la corde
   (rendu/corde.js) reste en noir et blanc. */
.piste-ejection-noir .piste-case {
  stroke: var(--couleur-bille-blanche, #e4e4e4);
  stroke-width: 0.6;
}

.piste-ejection-blanc .piste-case {
  stroke: var(--couleur-bille-noire, #1f1f1f);
  stroke-width: 0.6;
}

.piste-ejection-noir .piste-remplie {
  fill: var(--couleur-bille-noire, #1f1f1f);
}

.piste-ejection-blanc .piste-remplie {
  fill: var(--couleur-bille-blanche, #e4e4e4);
}

/* La corde (rendu/corde.js) : toujours en noir et blanc, jamais aux couleurs
   des billes — on sait ainsi qui a commence. Son fond prend la couleur du
   plateau en attribut (reglable), comme .fond-plateau. */
.corde {
  fill: none;
  stroke-width: 1.0;
  stroke-linejoin: round;
  stroke-linecap: round;
  pointer-events: none;
}

.corde-noir { stroke: #1f1f1f; }
.corde-blanc { stroke: #e4e4e4; }

.fond-corde {
  pointer-events: none;
}

/* Le cadre du compteur Occ : pointille noir et blanc sur le gris du plateau
   PAR DEFAUT (moteur/reglages.js, bg_color) — il ne change jamais (saab). */
.cadre-occurrences {
  pointer-events: none;
}

.cadre-occurrences-fond {
  fill: var(--fond-cadre-occurrences);
  stroke: #e4e4e4;
  stroke-width: 0.5;
}

.cadre-occurrences-tirets {
  fill: none;
  stroke: #1f1f1f;
  stroke-width: 0.5;
  stroke-dasharray: 1.5 1.5;
}

/* Alerte sur une piste : il ne reste plus qu'une ejection avant la
   defaite du camp ADVERSE (seuil SEUIL_ALERTE_EJECTIONS, 5 sur 6 — meme
   seuil que KAAWA). Vert, pas rouge : le rouge est reserve au nom du
   camp qui, LUI, est en danger (voir .nom-en-danger) — deux signaux
   distincts, comme dans KAAWA. */
/* L'alerte est un SECOND anneau vert, a l'INTERIEUR du cercle du camp (qui
   reste donc toujours visible, saab), et non plus un contour qui le
   remplacait. Un anneau par case (rendu/pistes-triangle.js), cache tant que
   l'alerte n'est pas donnee. */
.piste-anneau-alerte {
  display: none;
  fill: none;
  stroke: #2ecc55;
  stroke-width: 0.8;
  pointer-events: none;
}

.piste-anneau-alerte.piste-alerte {
  display: inline;
}

/* Ligne d'un joueur (rendu/ligne-joueur.js) : un cadre REMPLI de la couleur
   des billes du camp (verifie dans kaa_constants_ClO_Co.py : PLAYER_B_TEXT =
   #1f1f1f, PLAYER_W_TEXT = #e4e4e4), le nom en gris. Seul le NOM passe en
   rouge en danger. Le cadre ORANGE, comme
   les boutons actifs, n'entoure que "Tour N"/"Gagne"/"Nulle" et n'existe que
   pour le camp qui a la main : c'est lui qui dit a qui c'est de jouer. Le
   rouge du nom (3 classes) l'emporte sur sa couleur de camp (2 classes) sans
   dependre de l'ordre du fichier. `cursor: pointer` : le cadre du nom et
   celui du tour se cliquent (saisie du nom ; choix abandon/nulle). */
.nom-joueur {
  font: 5px sans-serif;
}

.nom-fond,
.nom-tour-cadre {
  cursor: pointer;
}

.nom-joueur-noir .nom-fond {
  fill: #1f1f1f;
}

.nom-joueur-blanc .nom-fond {
  fill: #e4e4e4;
}

/* Le nom est gris sur les deux cadres, comme les chiffres des pendules : c'est
   le cadre qui porte la couleur du camp (saab). */
.nom-joueur-noir .nom-texte,
.nom-joueur-blanc .nom-texte {
  fill: #828282;
}

.nom-joueur.nom-en-danger .nom-texte {
  fill: #e04040;
  font-weight: bold;
}

.nom-texte,
.nom-tour {
  pointer-events: none; /* le clic est recu par le cadre en dessous */
}

.nom-tour-cadre {
  fill: #cc6a00;
}

.nom-tour {
  fill: #0a0a0a;
}

.nom-tour-options {
  font-size: 4px; /* " Options" en fin de partie */
}

/* Abandon / nulle (rendu/abandon-nulle.js) : une confirmation qui recouvre la ligne
   dans un cadre vert avec deux boutons gris (saab). */
.confirmation-bouton {
  cursor: pointer;
}

.confirmation-bouton-fond {
  fill: #828282;
}

.confirmation-bouton-texte {
  fill: #0a0a0a;
  font: 4.4px sans-serif;
  pointer-events: none;
}

/* Boutons permanents Abandonner / Nulle de chaque joueur (rendu/boutons-fin-piste.js),
   pres de son compteur d'ejections : le meme gris que les choix ci-dessus, grises quand
   ils ne sont pas possibles, verts tant que leur confirmation attend. */
.bouton-fin-piste {
  cursor: pointer;
}

.bouton-fin-piste-fond {
  fill: #828282;
}

/* Abandonner en rouge, Nulle en bleu (saab), dessin blanc. */
.bouton-fin-piste[data-action='abandon'] .bouton-fin-piste-fond {
  fill: #b3261e;
}

.bouton-fin-piste[data-action='nulle'] .bouton-fin-piste-fond {
  fill: #1d5fbf;
}

.bouton-fin-piste-dessin {
  fill: #ffffff;
  pointer-events: none;
}

.bouton-fin-piste-inactif {
  opacity: 0.35;
  cursor: default;
}

.bouton-fin-piste.demande-en-cours .bouton-fin-piste-fond {
  fill: var(--vert-demande);
}

.confirmation-fond {
  fill: #1f7a3a;
}

.confirmation-question {
  fill: #ffffff;
  font: bold 4.4px sans-serif;
  pointer-events: none;
}

/* Temps restant de chaque camp (interface/pendules.js), affiche a cote de
   sa piste d'ejection — remplace l'ancien bandeau HTML #pendules. Taille
   augmentee (8px -> 11px, signale par saab) tout en restant sous
   .nombre-ejecte, comme dans KAAWA (font_size_ejected > clock font_big >
   font_size_player_name, verifie dans kaa_board_widget_ClO_Co.py). Pas de
   `fill` ici (voir .pendule-camp-noir/-blanc plus bas) : meme technique
   que .nom-joueur/.nom-joueur-noir, une specificite volontairement
   FAIBLE pour que l'alerte (2 classes) l'emporte toujours, quel que soit
   l'ordre des regles dans le fichier. */
.pendule-camp {
  /* 10 px (11 avant) : les bandes vertes "||" de chaque cote des chiffres ont besoin de
     leur place dans l'epaisseur du cadre (rendu/pendule.js). */
  font: 10px sans-serif;
}

/* Le CADRE de la pendule est de la couleur des billes du camp (voir
   .cadre-pendule-noir/-blanc plus bas) et les CHIFFRES sont gris (saab). */
.pendule-camp-noir,
.pendule-camp-blanc {
  fill: #828282;
}

/* Alerte sous le seuil (interface/pendules.js, SECONDES_ALERTE_PENDULE) :
   2 classes, l'emporte sur les 2 regles par-camp ci-dessus quel que soit
   l'ordre des regles dans le fichier (meme technique que .nom-en-danger). */
.pendule-camp.pendule-alerte {
  fill: #e04040;
  font-weight: bold;
}

/* Cadre-bouton autour de chaque pendule (rendu/pendule.js,
   dessinerPendule) : gris, cliquable — sert de Start/Pause (signale par
   saab, voir interface/saisie.js, basculerPause). */
.bouton-pendule {
  cursor: pointer;
}

.cadre-pendule {
  /* Le gris des cases du plateau (.case), pas un gris fonce quelconque —
     saab : le gris fonce manquait de contraste avec le noir du texte. */
  fill: #8a8a8a;
  stroke: #5a5a5a;
  stroke-width: 0.3;
}

/* Le vert des demandes (--vert-demande) tant qu'on attend un clic pour demarrer
   ou reprendre les pendules (au depart, et en pause) ; deux bandes vertes "||"
   au-dessus et au-dessous des chiffres quand elles tournent (interface/
   pendules.js, signalerEtatPause). 2 classes : l'emporte sur .cadre-pendule-noir/
   -blanc quel que soit l'ordre du fichier. */
.bouton-pendule.pendule-en-attente .cadre-pendule {
  fill: var(--vert-demande);
}

.bouton-pendule.pendule-en-attente .pendule-camp {
  fill: #e4e4e4;
}

/* La machine reflechit (phase 29, interface/ia.js) : sa pendule respire
   doucement, pour qu'on sache qu'elle cherche (plusieurs secondes au niveau 3)
   et pas que l'appli est figee. */
.bouton-pendule.machine-reflechit .cadre-pendule {
  animation: machine-reflechit 1s ease-in-out infinite alternate;
}

@keyframes machine-reflechit {
  to {
    opacity: 0.45;
  }
}

@media (prefers-reduced-motion: reduce) {
  .bouton-pendule.machine-reflechit .cadre-pendule {
    animation: none;
    opacity: 0.6;
  }
}

.pendule-bande {
  display: none;
  fill: var(--vert-demande);
  pointer-events: none;
}

.pendule-en-marche .pendule-bande {
  display: inline;
}

/* Cadre de la couleur des billes du camp (saab), chiffres gris. */
.cadre-pendule-noir {
  fill: #1f1f1f;
}

.cadre-pendule-blanc {
  fill: #e4e4e4;
}

/* Libelle de mode pres de chaque pendule (phase 22bis, rendu/pendule.js,
   dessinerLibellePendule) : CORRIGE (saab) — plus petit que le compteur
   Occ/Ref (.compteur-occurrences-plateau, 6px), colle contre la pendule
   dans le vide deja existant plutot que dans une bande a part. */
.libelle-pendule {
  /* Gras (correctif, saab : "le noir ne se voit pas bien") : l'encre d'un
     trait plus epais se voit mieux sur le fond gris moyen du plateau,
     surtout pour le camp noir (tres sombre). */
  font: bold 4px sans-serif;
}

/* Dans la pendule, en gris comme ses chiffres (saab, 2026-09-25) : c'est le
   cadre noir ou blanc qui dit le camp, jamais le texte — aux couleurs des
   billes, il ne se voyait pas sur le gris. Clair sur le vert d'attente. */
.libelle-pendule {
  fill: #828282;
}

.bouton-pendule.pendule-en-attente .libelle-pendule {
  fill: #e4e4e4;
}

/* Compte numerique des billes ejectees (rendu.dessinerNombreEjecte), a
   gauche de sa piste — retire par erreur dans un correctif precedent en
   le croyant redondant avec la piste visuelle ; KAAWA l'affiche bel et
   bien, en plus gros que le nom du joueur (verifie dans son code source,
   font_size_ejected largement superieur a font_size_player_name), remis
   ici avec la meme hierarchie. Pas de `fill` ici : voir
   .nombre-ejecte-noir/-blanc plus bas, meme technique que .pendule-camp. */
.nombre-ejecte {
  font: bold 14px sans-serif;
}

/* Le compte est le SCORE du camp qui possede la piste (celui qui a ejecte ces
   billes) : ecrit en gris, comme les chiffres des pendules, dans un cadre de
   la couleur de ce camp — noir ou blanc, comme le cadre de sa pendule, quelles
   que soient les couleurs des billes (saab). */
.nombre-ejecte {
  fill: #828282;
}

.cadre-compte-ejections-noir { fill: #1f1f1f; }
.cadre-compte-ejections-blanc { fill: #e4e4e4; }

/* Chaque bouton Abandonner / Nulle entoure de la couleur de son camp. */
.bouton-fin-piste[data-camp='noir'] .bouton-fin-piste-fond {
  stroke: #1f1f1f;
  stroke-width: 0.6;
}

.bouton-fin-piste[data-camp='blanc'] .bouton-fin-piste-fond {
  stroke: #e4e4e4;
  stroke-width: 0.6;
}

/* Compteur Occ/Ref/Br_Occ/Br_Ref a la verticale, tout a gauche du plateau
   (rendu/ejections.js, dessinerCompteurOccurrences) — comme KAAWA
   (kaa_board_widget_ClO_Co.py, _add_occurrence_label), etendu aux 4
   compteurs. `fill` (pas `color`) : c'est un <text>/<tspan> SVG, meme
   raison que .nombre-ejecte-noir/-blanc juste au-dessus. */
.compteur-occurrences-plateau {
  font: 6px sans-serif;
  fill: #ffd700; /* jaune KAAWA par defaut, voir le <tspan> individuel pour le seuil */
}

/* Bordure de coordonnees permanente (a-i/1-9), phase 19bis :
   rendu/coordonnees-bord.js. Gris neutre — un simple repere, jamais une
   information de jeu (pas de rouge, de vert ni d'orange a lui reserver). */
.coordonnee-bord {
  font: 5px sans-serif;
  fill: var(--couleur-coordonnee-bord);
}

/* Les chiffres, inclines, touchaient un peu les cylindres : plus petits que
   les lettres, qui elles ne les touchent pas (signale par saab). */
.coordonnee-bord-chiffre {
  font-size: 4px;
}

/* Coordonnees EN COURS DE PARTIE, phase 19bis (rendu/coordonnees-jeu.js) :
   sur les billes du camp au trait (contraste inverse de la bille, comme
   .nom-joueur-noir/-blanc) et sur les cases de destination possibles (en
   blanc sur le vert de .case-possible). `pointer-events: none` sur les
   deux : ce texte ne doit jamais voler le clic a la bille ou a la case
   sous lui (la case de destination est un <text> A PART, siblings du
   <circle> dans le meme <svg>, pas un enfant — sans ca, cliquer pile sur
   la lettre manquerait le data-notation de la vraie case). */
.coordonnee-bille,
.coordonnee-destination {
  font: bold 5px sans-serif;
  pointer-events: none;
}

/* Tailles reglables separement (saab, 2026-09-27, Reglages > Affichage ;
   jamais plus grandes que la bille, moteur/reglages.js BORNES_REGLAGES_KAAH).
   Apres le raccourci `font` ci-dessus, pour l'emporter sur sa taille. */
.coordonnee-bille {
  font-size: var(--taille-coordonnee-bille, 5px);
}

.coordonnee-destination {
  font-size: var(--taille-coordonnee-arrivee, 5px);
}

/* Contraste inverse de la bille qui la porte : claire sur bille noire,
   foncee sur bille blanche — chacune reglable (Reglages > Coordonnees). Une
   seule couleur pour les deux camps (2026-09-26) rendait la coordonnee
   invisible sur les billes blanches (saab, 2026-09-27). */
.bille-noir .coordonnee-bille {
  fill: var(--couleur-coordonnee-bille, #e4e4e4);
}

.bille-blanc .coordonnee-bille {
  fill: var(--couleur-coordonnee-bille-blanche, #1f1f1f);
}

/* Reglage "Coordonnées sur les billes" (phase 22, interface/reglages.js) :
   les etiquettes restent CONSTRUITES en permanence (interface/saisie.js,
   actualiserCoordonneesBilles) — seule cette classe, sur #plateau, les
   masque, pour qu'un clic sur la case a cocher les fasse disparaitre EN
   DIRECT sans reconstruire quoi que ce soit. Jamais .coordonnee-destination
   (les chiffres verts d'une selection active) : reglage sans rapport. */
#plateau.coordonnees-billes-masquees .coordonnee-bille {
  display: none;
}

.coordonnee-destination {
  fill: #fff;
}

/* Case d'arrivee possible : un rond vert TRANSLUCIDE de la taille du trou,
   pose SOUS sa coordonnee dans le DOM (rendu/coordonnees-jeu.js) — elle
   reste ainsi toujours lisible, meme sur un fond de case clair (saab,
   2026-09-27 : "le meme pb si ca tombe sur une blanche", voir
   .voile-selectionnable plus bas). Vert par defaut, reglable depuis
   Reglages (saab, 2026-09-26, "Couleur case arrivée" — moteur/reglages.js,
   kaah.dest_fill_color). */
.voile-destination {
  fill: var(--couleur-case-arrivee, #00aa3e);
  fill-opacity: 0.6;
  pointer-events: none;
}

/* Bille SELECTIONNABLE (celles du camp au trait, tant qu'aucune selection
   n'est active) : meme rond vert, meme taille (celle du trou, pas de la
   bille), meme opacite et meme couleur reglable que .voile-destination
   ci-dessus (saab, 2026-09-27 : "rester dans la logique du vert" —
   rendu/coordonnees-jeu.js, actualiserBillesSelectionnables). Toujours SOUS
   la coordonnee de la bille dans le DOM (voir cette fonction) : la meme
   opacite qu'une case d'arrivee reste lisible ici, contrairement a un
   premier essai ou ce rond passait PAR-DESSUS la coordonnee (saab,
   2026-09-27bis : illisible sur les billes blanches, quelle que soit
   l'opacite choisie). Un interrupteur a part ("Sélection sur bille",
   moteur/reglages.js kaah.show_selectable_balls) la masque en direct, voir
   juste en dessous. */
.voile-selectionnable {
  fill: var(--couleur-case-arrivee, #00aa3e);
  fill-opacity: 0.6;
  pointer-events: none;
}

#plateau.selection-bille-masquee .voile-selectionnable {
  display: none;
}

/* Fleche (chevron) du dernier coup, phase 19bis (rendu/fleche-dernier-coup.js) :
   contraste inverse de la bille qui la porte, meme principe que
   .coordonnee-bille juste au-dessus. `fill: none` : seul le CONTOUR du
   chevron doit se voir, jamais un triangle plein. */
.fleche-dernier-coup {
  fill: none;
  stroke-width: 0.9;
  stroke-linejoin: round;
  stroke-linecap: round;
  pointer-events: none;
}

/* Couleurs du chevron reglables (saab, 2026-09-27, Reglages > Chevron ;
   rendu/apparence-reglages.js), repli = l'aspect d'avant. */
.bille-noir .fleche-dernier-coup {
  stroke: var(--couleur-chevron-bille-noire, #e4e4e4);
}

.bille-blanc .fleche-dernier-coup {
  stroke: var(--couleur-chevron-bille-blanche, #1f1f1f);
}

/* Poussee qui ejecte : rouge, TOUJOURS (voir rendu/fleche-dernier-coup.js) —
   sur les deux camps, jamais le contraste noir/blanc habituel. 3 classes
   pour l'emporter sur .bille-noir/.bille-blanc .fleche-dernier-coup
   ci-dessus, quel que soit l'ordre du fichier (meme piege de specificite
   que .nom-joueur-noir.au-trait.nom-en-danger, deja rencontre). */
.bille-noir .fleche-dernier-coup.fleche-dernier-coup-ejection,
.bille-blanc .fleche-dernier-coup.fleche-dernier-coup-ejection {
  stroke: var(--couleur-chevron-ejection, #e04040);
}

/* Seuil de nulle atteint sur CE segment (Occ, Ref, Br_Occ ou Br_Ref
   individuellement) : meme bleu que .compteur-occurrences-seuil et
   .etiquette-occurrence-tag-seuil, un seul signal bleu dans toute
   l'appli. Porte sur le <tspan> du chiffre concerne, jamais sur toute la
   ligne : Occ peut avoir atteint son seuil sans que Ref (ou l'inverse)
   ait atteint le sien. */
.compteur-occurrences-plateau-seuil {
  fill: #4aa8ff;
}

/* Le meme compteur sous le titre, pendules a l'horizontale (saab, 2026-10-01) — sur le meme
   fond que son cadre a gauche du plateau (« Fond Occ », .cadre-occurrences-fond) : un fond de
   fenetre change ne lui retire jamais son contraste (saab, 2026-10-23). */
.compteur-occurrences-entete {
  justify-self: center;
  width: fit-content;
  max-width: 100%;
  box-sizing: border-box;
  background: var(--fond-cadre-occurrences);
  border: 1px solid #e4e4e4;
  border-radius: 4px;
  padding: 1px 6px;
  font: 12px sans-serif;
  color: #ffd700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.compteur-occurrences-entete .compteur-occurrences-plateau-seuil {
  color: #4aa8ff;
}

/* Grand bouton rond de pause (rendu/pendule.js, afficherPause) : masque
   tout le plateau, vert avec deux barres blanches ("||") — signale par
   saab. `pointer-events` sur le groupe entier via le clic delegue de
   interface/saisie.js (svg.addEventListener('click', ...), pas besoin
   d'un ecouteur ici). */
.fond-pause {
  fill: #000;
  opacity: 0.75;
}

.bouton-pause-rond {
  fill: var(--vert-demande); /* le meme vert que toutes les demandes (choisi par saab) */
  cursor: pointer;
}

.barre-pause {
  fill: #fff;
  pointer-events: none; /* le clic doit atteindre le rond en dessous, pas s'arreter sur une barre */
}

.numero-pause {
  fill: #fff;
  font-family: sans-serif;
  font-weight: bold;
  pointer-events: none; /* meme raison que .barre-pause */
}

/* Colonne d'icones (saab : "les cadres de tous les 12 boutons ... toucher la
   bordure noire du groupe") : plus de marge ENTRE le cadre d'un bouton et la
   bordure de son groupe, ni autour des groupes. Barre de defilement cachee : la
   colonne defile toujours (doigt, molette) mais une barre classique lui
   mangeait 15 px de large. */
#colonne-gauche {
  padding: 2px;
  scrollbar-width: none;
}

#colonne-gauche::-webkit-scrollbar {
  display: none;
}

/* Fixe en haut de la colonne, qu'elle defile ou non (saab : il fallait remonter
   toute la colonne pour le retrouver). `z-index` : au-dessus des boutons qui
   remontent sous lui en defilant ; son propre fond (deja opaque, voir plus
   haut) les cache au passage, sans qu'il faille le repeter ici. */
#bouton-etendre-colonne {
  position: sticky;
  top: 0;
  z-index: 1;
}

.groupe-boutons {
  padding: 0;
  gap: 2px;
  overflow: hidden;
}

/* Les trois icones dessinees a la main (Sequence, Commentaires,
   Occurrences) : plus grandes, elles paraissaient petites dans le cadre
   agrandi. */
.icone-bouton.icone-carre {
  width: 32px;
  height: 32px;
}

/* Le grand Annuler (phase 31, saab : « un large btn Annuler independant ...
   plus facile d'acces pour les 2 joueurs ») : toute la largeur de sa barre. */
#nav-annuler {
  flex: 1 1 auto;
  min-height: var(--hauteur-commande);
  font-weight: bold;
  font-size: 18px;
}

/* Le bouton Annuler de la navigation est TOUJOURS vert (saab) — sauf quand il
   n'y a rien a annuler (au depart, ou sur un coup d'origine deja depasse) : il
   est alors grise comme les autres (#navigation button:disabled). Le cadre
   "Tour N", lui, ne devient vert que tant qu'un abandon ou une nulle attend
   sa reponse. */
#nav-annuler:not(:disabled) {
  background: var(--vert-demande);
  border-color: var(--vert-demande);
  color: #ffffff;
}

.nom-joueur.demande-en-cours .nom-tour-cadre,
.nom-joueur.attend-choix-fin .nom-tour-cadre {
  fill: var(--vert-demande);
}

.nom-joueur.demande-en-cours .nom-tour,
.nom-joueur.attend-choix-fin .nom-tour {
  fill: #ffffff;
}

/* Le cadre du resultat ("Gagné", "Nulle", avec ou sans " Options",
   rendu/ligne-joueur.js) : vert et quelques clignotements, comme le bandeau
   d'un puzzle (saab : texte de fin pas assez visible). Dans un puzzle, il prend
   la couleur du verdict (index.html pose la classe sur le plateau) : rouge si
   ce n'est pas la solution, orange tant que ce n'est pas tranche. */
.nom-joueur.resultat-fin .nom-tour-cadre {
  fill: var(--vert-demande);
}
.nom-joueur.resultat-fin .nom-tour {
  fill: #ffffff;
}
.nom-joueur.resultat-fin .nom-tour-cadre,
.nom-joueur.resultat-fin .nom-tour {
  animation: clignoter-fin 0.8s ease-in-out 8;
}
#plateau.verdict-puzzle-refus .nom-joueur.resultat-fin .nom-tour-cadre { fill: #a82828; }
#plateau.verdict-puzzle-incertain .nom-joueur.resultat-fin .nom-tour-cadre { fill: #9a5a00; }

/* Le camp qui a PERDU (ejections ou abandon, jamais une nulle) recoit "Perdu"
   / "Perdu Options" dans le meme cadre que le gagnant, mais en ROUGE
   (rendu/ligne-joueur.js, .perdant) : demande de saab, pour que le perdant
   puisse lui aussi ouvrir les Options. Selecteur a deux classes, plus
   specifique que .resultat-fin/.attend-choix-fin seuls : l'emporte quel que
   soit l'ordre du fichier. */
.nom-joueur.perdant.resultat-fin .nom-tour-cadre,
.nom-joueur.perdant.attend-choix-fin .nom-tour-cadre {
  fill: #a82828;
}

/* Aide simplifiee (interface/aide.js) : le titre et Fermer restent FIXES en haut,
   le corps defile au milieu avec sa barre TOUJOURS visible (`overflow-y: scroll`),
   Fermer aussi en bas — on n'a jamais a defiler pour fermer (saab). Les rubriques
   se touchent sur toute leur largeur (44 px). `[open]` : sans lui, `display: flex`
   afficherait la boite meme fermee. */
.dialogue-aide {
  max-width: 560px;
  font: 14px sans-serif;
  line-height: 1.4;
}

/* Le titre et les boutons (English, Fermer) sur la premiere ligne, puis les lignes de la version sur
   TOUTE la largeur (saab, 2026-10-24 : « le texte ne prend tjs pas toute la largeur, il s'arrête à
   English ») : la colonne du texte s'efface (display: contents), ses lignes passent sous les boutons. */
.aide-entete {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: start;
  column-gap: 8px;
}
.aide-entete > div:first-child {
  display: contents;
}
.aide-entete > div:first-child > :not(h2) {
  grid-column: 1 / -1;
}
.aide-entete .boutons-entete-aide {
  grid-column: 2;
  grid-row: 1;
}

.aide-entete .bouton-dialogue {
  flex: 0 0 auto;
  margin-top: 0;
  min-height: var(--hauteur-commande);
}

.dialogue-aide .aide-corps {
  overflow-y: scroll; /* barre TOUJOURS visible : on voit qu'on peut defiler */
}

/* Chercher dans l'Aide (interface/aide-recherche.js) : le champ sous le titre,
   fixe lui aussi ; les endroits trouves surlignes, le courant en orange. */
.aide-recherche {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0 0 6px;
}

.aide-recherche input {
  flex: 1 1 auto;
  min-width: 0;
  height: var(--hauteur-commande);
  box-sizing: border-box;
}

.aide-recherche .bouton-dialogue {
  flex: 0 0 auto;
  min-width: var(--hauteur-commande);
  min-height: var(--hauteur-commande);
  margin: 0;
  padding: 0 6px;
}

.aide-compte {
  flex: 0 0 auto;
  font-size: 12px;
  color: #c4c4c4;
}

mark.aide-trouve {
  background: #6b5a14;
  color: inherit;
}

mark.aide-trouve.aide-trouve-courant {
  background: #cc6a00;
  color: #0a0a0a;
}

.dialogue-aide summary {
  display: flex;
  align-items: center;
  min-height: var(--hauteur-commande);
  font-weight: bold;
  cursor: pointer;
}

.dialogue-aide ul {
  margin: 0 0 8px;
  padding-left: 20px;
}

.dialogue-aide li {
  margin-bottom: 6px;
}

/* Version et Hors ligne en orange (saab, 2026-10-01 : « c'est ce qui est
   actif ») ; les chapitres en vert, numerotes (interface/aide.js) : ils
   attendent un geste, plier ou deplier. */
.aide-version {
  margin: 0 0 4px;
  color: #e0832a;
  font-size: 12px;
}

/* Les modes Entrainement et Ceinture, en vert (saab, 2026-10-10). */
.aide-modes {
  color: #45b862;
}

/* L'en-tete replie au premier clic (interface/aide.js) : la version et le hors-ligne
   restent ; ils se touchent pour revoir les autres lignes (la marque verte le dit). */
.aide-entete-repliee #hors-ligne-kaah ~ .aide-version {
  display: none;
}

#version-kaah,
#hors-ligne-kaah {
  cursor: pointer;
}

.aide-entete-repliee #hors-ligne-kaah::after {
  content: ' ▸ …';
  color: #45b862;
}

/* Nouvelle version et Replier / Déplier, sur une ligne (saab, 2026-10-28 : interface/aide.js). */
.aide-entete .boutons-version-aide {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 2px 0 6px;
}
.aide-entete .boutons-version-aide .bouton-nouvelle-version {
  margin: 0;
}

/* Les fleches de la recherche, grisees tant que rien n'est trouve (interface/aide-recherche.js). */
#bouton-precedent-aide:disabled,
#bouton-suivant-aide:disabled {
  opacity: 0.35;
  cursor: default;
}

.dialogue-aide .aide-corps > details > summary {
  color: #45b862;
}

/* Bloc-notes personnel (phase 27, interface/notes-perso.js) : un simple
   <textarea> pleine largeur/hauteur, enregistre a chaque frappe. */
.champ-notes-perso {
  width: 100%;
  min-height: 200px;
  margin: 8px 0;
  padding: 6px 8px;
  box-sizing: border-box;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  background: #101010;
  color: #e4e4e4;
  font: 13px/1.4 sans-serif;
  resize: none; /* deja plein ecran/hauteur disponible, un redimensionnement manuel n'ajouterait rien */
}

#bouton-fermer-aide {
  flex: 0 0 auto;
  min-height: var(--hauteur-commande);
}

/* Rangee de classement des dialogues Variantes et Puzzles (interface/filtres-
   classement.js) : une seule rangee, defilement horizontal a barre visible, boutons
   de 44 px de haut. */
.barre-filtres {
  display: flex;
  gap: 6px;
  margin: 4px 0;
  padding-bottom: 4px;
  overflow-x: scroll;
}

.bouton-filtre {
  flex: 0 0 auto;
  min-height: var(--hauteur-commande);
  padding: 0 7px;
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
}

.bouton-filtre.bouton-actif {
  background: #cc6a00;
  color: #0a0a0a;
  border-color: #cc6a00;
}

/* Boite des sons (interface/reglages-sons.js) : une ligne = un reglage, toute
   la ligne se touche (44 px). Le "Son global" decoche grise les autres. */
#liste-sons {
  /* Deux colonnes quand la boite est assez large : sept lignes de 44 px ne
     tiennent pas sur un telephone couche (375 px de haut). */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  column-gap: 8px;
}

.ligne-reglage {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--hauteur-commande);
  cursor: pointer;
}

/* Mode de pendule (phase 22bis, dialogue-mode-pendules) : les 3 boutons
   Chrono/Bonus/Delai reutilisent .bouton-filtre (44px, .bouton-actif deja
   orange, meme technique que Variantes/Puzzles) ; les champs numeriques
   ci-dessous n'apparaissent que pour le mode choisi (voir
   interface/pendules-mode.js). */
#dialogue-mode-pendules .boutons-dialogue-cote-a-cote {
  margin: 10px 0;
}

.section-mode-pendule {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Sans cette regle, le `display: flex` ci-dessus l'emporte sur l'attribut
   `hidden` : en Chrono, « Temps initial 300 » restait affiche (saab : « le
   Chrono est tjs a 300 »). */
.section-mode-pendule[hidden] {
  display: none;
}

.ligne-nombre-pendule {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: var(--hauteur-commande);
}

.ligne-nombre-pendule input {
  width: 70px;
  min-height: 32px;
  font-size: 14px;
  text-align: right;
}

.ligne-reglage input {
  width: 22px;
  height: 22px;
}

.reglages-inactifs .ligne-reglage:not(:first-child):not(.reglage-independant) {
  opacity: 0.4;
}

/* Curseur de volume (phase 21bis, index.html/interface/sons.js) : une ligne
   a part, jamais grisee par .reglages-inactifs — regler le volume avant de
   reactiver le son global reste utile. Zone tactile de 44px malgre le
   curseur fin (CLAUDE.md), le curseur lui-meme grandit sur son axe. */
.ligne-volume-sons {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--hauteur-commande);
}

.ligne-volume-sons input {
  flex: 1 1 auto;
  min-width: 0;
  height: 28px;
}

/* Champ de saisie du nom d'un joueur (interface/noms-joueurs.js). */
#champ-nom-joueur {
  width: 100%;
  box-sizing: border-box;
  min-height: var(--hauteur-commande);
  margin-bottom: 8px;
  padding: 0 8px;
  font-size: 16px; /* 16 px : en dessous, Safari/iOS agrandit la page a la prise de focus */
  color: #e4e4e4;
  background: #2a2a2a;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
}

#champ-nom-joueur::placeholder {
  color: #8a8a8a;
}

/* En face-a-face, la boite de saisie de Blanc est lue depuis SON cote. */
.dialogue-retourne {
  transform: rotate(180deg);
}

/* Fin de partie : Options (interface/fin-de-partie.js) : un bouton par choix, son
   explication dessous. */
.options-fin .bouton-dialogue {
  width: 100%;
  min-height: var(--hauteur-commande);
  margin-top: 8px;
}

.options-fin p {
  margin: 2px 0 0;
  font-size: 12px;
}

/* Mode FACE-A-FACE (phase 20, interface/face-a-face.js) : deux joueurs de
   chaque cote d'un telephone pose a plat. Le PLATEAU ne tourne jamais ;
   Blanc joue depuis le HAUT (rendu/ejections.js), donc lit tout a l'envers
   sans ces regles. `transform-box: fill-box` + `transform-origin: center` :
   on tourne CHAQUE element SVG autour de son propre centre, sans toucher a
   sa position (x/y). */
body.face-a-face .nom-joueur-en-haut {
  transform: rotate(180deg);
  transform-box: view-box; /* avec le transform-origin pose en ligne : (0, y de la ligne), voir rendu/ligne-joueur.js */
}

/* Chaque NOM se lit depuis l'autre cote (saab, 2026-10-01 : « c'est
   l'adversaire qui lit mon nom et moi le sien ») ; « Tour n », la boite de
   saisie et le reste de la ligne restent tournes vers leur joueur. */
body.face-a-face .nom-texte {
  transform: rotate(180deg);
  transform-box: fill-box;
  transform-origin: center;
}

body.face-a-face:not(.plateau-retourne) .bille-blanc .coordonnee-bille,
body.face-a-face:not(.plateau-retourne) .coordonnee-destination-blanc,
body.face-a-face.plateau-retourne .bille-noir .coordonnee-bille,
body.face-a-face.plateau-retourne .coordonnee-destination-noir {
  transform: rotate(180deg);
  transform-box: fill-box;
  transform-origin: center;
}

/* Boutons Abandonner / Nulle du joueur du haut : chacun pivote sur lui-meme, il garde sa
   place et n'est jamais lu a la verticale (le point est pose en ligne,
   rendu/boutons-fin-piste.js). */
body.face-a-face .boutons-fin-piste-en-haut .bouton-fin-piste {
  transform: rotate(180deg);
  transform-box: view-box;
}

/* Lecture verticale (saab) : ce qui est a GAUCHE du plateau se lit de BAS en
   HAUT (-90), ce qui est a DROITE de HAUT en BAS (+90). Les compteurs
   d'ejection sont dans les coins de gauche (rendu/pistes-triangle.js). */
body.face-a-face .nombre-ejecte {
  transform: rotate(-90deg);
  transform-box: view-box; /* avec le transform-origin pose en ligne : le point d'ancrage du compte, voir rendu/pistes-triangle.js */
}

/* Icones de la colonne de gauche, lues de bas en haut ; le hamburger
   (#bouton-etendre-colonne, sans <svg>) reste droit (saab). On tourne le
   <svg> LUI-MEME, autour de son propre centre : tourner le <span> qui le
   contient (25x34, avec le dessin en haut) decalait le dessin de 4,5 px hors
   du centre de son bouton (mesure). */
/* Chaque icone est tournee UNE SEULE FOIS, celle qui porte le dessin :
   - l'<svg> imbrique dans un <span> (hexagones, Face-a-face) ;
   - l'<svg> qui est lui-meme l'icone (Sequence, Commentaires, Occurrences) ;
   - le <span> de texte (`.icone-texte` : Conseils, Menaces, Exporter, Importer).
   Tourner aussi le <span> qui contient un <svg> doublait la rotation (180 au lieu
   de 90 pour l'icone Face-a-face, saab). */
body.face-a-face #colonne-gauche .icone-bouton svg,
body.face-a-face #colonne-gauche svg.icone-bouton {
  transform: rotate(-90deg);
}

body.face-a-face #colonne-gauche .icone-texte {
  display: inline-block;
  transform: rotate(-90deg);
}

/* La jauge de "Mes parties" tourne avec le reste de son icone (saab,
   "penser a le faire tourner en FaF") : le translate(-50%,-50%) qui la
   centre doit rester AVANT la rotation (l'ordre des fonctions transform
   compte), sinon elle se decale hors du centre de l'icone. */
body.face-a-face #colonne-gauche .badge-mes-parties {
  transform: translate(-50%, -50%) rotate(-90deg);
}

@media (min-width: 700px) {
  /* La colonne d'icones doit pouvoir defiler : un telephone couche fait
     moins de 400 px de haut pour une douzaine d'icones (elle n'avait cette
     regle qu'en portrait, plus haut). Aucun rapport avec le face-a-face, mais
     c'est ce mode qui a revele l'oubli. */
  #colonne-gauche {
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* Fenetres de droite (Sequence, Commentaires, Conseils, Occurrences...) :
     la colonne est mise en page A PLAT dans une boite de la taille de
     l'ECRAN tourne (largeur = hauteur de l'ecran, hauteur = epaisseur voulue),
     puis tournee de +90 autour de son coin haut-droit et redescendue : elle
     occupe alors une bande verticale a droite, ses lignes se lisent de haut
     en bas. Plus fiable qu'`writing-mode` : la mise en page interne (flex,
     grilles, defilement) reste celle d'une colonne ordinaire. Un clic suit la
     rotation tout seul.
     L'EPAISSEUR (la largeur a l'ecran) est TOUT l'espace libre : ecran, moins
     la colonne d'icones (44), moins la barre de navigation, moins le plateau
     (100vh x son rapport largeur/hauteur, voir interface/face-a-face.js) ;
     `max(200px, ...)` pour ne jamais tomber a rien sur un ecran presque carre. */
  body.face-a-face {
    /* Meme epaisseur que les pendules (voir interface/face-a-face.js), plus les
       2 x 2 px de marge de la barre. `vh` en repli, `svh` (comme `html`/`body`
       plus haut) par-dessus des qu'il est compris : CORRIGE (saab, testeur sur
       Android/Xiaomi, Chrome et Opera) — `vh` compte la page ENTIERE, barre
       d'adresse comprise, alors que `body` lui-meme est deja borne a `100svh`
       (la hauteur VISIBLE la plus petite garantie) ; l'ecart entre les deux
       faisait deborder le bas de la fenetre retournee sur le plateau, variable
       selon que la barre d'adresse etait affichee ou non au moment du
       basculement. */
    --epaisseur-bouton-navigation-fa: calc(100vh * var(--rapport-pendule, 0.07));
    --epaisseur-bouton-navigation-fa: calc(100svh * var(--rapport-pendule, 0.07));
    /* Plus de bande pour le grand Annuler (saab, 2026-10-02 : un Annuler sur
       la ligne de chaque joueur, rendu/ligne-joueur.js) : tout aux fenetres. */
    --largeur-navigation-fa: 0px;
    --epaisseur-fenetres-fa: max(200px, calc(100vw - 44px - var(--largeur-navigation-fa) - 100vh * var(--rapport-plateau, 1.08)));
    --epaisseur-fenetres-fa: max(200px, calc(100vw - 44px - var(--largeur-navigation-fa) - 100svh * var(--rapport-plateau, 1.08)));
    padding-right: calc(var(--epaisseur-fenetres-fa) + var(--largeur-navigation-fa));
  }

  body.face-a-face #colonne-droite {
    position: fixed;
    top: 0;
    right: 0;
    width: 100vh;
    width: 100svh;
    height: var(--epaisseur-fenetres-fa);
    max-height: none;
    margin: 0;
    transform-origin: top right;
    transform: translateY(100vh) rotate(90deg);
    transform: translateY(100svh) rotate(90deg);
  }

  /* Dans la boite a plat, chaque fenetre prend toute la largeur (= la hauteur
     de l'ecran) et se partage la hauteur (= l'espace libre a l'ecran). Les
     regles ordinateur d'origine (largeur fixe, 50vh, 40vh) supposaient une
     colonne haute et etroite. La Sequence garde une hauteur de DEPART que la
     poignee peut changer (`flex: 1 1 auto` sur une hauteur nulle : elle
     partage a parts egales tant qu'on n'a pas tire). */
  body.face-a-face #arbre-panneau {
    width: 100%;
    height: 0;
    /* Pas la hauteur minimale de la Sequence hors face-a-face (plus haut) : la
       colonne tournee n'a que l'epaisseur des fenetres, et cette hauteur la
       faisait deborder sur le plateau (saab, 2026-10-01). */
    min-height: 0;
    flex: 1 1 auto;
    border-left: none;
    border-top: 1px solid #3a3a3a;
  }

  /* Meme priorite que hors face-a-face : Reflexion IA cede sa hauteur la
     premiere, mais dans l'epaisseur des fenetres tournees, pas la hauteur de
     l'ecran. 270px : le titre, le rappel, l'en-tete de Reflexion et le haut de
     la Sequence (sa ligne de depart, ses boutons, quelques coups). */
  body.face-a-face .reflexion-ia .reflexion-ia-defilement {
    max-height: clamp(2.6em, calc(var(--epaisseur-fenetres-fa) - 270px), 12em);
  }

  body.face-a-face #panneau-conseils,
  body.face-a-face #panneau-occurrences {
    width: 100%;
    min-width: 0;
    max-height: none;
    flex: 1 1 0;
    border-left: none;
  }

  /* La poignee de LARGEUR n'a plus de sens (les fenetres remplissent tout
     l'espace libre) ; celle de HAUTEUR reste, a la fin de la boite a plat donc
     sur le bord GAUCHE de la fenetre a l'ecran, plus epaisse au doigt
     (interface/sequence.js inverse le sens du glisser dans ce mode). */
  body.face-a-face #arbre-poignee-largeur {
    display: none;
  }

  /* Menu DEPLOYE (bouton hamburger) : les icones ne bougent pas, seuls les
     LIBELLES s'orientent vers le camp qui a le trait — comme d'habitude pour
     Noir (en bas), retournes de 180 degres pour le joueur du haut quand c'est lui qui
     demande (saab). `.trait-en-haut` est posee sur <body> par interface/face-a-face.js. */
  body.face-a-face #colonne-gauche.colonne-gauche-etendue .libelle-bouton {
    display: inline-block;
  }

  body.face-a-face.trait-en-haut #colonne-gauche.colonne-gauche-etendue .libelle-bouton {
    transform: rotate(180deg);
  }

  body.face-a-face #arbre-poignee-hauteur {
    height: 18px;
  }

  /* Le grand Annuler (phase 31 ; la barre de navigation avant elle,
     interface/disposition.js, replacerNavigation) : au milieu du plateau, a
     egale distance des deux joueurs, contre la colonne des fenetres, lu de
     haut en bas comme elle. `writing-mode: vertical-rl` le met a la verticale
     sans calcul. Il a sa PROPRE bande (--largeur-navigation-fa, deja
     reservee par le padding de <body>) : posee sur le dessin, elle recouvrait
     les pendules des coins de droite. Epaisseur des pendules (saab) : DEROGATION
     ASSUMEE a la regle des 44 px de CLAUDE.md, demandee par saab ("comme celle
     des pendules"), comme celle deja faite sur la hauteur de ces boutons. */
  body.face-a-face > #barre-annuler {
    position: fixed;
    top: 50%;
    right: var(--epaisseur-fenetres-fa);
    width: var(--largeur-navigation-fa);
    box-sizing: border-box;
    padding: 2px;
    transform: translateY(-50%);
    writing-mode: vertical-rl;
    flex-wrap: nowrap;
    z-index: 5;
  }

  body.face-a-face > #barre-annuler button {
    min-width: var(--epaisseur-bouton-navigation-fa);
    min-height: 40vh;
    padding: 0;
    font-size: 11px;
  }

  /* Le rappel "Touchez une pendule..." (voir .message-demarrage et
     interface/disposition.js) : DERNIERE ligne de la colonne des fenetres,
     donc tournee avec elle — a la verticale, lue de haut en bas, juste a
     droite de #barre-annuler ("au-dessus" de lui dans le sens de lecture,
     saab). En haut de l'ecran, horizontal, il chevauchait le plateau et le
     nom du joueur du haut. `order` : toujours apres les fenetres, quel que
     soit l'ordre dans lequel elles ont ete ajoutees. */
  body.face-a-face #colonne-droite > .message-demarrage {
    order: 1;
    margin: 0;
    border-radius: 0;
  }
}

/* Rubrique « Adversaire » de la boite du debut de partie (phase 29,
   interface/choix-adversaire.js) : une ligne par choix (niveau, style, camp),
   le libelle a gauche, les boutons a la suite. */
.section-adversaire {
  margin-top: 8px;
}

.ligne-choix-machine {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-height: var(--hauteur-commande);
  margin-top: 4px;
}

.ligne-choix-machine > span {
  min-width: 5.5em;
}

/* Rubrique « Joueurs » (phase 32, interface/choix-joueurs.js) : un bloc par
   camp, les reglages de la machine en retrait sous sa ligne. */
.choix-joueur + .choix-joueur {
  border-top: 1px solid #3a3a3a;
  margin-top: 6px;
}

.choix-joueur .reglages-machine {
  padding-left: 1em;
}

/* Le nom d'une machine (phase 32, rendu/ligne-joueur.js) : son evaluation en
   premiere ligne, son nom en seconde sur un fond vert (gris a l'arret), en plus
   petit pour tenir dans la meme hauteur de cadre. Le fond vert laisse passer le
   toucher vers le cadre du nom (boite du nom, Marche/Arret). */
.nom-machine-fond {
  display: none;
  pointer-events: none;
}

.nom-joueur.nom-machine .nom-machine-fond {
  display: inline;
}

.nom-machine-fond {
  fill: var(--vert-demande);
}

.nom-joueur.machine-arretee .nom-machine-fond {
  fill: #6a6a6a;
}

.nom-joueur.nom-machine .nom-texte {
  fill: #e4e4e4;
}

/* L'evaluation de chaque camp, collee a son compte d'ejections (rendu/
   evaluation.js) : cadre de la couleur du camp comme le nom, texte gris ;
   « Évaluation » en italique tant qu'un humain ne l'a pas demandee. */
.cadre-evaluation {
  cursor: pointer;
  font: bold 4.5px sans-serif;
}

.cadre-evaluation-noir .cadre-evaluation-fond {
  fill: #1f1f1f;
}

.cadre-evaluation-blanc .cadre-evaluation-fond {
  fill: #e4e4e4;
}

.cadre-evaluation-texte {
  fill: #828282;
  pointer-events: none;
}

.cadre-evaluation.evaluation-vide .cadre-evaluation-texte {
  font-weight: normal;
  font-style: italic;
}

body.face-a-face .cadre-evaluation-en-haut .cadre-evaluation-texte {
  transform: rotate(180deg);
  transform-box: view-box;
}

/* Le temps cumule (rendu/pendule.js) : plus gros que le libelle, plus petit
   que les chiffres de la pendule (10px). */
.texte-cumul-pendule {
  font: bold 6px sans-serif;
  fill: #828282;
}

/* Les tailles de Reglages, en chiffres (saab) plutot qu'en curseurs. */
.nombre-reglage {
  width: 70px;
  text-align: right;
}

.nombre-avec-boutons {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.bouton-pas {
  min-width: var(--hauteur-commande);
  min-height: var(--hauteur-commande);
  font-weight: bold;
}

/* Bouton Marche/Arret de la boite du nom : vert tant que la machine joue (un
   geste possible), gris a l'arret. */
.bouton-marche-machine {
  display: block;
  width: 100%;
  margin-top: 6px;
  background: var(--vert-demande);
  color: #ffffff;
}

/* `hidden` doit gagner sur le display des .bouton-dialogue (meme piege que
   .section-mode-pendule[hidden]) : sinon une barre verte vide restait pour un
   humain. */
/* Chargement d'une nouvelle version (interface/mise-a-jour.js) : par-dessus
   tout, en haut, le temps de recharger. */
.bandeau-mise-a-jour {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 200;
  margin: 0;
  padding: 6px 12px;
  background: var(--vert-demande);
  color: #ffffff;
  font: bold 14px sans-serif;
  text-align: center;
}

.bandeau-mise-a-jour[hidden] {
  display: none;
}

/* Aide (saab, 2026-10-01) : Fermer en vert (le geste attendu), et les noms de
   couleur dans leur couleur (interface/aide.js). */
.bouton-fermer-aide {
  background: var(--vert-demande);
  border-color: var(--vert-demande);
  color: #ffffff;
}

.mot-vert { color: #45b862; }
.mot-orange { color: #e0832a; }
.mot-jaune { color: #e6c300; }
.mot-rouge { color: #e04040; }
.mot-bleu { color: #4aa8ff; }
.mot-gris { color: #9a9a9a; }

.mot-noir,
.mot-blanc {
  padding: 0 3px;
  border-radius: 3px;
}

.mot-noir {
  background: #000000;
  color: #ffffff;
  border: 1px solid #5a5a5a;
}

.mot-blanc {
  background: #ffffff;
  color: #000000;
}

.bouton-marche-machine[hidden],
#bouton-ia-nom-joueur[hidden],
#bouton-suggestion-nom-joueur[hidden] {
  display: none;
}

/* Les poids de la machine, en colonne (boite du nom, saab 2026-10-01). */
.poids-machine-nom {
  font: 13px sans-serif;
  border-collapse: collapse;
}

.poids-machine-nom td:last-child {
  padding-left: 12px;
  text-align: right;
}

.bouton-marche-machine.machine-arretee {
  background: #3a3a3a;
}

/* Tableau de reflexion de la machine (phase 32, interface/reflexion-ia.js),
   replie par defaut sous le titre de la partie ; la ligne en cours en italique. */
/* Fond propre, jamais celui de la fenetre (reglable) : le texte reste lisible
   quelle que soit la couleur choisie (saab). */
.reflexion-ia {
  font: 11px sans-serif;
  color: #cfcfcf;
  background: #1e1e1e;
  border-top: 1px solid #3a3a3a;
  border-left: 1px solid #3a3a3a;
  padding: 0 4px;
  /* Sa largeur ne compte jamais dans celle de la colonne (saab, 2026-09-30 :
     « le plateau ne doit pas bouger pendant une partie, les boites autour
     s'adaptent ») : il prend celle que les autres panneaux lui laissent, et
     son tableau defile s'il le faut. */
  contain: inline-size;
  min-width: 176px;
}

.reflexion-commentaire {
  margin-left: 8px;
  font-weight: normal;
  color: #9a9a9a;
}

/* « en commentaire » decochee : entouree de vert, pour rappeler qu'on peut la
   cocher (saab, 2026-10-08) — le vert de ce qui attend un geste. */
.case-reflexion-commentaire:not(:checked),
.case-garder-recherches:not(:checked) {
  outline: 2px solid #45b862;
  outline-offset: 1px;
}

.reflexion-ia > summary {
  cursor: pointer;
  min-height: var(--hauteur-ligne-liste);
}

/* La recherche de KAI++ par premier coup (interface/recherche-ia.js) : sur
   ordinateur seulement, repliee par defaut ; elle defile sur elle-meme. */
.recherche-ia {
  display: none;
}

@media (min-width: 700px) {
  .recherche-ia {
    display: block;
    border-top: 1px solid #3a3a3a;
  }
}

.recherche-ia > summary {
  cursor: pointer;
  min-height: var(--hauteur-ligne-liste);
}

.note-recherche-ia {
  margin: 2px 0;
  color: #9a9a9a;
}

.recherche-ia-defilement {
  max-height: 40vh;
  overflow: auto;
}

.recherche-ia-profondeur td {
  padding-top: 4px;
  color: #e0832a;
  font-weight: bold;
  white-space: normal;
}

.recherche-ia-choisi .recherche-ia-coup {
  color: #3fcf7a;
  font-weight: bold;
}

/* Vert : un geste qui fait repartir quelque chose (comme Fermer et Jouer). */
.bouton-relancer-ia {
  margin-left: 6px;
  padding: 0 6px;
  border: 1px solid var(--vert-demande);
  border-radius: 6px;
  background: none;
  color: #3fcf7a;
  font-size: 12px;
  cursor: pointer;
}

.reflexion-ia-defilement {
  max-height: 12em;
  overflow: auto;
}

.reflexion-ia table {
  border-collapse: collapse;
  width: 100%;
}

.reflexion-ia th,
.reflexion-ia td {
  padding: 1px 4px;
  text-align: left;
  white-space: nowrap;
}

.reflexion-ia th {
  color: #9a9a9a;
  font-weight: normal;
}

.reflexion-ia .reflexion-en-cours {
  font-style: italic;
  color: #7fd48f;
}

/* La sequence prevue sur 2 lignes (interface/reflexion-ia.js) ; un clic la
   montre sur un petit plateau (interface/sequence-prevue.js). */
.reflexion-ia td {
  vertical-align: top;
}

.reflexion-ia .sequence-prevue-cliquable {
  cursor: pointer;
  text-decoration: underline dotted #6a6a6a;
}

.noir-commence {
  color: #e6c300;
}

#apercu-sequence-prevue {
  display: block;
  width: var(--taille-apercu);
  height: var(--taille-apercu);
  margin: 0 auto 6px;
  background: #2b2b2b;
  border-radius: 6px;
  cursor: pointer;
}

/* Tour par tour, deux tours par ligne : le numero, Noir, Blanc (saab, 2026-10-22 : « mettre en
   colonnes paires », Noir et Blanc toujours dans leur colonne ; interface/sequence-prevue.js). */
.coups-sequence-prevue {
  display: grid;
  grid-template-columns: repeat(2, auto 1fr 1fr);
  align-items: center;
  gap: 2px 4px;
  max-width: 280px;
  margin: 0 auto 6px;
  /* Une longue partie (LabAl) : les coups defilent, les boutons restent visibles (saab, 2026-10-18). */
  max-height: 7.5em;
  overflow-y: auto;
  position: relative; /* les coups s'y reperent (interface/sequence-prevue.js) */
}

/* Un bouton sans effet (rien a valider, deja au bout de la sequence) le dit. */
#bouton-valider-profil-ia:disabled,
#bouton-abandonner-profil-ia:disabled,
.dialogue-sequence-prevue .bouton-dialogue:disabled {
  opacity: 0.4;
  cursor: default;
}

.coup-sequence-prevue {
  padding: 0 4px;
  border: none;
  background: none;
  color: #cfcfcf;
  font: 13px monospace;
  cursor: pointer;
}

.tour-sequence-prevue { color: #8a8a8a; font: 12px monospace; text-align: right; }
.joueurs-sequence-prevue, .reflexion-sequence-prevue { margin: 0 0 4px; text-align: center; }
.reflexion-sequence-prevue { color: #e0832a; }

.coup-sequence-prevue-actuel {
  background: var(--vert-demande);
  color: #ffffff;
  border-radius: 3px;
}

/* Historique IA (interface/historique-ia.js) : les versions du profil, comme
   les branches de la Sequence. */
.boite-historique-ia > summary {
  cursor: pointer;
  min-height: var(--hauteur-ligne-liste);
}

.historique-profil-ia {
  display: flex;
  flex-direction: column;
  max-height: 10em;
  overflow-y: auto;
}

.ligne-historique-ia {
  min-height: var(--hauteur-ligne-liste);
  border: none;
  background: none;
  color: #cfcfcf;
  font: 12px sans-serif;
  text-align: left;
  cursor: pointer;
}

.ligne-historique-ia.hors-du-chemin {
  color: #8a8a8a;
}

/* L'essai des poids (interface/essai-ia.js) : des tableaux de chiffres serres,
   qui defilent dans leur boite plutot que d'elargir Reglages. */
.defilement-essai-ia {
  overflow: auto;
  max-width: 100%;
}

.defilement-coups-essai-ia {
  max-height: 16em;
}

.tableau-essai-ia {
  border-collapse: collapse;
  font: 11px sans-serif;
}

.tableau-essai-ia th,
.tableau-essai-ia td {
  padding: 1px 4px;
  text-align: right;
  white-space: nowrap;
}

.tableau-essai-ia th {
  position: sticky;
  top: 0;
  background: #262626;
  color: #9a9a9a;
  font-weight: normal;
}

.tableau-essai-ia td:first-child,
.tableau-essai-ia th:first-child {
  text-align: left;
}

.essai-position-actuelle td {
  color: #9a9a9a;
  font-style: italic;
}

/* Reglages ouvert SANS bloquer le plateau (case « Essai sur position ») : hors
   de la couche du dessus des boites modales, il doit quand meme passer
   devant tout le reste de la page. */
#dialogue-reglages[open]:not(:modal) {
  position: fixed;
  z-index: 100;
}

/* Le coup touche (interface/essai-ia.js), a comparer au choisi. */
/* Commentaire portant une suggestion de la machine (rendu/commentaires-html.js). */
.texte-commentaire.texte-commentaire-suggestion {
  color: #e04040;
}

.essai-coup-touche td {
  background: #cc6a00;
  color: #ffffff;
}

/* Le coup du niveau 3, encadre. */
.essai-coup-niveau-3 td {
  border-top: 1px solid #e6c300;
  border-bottom: 1px solid #e6c300;
}

/* Ce que la sequence du niveau 3 change, au bout (interface/essai-ia.js). */
.essai-fin-de-sequence td {
  color: #e6c300;
  font-style: italic;
}

.tableau-essai-ia tr[data-coup] {
  cursor: pointer;
}

.niveau3-essai-ia {
  color: #e6c300;
}

.essai-coup-choisi td {
  background: var(--vert-demande);
  color: #ffffff;
}

.boite-essai-ia > summary {
  cursor: pointer;
  min-height: var(--hauteur-ligne-liste);
}

/* Les doubles des boutons de navigation (interface/essai-ia.js). */
.navigation-essai-ia {
  display: flex;
  gap: 6px;
  margin: 4px 0;
}

.navigation-essai-ia button {
  min-width: 44px;
  min-height: var(--hauteur-commande);
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  cursor: pointer;
}

.navigation-essai-ia button:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Ce que la machine aurait joue (interface/reflexion-ia.js) : a toucher. */
.reflexion-ia .reflexion-hypothese {
  color: #e6c300;
}

.reflexion-ia .coup-hypothese {
  cursor: pointer;
  text-decoration: underline;
}

.machine-nom-joueur {
  margin-top: 6px;
}

.ligne-historique-ia.version-courante {
  background: var(--vert-demande);
  color: #ffffff;
}

/* ---------------------------------------------------------------------
   Saab, 2026-10-02 : plus de grand Annuler sous le plateau — chaque joueur a
   le sien sur sa ligne (rendu/ligne-joueur.js), du cote de « Gagné Options ».
   Le bouton d'origine reste dans la page, cache : c'est lui qu'ils touchent
   (interface/saisie.js). Ce que voit Noir (J1) s'ecrit en noir : son Annuler,
   son « Gagné/Perdu Options », le nom de sa machine, le drapeau et le = de
   ses boutons Abandonner / Nulle.
   --------------------------------------------------------------------- */
#barre-annuler,
body.face-a-face > #barre-annuler {
  display: none;
}

.bouton-annuler-joueur {
  cursor: pointer;
}

.bouton-annuler-joueur-fond {
  fill: var(--vert-demande);
}

.bouton-annuler-joueur-texte {
  fill: #ffffff;
  font: bold 5.5px sans-serif; /* plus gros que les autres boutons de la ligne (saab) */
  pointer-events: none;
}

.bouton-annuler-joueur.bouton-annuler-inactif {
  opacity: 0.35;
  cursor: default;
}

/* « Tour n » en blanc pour Blanc (saab, 2026-10-02), comme ses autres textes. */
.nom-joueur-blanc .nom-tour {
  fill: #ffffff;
}

.nom-joueur-noir .bouton-annuler-joueur-texte,
.nom-joueur-noir.resultat-fin .nom-tour,
.nom-joueur-noir.attend-choix-fin .nom-tour,
.nom-joueur-noir.demande-en-cours .nom-tour,
.nom-joueur-noir.nom-machine .nom-texte,
.bouton-fin-piste[data-camp='noir'] .bouton-fin-piste-dessin {
  fill: #0a0a0a;
}

/* ---------------------------------------------------------------------
   Ordinateur, hors face-a-face (saab, 2026-10-02 : « le plateau n'est pas
   assez a gauche, et l'espace a droite et a gauche est trop important, ce qui
   fait que la fenetre de droite est trop petite. Toutes les fenetres doivent
   etre collees au plus proche de la fenetre du plateau ») :
     - la colonne du plateau a exactement la largeur du plateau (plus de vide
       de part et d'autre, plus de largeur maximale) ;
     - la colonne de droite prend TOUT le reste de la largeur, et toute la
       hauteur ; ses fenetres en prennent la largeur ;
     - la Sequence remplit la hauteur restante (« comme Reflexion »), qui
       recoit la sienne de interface/hauteurs-colonne.js.
   Les poignees de la Sequence restent (saab : « pratiques pour etudier les
   tableaux, un petit plateau n'est pas genant ») : la largeur choisie est
   celle de la colonne, au besoin aux depens du plateau (--largeur-sequence,
   interface/sequence.js) ; une hauteur choisie fige la Sequence
   (.hauteur-choisie), Reflexion IA prend le reste.
   --------------------------------------------------------------------- */
@media (min-width: 700px) {
  body:not(.face-a-face) #colonne-principale {
    flex: 0 1 auto;
    max-width: none;
  }

  body:not(.face-a-face) #colonne-droite {
    flex: 1 0 var(--largeur-sequence, 0px);
    min-width: 176px;
    align-self: stretch;
    height: 100vh;
    height: 100dvh;
    margin-left: 0;
  }

  body:not(.face-a-face) #colonne-droite > #entete-partie,
  body:not(.face-a-face) #colonne-droite > .reflexion-ia,
  body:not(.face-a-face) #colonne-droite > #arbre-panneau,
  body:not(.face-a-face) #colonne-droite > #panneau-conseils,
  body:not(.face-a-face) #colonne-droite > #panneau-occurrences {
    width: auto;
    max-width: none;
  }

  body:not(.face-a-face) #colonne-droite > #arbre-panneau {
    flex: 1 1 auto;
    height: auto;
  }

  body:not(.face-a-face) #colonne-droite > #arbre-panneau.hauteur-choisie {
    flex: 0 0 auto;
  }
}

/* Un coup de Reflexion IA mene a sa position (interface/reflexion-ia.js). */
.coup-reflexion-navigable {
  cursor: pointer;
  text-decoration: underline dotted;
}

/* La poignee entre Reflexion IA et la Recherche par 1er coup
   (interface/hauteurs-colonne.js), comme celle de la Sequence. */
.poignee-reflexion-recherche {
  height: 8px;
  cursor: ns-resize;
  background: #3a3a3a;
  touch-action: none;
}

.poignee-reflexion-recherche[hidden] {
  display: none;
}

/* Les couleurs d'un profil IA remontent de la valeur jusqu'a son fichier
   (saab, 2026-10-02 ; interface/couleurs-ia.js) : le chiffre lui-meme et la
   liste fermee prennent la couleur de leur ligne ; chaque option de profil a
   la sienne, les autres restent claires. */
:is(.reglage-modifie, .reglage-valide-dernier, .reglage-valide-ancien) :is(input, select) {
  color: inherit;
}

select option:not(.reglage-modifie, .reglage-valide-dernier, .reglage-valide-ancien) {
  color: #e4e4e4;
}

.rubrique-reglages.rubrique-valide-dernier:not(.rubrique-modifiee) > summary {
  color: #45b862;
}

.rubrique-reglages.rubrique-valide-ancien:not(.rubrique-modifiee) > summary {
  color: #d9b62b;
}

/* Sur le plateau, sur le fond vert d'une machine : les memes couleurs, plus
   claires pour s'en detacher (rendu/ligne-joueur.js, colorerStyleDuNom). */
.nom-joueur .nom-texte .nom-style-modifie {
  fill: #ffa040;
}

.nom-joueur .nom-texte .nom-style-dernier {
  fill: #8dffa8;
}

.nom-joueur .nom-texte .nom-style-ancien {
  fill: #ffe14d;
}

/* Une valeur par defaut (interface/nom-machine-couleurs.js) : le marron, eclairci. */
.nom-joueur .nom-texte .nom-style-defaut {
  fill: #f0c48e;
}

/* Les noms des colonnes restent en haut quand le tableau defile (saab,
   2026-10-02 : « figer les noms des colonnes Reflexion / 1er coup ») : le fond
   du tableau sous eux, pour que les lignes passent dessous sans se melanger. */
.reflexion-ia thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #1e1e1e;
}

/* La barre de navigation de Reflexion IA (saab, 2026-10-02 : « a gauche,
   donc pas centree ») : comme celle de l'Essai. */
.navigation-reflexion-ia {
  display: flex;
  justify-content: flex-start;
  gap: 6px;
  margin: 4px 0;
  /* Sous le tableau 1er coup, et toujours dans la fenetre (saab, 2026-10-04) :
     collee en bas si le reste deborde. */
  position: sticky;
  bottom: 0;
  z-index: 2;
  padding: 2px 0;
  background: #1e1e1e;
}

.navigation-reflexion-ia button {
  min-width: 44px;
  min-height: var(--hauteur-commande);
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  cursor: pointer;
}

.navigation-reflexion-ia button:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Le coup regarde sur le plateau, encadre dans les deux tableaux (saab,
   2026-10-02) : Reflexion IA (le dernier coup du chemin) et Recherche par 1er
   coup (le coup joue depuis la position cherchee). */
.reflexion-ia tr.coup-actif td {
  border-top: 2px solid #e0832a;
  border-bottom: 2px solid #e0832a;
}

.reflexion-ia tr.coup-actif td:first-child {
  border-left: 2px solid #e0832a;
}

.reflexion-ia tr.coup-actif td:last-child {
  border-right: 2px solid #e0832a;
}

/* La poignee de largeur de Reflexion IA (interface/reflexion-ia.js), comme
   celle de la Sequence (#arbre-poignee-largeur) : a cheval sur le bord gauche,
   ordinateur seulement, jamais en face-a-face (les fenetres y remplissent
   l'espace). */
.poignee-largeur-reflexion {
  display: none;
}

@media (min-width: 700px) {
  #reflexion-ia {
    position: relative;
  }

  body:not(.face-a-face) .poignee-largeur-reflexion {
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: -4px;
    width: 8px;
    cursor: ew-resize;
    touch-action: none;
    z-index: 2;
  }

  body:not(.face-a-face) .poignee-largeur-reflexion:hover,
  body:not(.face-a-face) .poignee-largeur-reflexion:active {
    background: #3a3a3a;
  }
}

/* Sur telephone en portrait, la barre sous Reflexion IA au centre (saab,
   2026-10-03) ; a gauche sur ordinateur. */
@media (max-width: 699px) {
  .navigation-reflexion-ia {
    justify-content: center;
  }
}

/* Ce que cherche le profil IA (saab, 2026-10-03 ; interface/reglages-ia.js) :
   sur toute la largeur, sous son nom. */
.ligne-description-profil-ia {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 2px 0 4px;
}

.ligne-description-profil-ia textarea {
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
  font: inherit;
}

.description-choix-profil:empty {
  display: none;
}

/* Exporter, dans le titre du tableau Recherche par 1er coup. */
.bouton-exporter-recherches {
  margin-left: 6px;
  padding: 0 6px;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  background: none;
  color: #e4e4e4;
  font-size: 12px;
  cursor: pointer;
}

/* Touche : orange un instant (saab, 2026-10-06 ; interface/recherche-ia.js). */
.bouton-exporter-recherches.bouton-touche {
  background: #cc6a00;
  color: #0a0a0a;
  border-color: #cc6a00;
}

/* Le tableau comparatif des profils IA (interface/comparaison-ia.js) : il
   defile sur lui-meme, dans les deux sens. */
.defilement-comparaison-ia {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}

.tableau-comparaison-ia {
  border-collapse: collapse;
}

.tableau-comparaison-ia th,
.tableau-comparaison-ia td {
  padding: 2px 6px;
  text-align: left;
  white-space: nowrap;
  border-bottom: 1px solid #3a3a3a;
}

.tableau-comparaison-ia th {
  position: sticky;
  top: 0;
  background: #1e1e1e;
  color: #9a9a9a;
  font-weight: normal;
}

/* La coche et le Profil IA figes a gauche (saab, 2026-10-16) ; leur fond cache ce qui
   defile dessous (left : interface/comparaison-ia.js). */
.tableau-comparaison-ia .comparaison-coche,
.tableau-comparaison-ia .comparaison-profil {
  position: sticky;
  left: 0;
  z-index: 1;
  background: #1e1e1e;
}

.tableau-comparaison-ia th.comparaison-coche,
.tableau-comparaison-ia th.comparaison-profil {
  z-index: 3;
}

.tableau-comparaison-ia th {
  z-index: 2;
}

.tableau-comparaison-ia tr.comparaison-groupes th {
  font-weight: bold;
  border-bottom: none;
}

.tableau-comparaison-ia .comparaison-description {
  min-width: 14em;
  max-width: 22em;
  white-space: normal;
}

.tableau-comparaison-ia tr {
  cursor: pointer;
}

/* Les tableaux comparatifs (profils IA, reglages du plateau : saab, 2026-10-03,
   « pas scrollable ... illisible ») : la boite prend presque tout l'ecran, et
   le tableau, lui, retrecit et defile dans les deux sens — la regle generale
   des grandes boites (`> * { flex-shrink: 0 }`) l'en empechait. */
#dialogue-comparaison-ia,
#dialogue-comparaison-reglages {
  width: 96vw;
  max-width: 96vw;
}

.dialogue-grand[open] > .defilement-comparaison-ia {
  flex-shrink: 1;
}

/* Le tableau des profils de reglages (interface/comparaison-reglages.js) : le
   titre de chaque rubrique, une pastille par couleur, le nom d'un profil a
   toucher. */
.tableau-comparaison-ia .comparaison-rubrique td {
  padding-top: 6px;
  color: #e0832a;
  font-weight: bold;
}

.pastille-comparaison {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: middle;
  border: 1px solid #5a5a5a;
  border-radius: 3px;
}

.tableau-comparaison-ia .comparaison-nom-profil {
  cursor: pointer;
  text-decoration: underline dotted;
}

.tableau-comparaison-ia th.reglage-modifie {
  color: #cc6a00;
}

/* Profils IA compares (saab, 2026-10-03) : la colonne Profil IA juste a sa
   taille ; « Ce qu'il cherche » plie par defaut, une seule ligne coupee par
   profil (le texte entier au survol), pour comparer d'un coup d'oeil. */
.tableau-comparaison-ia {
  width: auto;
}

.tableau-comparaison-ia .comparaison-profil {
  width: 1%;
}

.tableau-comparaison-ia.descriptions-pliees .comparaison-description {
  min-width: 0;
  max-width: 16em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tableau-comparaison-ia .comparaison-titre-pliable {
  cursor: pointer;
}

/* Profils IA compares, version 3 (saab, 2026-10-03) : les cases d4 a a2 se
   replient en touchant le titre Centre (a1 reste) ; chaque colonne s'elargit ou
   se retrecit en tirant le bord droit de son titre — les largeurs sont alors
   fixes, le texte trop long coupe. */
.tableau-comparaison-ia.cases-pliees .colonne-case-repliable {
  display: none;
}

.tableau-comparaison-ia .poignee-colonne {
  position: absolute;
  top: 0;
  right: -4px;
  width: 8px;
  height: 100%;
  cursor: col-resize;
  touch-action: none;
  z-index: 1;
}

.tableau-comparaison-ia .poignee-colonne:hover {
  background: rgba(224, 131, 42, 0.5);
}

.tableau-comparaison-ia.largeurs-fixees {
  table-layout: fixed;
}

.tableau-comparaison-ia.largeurs-fixees th,
.tableau-comparaison-ia.largeurs-fixees td {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Les infos d'une case (saab, 2026-10-04, interface/infos-case.js) : une
   infobulle qui suit la souris, et le petit tableau d'une bille au clic droit. */
.infobulle-case,
.panneau-bille {
  position: fixed;
  z-index: 1000;
  background: #1e1e1e;
  color: #e6e6e6;
  border: 1px solid #5a5a5a;
  border-radius: 4px;
  font-size: 12px;
}

.infobulle-case {
  padding: 1px 6px;
  pointer-events: none;
  color: #e06321;
  white-space: nowrap;
}

/* Toujours entier dans la fenetre (saab : « la barre de scroll est hors
   fenetre ») : le titre reste, le corps defile sur lui-meme. */
.panneau-bille {
  display: flex;
  flex-direction: column;
  padding: 4px 6px;
  max-width: calc(100vw - 12px);
  max-height: calc(100vh - 12px);
  box-sizing: border-box;
  /* Une poignee dans le coin en bas a droite (saab, 2026-10-05 : « ajouter des
     poignees sur les panneaux, qu'on puisse les modifier a volonte ») ; le
     corps defile dedans, jamais hors de la fenetre. */
  resize: both;
  overflow: hidden;
  min-width: 160px;
  min-height: 80px;
}

.panneau-bille[hidden] {
  display: none;
}

.corps-panneau-bille {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}

.panneau-bille p {
  margin: 2px 0;
  color: #9a9a9a;
}

.entete-panneau-bille {
  display: flex;
  align-items: center;
  gap: 4px;
  font-weight: bold;
  cursor: move;
  touch-action: none;
}

.entete-panneau-bille span {
  flex: 1 1 auto;
}

.entete-panneau-bille button {
  min-height: 0;
  padding: 0 6px;
  background: none;
  border: 1px solid #5a5a5a;
  border-radius: 3px;
  color: inherit;
  cursor: pointer;
}

.panneau-bille table {
  border-collapse: collapse;
}

.panneau-bille th,
.panneau-bille td {
  padding: 1px 6px 1px 0;
  text-align: left;
  font-weight: normal;
  white-space: nowrap;
}

.panneau-bille th {
  color: #9a9a9a;
}

.choix-infos-case {
  display: flex;
  flex-direction: column;
  margin-top: 4px;
  border-top: 1px solid #3a3a3a;
}

.choix-infos-case p {
  margin-top: 4px;
  color: #e0832a;
}

.panneau-bille .ligne-total-bille th,
.panneau-bille .ligne-total-bille td {
  color: #e6e6e6;
  font-weight: bold;
  border-top: 1px solid #5a5a5a;
}

.entete-panneau-bille button:disabled {
  opacity: 0.4;
  cursor: default;
}

/* L'aire dessinee sur le plateau (interface/aire-plateau.js) : blanche en
   cours, orange une fois fermee ; pendant le dessin, le curseur le dit. */
.trace-aire {
  fill: none;
  stroke: #ffffff;
  stroke-width: 3;
  stroke-linejoin: round;
  pointer-events: none;
}

.trace-aire-fermee {
  stroke: #e0832a;
  fill: rgba(224, 131, 42, 0.12);
}

svg.dessin-aire {
  cursor: crosshair;
  touch-action: none;
}

/* Le bouton Aire (saab, 2026-10-04) : vert au repos, orange pendant le dessin. */
.entete-panneau-bille .bouton-aire {
  background: #2e7d32;
  border-color: #2e7d32;
  color: #ffffff;
}

.entete-panneau-bille .bouton-aire.bouton-aire-en-cours {
  background: #e0832a;
  border-color: #e0832a;
}

/* Les boutons du bas des boites du nom et du debut de partie (saab, 2026-10-04 :
   « hors fenetre ... il faudrait les avoir toujours en vue ») : colles en bas
   pendant que le reste defile. */
.dialogue .pied-dialogue {
  position: sticky;
  bottom: -8px; /* le padding de .dialogue */
  z-index: 2;
  margin: 0 -8px -8px;
  padding: 4px 8px 8px;
  background: #1a1a1a;
  border-top: 1px solid #3a3a3a;
}

/* Le choix du style devant la liste des profils (interface/choix-joueurs.js). */
.choix-style-ia {
  flex: 0 0 auto;
  width: auto;
}

/* Le tableau des termes du panneau (saab, 2026-10-05) : le profil de la machine
   en orange, le reglage de chaque terme en gris (« +5000/+1000 »), le nom du
   profil a la largeur de sa colonne (il passe a la ligne). */
.panneau-bille th.profil-panneau {
  white-space: normal;
  text-align: center;
  color: #e6e6e6;
}

.panneau-bille th.profil-actif,
.panneau-bille td.valeur-profil-actif {
  color: #e0832a;
}

.panneau-bille .reglage-du-terme {
  color: #7a7a7a;
}

/* Sur ordinateur, la barre de navigation de Reflexion IA tout en bas de la
   colonne des tableaux, fixe (saab, 2026-10-05 ; interface/disposition.js) ;
   cachee avec Reflexion IA. */
#colonne-droite > .navigation-reflexion-ia {
  margin-top: auto;
  position: static;
}

#reflexion-ia[hidden] ~ .navigation-reflexion-ia,
#reflexion-ia:not([open]) ~ .navigation-reflexion-ia {
  display: none;
}

/* Sur ordinateur hors face-a-face, une seule barre (saab, 2026-10-06 : « ca fait
   doublon ») : celle du plateau, dans la colonne des tableaux, toujours visible
   — tout en bas par defaut, ou entre deux tableaux (boutons ▲ ▼ :
   interface/navigation-colonne.js). Celle de Reflexion IA n'y sert plus. */
@media (min-width: 700px) {
  body:not(.face-a-face) .navigation-reflexion-ia {
    display: none;
  }
}

.bouton-place-navigation {
  display: none;
}

#colonne-droite > #navigation {
  justify-content: flex-start;
  gap: 4px;
  margin: 4px 0;
  padding: 2px 0;
  background: #1e1e1e;
}

#colonne-droite > #navigation:last-child {
  margin-top: auto;
}

#colonne-droite > #navigation button {
  min-width: 36px;
  min-height: var(--hauteur-commande);
  font-size: inherit;
  cursor: pointer;
}

#colonne-droite > #navigation button:disabled {
  opacity: 0.4;
  cursor: default;
}

#colonne-droite > #navigation .bouton-place-navigation {
  display: inline-block;
  min-width: 26px;
}

#colonne-droite > #navigation #nav-monter {
  margin-left: auto;
}

/* − et + du temps de reflexion d'une machine (saab, 2026-10-07 ;
   interface/choix-joueurs.js) : sur telephone aussi. */
.bouton-palier-reflexion {
  min-width: var(--hauteur-commande);
  min-height: var(--hauteur-commande);
  margin: 0 2px;
  padding: 0 6px;
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #5a5a5a;
  border-radius: 6px;
  cursor: pointer;
}

/* KAI choisi avec un profil recent (interface/choix-joueurs.js). */
/* Le conseil de temps d'un niveau (interface/conseil-temps-ia.js) ; en orange
   quand la reflexion max est trop courte pour le finir. */
.conseil-temps-niveau {
  margin: 2px 0 4px;
  font-size: 12px;
  color: #9a9a9a;
}

.conseil-temps-niveau.conseil-trop-court {
  color: #e0832a;
}

/* La case devant chaque poids d'un profil IA (saab, 2026-10-07 ;
   interface/reglages-ia.js) : decochee, le poids ne compte plus. */
.coche-poids {
  margin: 0 4px 0 0;
  vertical-align: middle;
}

/* Les ajouts de l'IA (sv, ec, ea, da) : seulement dans une version de travail
   (index.html, classe version-de-travail) — pas encore pour les testeurs. */
body:not(.version-de-travail) .poids-ajout,
body:not(.version-de-travail) .aide-ajouts {
  display: none !important;
}

/* Profils IA compares : les profils coches, remontes en tete (interface/comparaison-ia.js). */
.tableau-comparaison-ia tr.profil-coche-comparaison td {
  background: #26302a;
}

/* Le banc d'essais (interface/banc-essais.js) : ordinateur seulement (saab,
   2026-10-08 : « sur tel c'est trop lourd »). En haut les choix sur deux
   colonnes, en dessous les resultats qui defilent. */
@media (max-width: 699px) {
  .banc-ordinateur {
    display: none !important;
  }
}

/* Sur telephone seulement : l'Aide dit que l'ordinateur a le banc en plus. */
@media (min-width: 700px) {
  .banc-telephone {
    display: none !important;
  }
}

#dialogue-banc-essais {
  width: min(1100px, 96vw);
  max-width: 96vw;
  height: 92vh;
}

/* Les choix prennent toute la hauteur tant qu'il n'y a pas de resultats (saab :
   « elles sont coupees au milieu de la fenetre ») ; ensuite un tiers, les
   resultats le reste. Chaque colonne defile seule. */
.dialogue-grand[open] > .banc-reglages {
  display: flex;
  gap: 16px;
  flex: 1 1 0;
  min-height: 0;
}

.banc-colonne {
  flex: 1 1 0;
  min-width: 0;
  overflow: auto;
}

.banc-colonne input[type='text'] {
  width: 12em;
}

/* Assez large pour « 20 » ou « 30 » et les fleches du champ (trop etroit, il
   n'en montrait que le premier chiffre). */
.banc-colonne input[type='number'] {
  width: 5em;
}

/* Un profil par ligne : son nom, puis ses petits champs Niv. et Refl. (vides :
   ceux par defaut, en gris), alignes en colonnes sous leur titre. */
.banc-ligne-profil {
  display: flex;
  align-items: center;
  gap: 6px;
}

.banc-ligne-profil > label {
  flex: 1 1 auto;
  min-width: 0;
}

/* Un reglage : son champ, puis deux petites fleches empilees. */
.banc-reglage-recherche,
.banc-recherche-reference {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  gap: 2px;
}

.banc-recherche-reference {
  gap: 6px;
}

.banc-fleches {
  display: inline-flex;
  flex-direction: column;
}

#dialogue-banc-essais button.banc-fleche {
  width: 16px;
  min-width: 0;
  height: calc(var(--hauteur-commande) / 2);
  min-height: 0;
  padding: 0;
  font-size: 8px;
  line-height: 1;
  background: #3a3a3a;
  color: #e4e4e4;
  border: 1px solid #555555;
}

.banc-colonne input.banc-champ-recherche {
  width: 3em;
  text-align: right;
}

.banc-entete-profils {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  padding-right: 2px;
  margin: 0;
}

.banc-entete-profils span {
  /* la largeur d'un reglage : son champ et ses deux boutons */
  width: calc(3em + 18px);
  text-align: center;
}

/* Parties ou puzzles (interface/banc-essais-choix.js) : chaque mode ne montre que
   ses reglages ; les boutons de la recolte, seulement quand il y en a une. */
#dialogue-banc-essais:not(.banc-en-puzzles) .banc-mode-puzzles,
#dialogue-banc-essais.banc-en-puzzles .banc-mode-parties,
#dialogue-banc-essais:not(.banc-a-recolte) .banc-avec-recolte {
  display: none;
}

/* Ceintures (saab, 2026-10-22 : « si je teste les ceintures, on dirait que Ce qu'on essaie se
   lance aussi ») : seulement les reglages des ceintures des IA, ni parties, ni puzzles, ni ce
   qu'on fait varier, ni la reference. */
#dialogue-banc-essais:not(.banc-en-ceintures) .banc-mode-ceintures,
#dialogue-banc-essais.banc-en-ceintures .banc-mode-parties,
#dialogue-banc-essais.banc-en-ceintures .banc-mode-puzzles,
#dialogue-banc-essais.banc-en-ceintures .banc-hors-ceintures {
  display: none;
}

.banc-choix-mode {
  display: flex;
  gap: 16px;
}

.banc-tableau .banc-rate {
  color: #e05a5a;
}

.banc-tableau .banc-moins-sur {
  color: #d9b62b;
}

/* Le total des parties, au-dessus du compteur : on sait avant de lancer. */
.banc-total {
  margin: 4px 0 0;
  color: #cc6a00;
}

.banc-titre {
  margin: 6px 0 2px;
  font-weight: bold;
}

/* Les parties en cours, une ligne chacune (interface/banc-essais-suivi.js). */
.banc-en-cours {
  font-size: 12px;
  max-height: 20vh;
  overflow: auto;
}

.banc-en-cours > div:first-child {
  color: #cc6a00;
}

.dialogue-grand[open] > .banc-resultats {
  flex: 2 1 0;
  min-height: 0;
  overflow: auto;
}

.dialogue-grand[open] > .banc-resultats:empty,
#dialogue-banc-essais.banc-resultats-caches > .banc-resultats {
  display: none;
}

.banc-tableau {
  border-collapse: collapse;
  font-size: 12px;
}

.banc-tableau th,
.banc-tableau td {
  padding: 1px 6px;
  border-bottom: 1px solid #3a3a3a;
  text-align: left;
  vertical-align: top;
}

.banc-tableau th {
  color: #9a9a9a;
  font-weight: normal;
  vertical-align: bottom; /* les titres sur plusieurs lignes, alignes sur leurs valeurs */
}

/* Le titre de la reference en jaune, la couleur des versions plus anciennes
   (.reglage-valide-ancien) : la base a laquelle on compare (saab). */
.banc-tableau th.banc-reference {
  color: #d9b62b;
  font-weight: bold;
}

/* Les boutons du banc (interface/banc-essais.js) : vert quand il attend qu'on le
   touche (Lancer), orange quand il est actif — les couleurs de tout KAAH. */
#dialogue-banc-essais .bouton-attend {
  background: var(--vert-demande);
  color: #ffffff;
  border-color: var(--vert-demande);
}

#dialogue-banc-essais .bouton-actif {
  background: #cc6a00;
  color: #0a0a0a;
  border-color: #cc6a00;
}

.banc-change,
.banc-livre-actif,
.banc-moins td:first-child {
  color: #e0832a;
}

/* Un coup qui redonne une position deja vue, son Occ en exposant (interface/banc-essais-page.js). */
.banc-occ {
  color: #5aa0ff;
}

.banc-occ sup {
  font-size: 9px;
}

.banc-change {
  font-weight: bold;
}

.banc-essai,
.banc-livre,
.banc-mieux td:first-child {
  color: #3fcf7a;
}

/* Le resultat d'une partie du banc, vu de l'essai (interface/banc-essais-page.js, classeDuResultatBanc) :
   gagnee en vert (.banc-essai), perdue en rouge, nulle du bleu des nulles de KAAH. */
.banc-perdue {
  color: #e05a5a;
}

.banc-nulle {
  color: #4aa8ff;
}

.banc-coups {
  font-family: monospace;
  max-width: 700px;
}

.banc-tour {
  color: #7a7a7a;
  margin-left: 4px;
}

/* La machine interdite dans un puzzle, version publiee (interface/noms-joueurs.js) :
   grise, mais on peut toucher pour savoir pourquoi. */
.bouton-interdit {
  opacity: 0.4;
}

/* Historique des joueurs (phase 35, interface/historique-joueurs.js). */
.contenu-historique { max-height: 60vh; overflow: auto; }
.contenu-historique h3 { margin: 6px 0; }
.contenu-historique h4 { margin: 10px 0 4px; color: #d9b62b; }
.tableau-historique { border-collapse: collapse; width: 100%; font-size: 13px; }
.tableau-historique th, .tableau-historique td { padding: 3px 6px; border-bottom: 1px solid #3a3a3a; text-align: right; }
.tableau-historique th:first-child, .tableau-historique td:first-child { text-align: left; }
.tableau-historique th { color: #9a9a9a; font-weight: normal; }
.historique-records td { text-align: left; }
.historique-joueur { cursor: pointer; height: var(--hauteur-ligne-liste); }
.historique-joueur:hover { background: rgba(255, 255, 255, 0.06); }
.historique-g { color: #3fcf7a; }
.historique-p { color: #e05a5a; }

/* Les noms deja donnes, sous le champ de la boite du nom (interface/noms-connus.js). */
.noms-connus { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0; }

/* L'Entrainement (phase 36, interface/entrainement.js). */
.ligne-onglets-entrainement { display: flex; gap: 6px; margin: 6px 0; }
.ceinture { display: inline-block; width: 26px; height: 10px; border-radius: 3px; border: 1px solid #777; vertical-align: middle; }
.tableau-ceintures td { text-align: left; }
.ceinture-visee td { background: rgba(217, 182, 43, 0.12); }
.boutons-jeu { white-space: nowrap; }
.boutons-jeu .bouton-dialogue { margin-left: 4px; }
.jeu-fait { opacity: 0.6; }

/* L'Entrainement : le plateau seul (saab, 2026-10-08 : « bloquer aussi les btn
   Conseils, Menaces, Séquences, Commentaire, en fait il n'a que la fenêtre
   plateau »). Le bandeau du puzzle reste : il dit ou on en est. */
body.bloque-conseils #bouton-conseils,
body.bloque-menaces #bouton-menaces,
body.bloque-sequence #bouton-sequence,
body.bloque-commentaires #bouton-commentaires,
body.bloque-occurrences #bouton-occurrences,
body.bloque-reglages #bouton-reglages,
body.mode-entrainement #bouton-correspondance {
  pointer-events: none;
  opacity: 0.3;
}
body.bloque-conseils :is(#panneau-conseils, #fleches-conseils),
body.bloque-menaces #fleches-menaces,
body.bloque-sequence #arbre-panneau,
body.bloque-occurrences #panneau-occurrences,
body.cacher-evaluation :is(#reflexion-ia, .cadre-evaluation) {
  display: none !important;
}

/* Le nom obligatoire (boite du nom, interface/noms-joueurs.js). */
.message-nom-obligatoire { color: #e0832a; font-size: 13px; margin: 4px 0; }

/* Les reglages de l'Entrainement (interface/entrainement-reglages.js). */
.reglages-entrainement { margin: 6px 0; }
.reglages-entrainement summary { cursor: pointer; color: #d9b62b; min-height: var(--hauteur-commande); line-height: var(--hauteur-commande); }
.defilement-horizontal { overflow-x: auto; }
.tableau-reglages-ceintures .nombre-reglage { width: 4.5em; }
.tableau-reglages-ceintures td { text-align: left; }
.reglages-entrainement .nombre-reglage { width: 5em; }
/* Les regles du profil d'Entrainement (interface/entrainement-reglages.js). */
.groupe-regles { margin: 4px 0; }
.groupe-regles summary { cursor: pointer; min-height: var(--hauteur-commande); line-height: var(--hauteur-commande); }
.ligne-regle-entrainement { display: flex; align-items: center; gap: 6px; min-height: var(--hauteur-commande); }
.ligne-regle-entrainement .libelle-regle { flex: 1; }
.ligne-regle-entrainement .sans-coche { display: inline-block; width: 18px; }
.historique-regles { max-height: 30vh; overflow: auto; }

/* La boite Entrainement : une seule zone defile (saab, 2026-10-09). */
.dialogue-grand .corps-entrainement {
  flex: 1 1 auto;
  flex-shrink: 1;
  min-height: 0;
  overflow-y: auto;
}

/* Les noms connus (interface/noms-connus.js) : une colonne a droite sous le champ,
   repliee sur le premier nom, depliee au toucher du champ, et qui defile. */
.liste-noms-connus {
  display: block;
  width: 60%;
  margin: 2px 0 4px auto;
  max-height: 30vh;
  overflow-y: auto;
  border: 1px solid #3a3a3a;
  border-radius: 4px;
}
.liste-noms-connus.liste-repliee .ligne-nom-connu:not(:first-child) {
  display: none;
}
.ligne-nom-connu {
  cursor: pointer;
  min-height: var(--hauteur-ligne-liste);
  font-size: 14px;
  padding-left: 2px;
}
.ligne-nom-connu:hover {
  background: rgba(255, 255, 255, 0.06);
}

/* L'icone ceinture, un peu plus grande que les autres. */
.icone-ceinture svg {
  width: 30px;
  height: 30px;
  display: block;
}

/* Annuler interdit par le grade (l'Entrainement, ceintures rouges). */
body.bloque-annuler :is(#nav-annuler, .bouton-annuler-joueur) {
  pointer-events: none;
  opacity: 0.3;
}

/* Les pastilles des Dans (interface/entrainement.js, classesDeLaCeinture) : la noire
   et ses barrettes dorees (une par Dan, jusqu'a 5), la blanche et rouge a rayures,
   la rouge. */
.ceinture-noire { position: relative; }
.ceinture-noire::after {
  content: '';
  position: absolute;
  right: 2px;
  top: 1px;
  bottom: 1px;
  width: calc(var(--barrettes) * 4px);
  background: repeating-linear-gradient(90deg, #d9b62b 0 2px, transparent 2px 4px);
}
.ceinture-dan-1 { --barrettes: 1; }
.ceinture-dan-2 { --barrettes: 2; }
.ceinture-dan-3 { --barrettes: 3; }
.ceinture-dan-4 { --barrettes: 4; }
.ceinture-dan-5 { --barrettes: 5; }
.ceinture.ceinture-blanche-rouge {
  background: repeating-linear-gradient(90deg, #f2f2f2 0 5px, #d22f2f 5px 10px) !important;
}

.case-proprietaire { font-size: 12px; }

/* Noir et Blanc differents (interface/pendules-mode.js) : la colonne de Blanc et
   les titres Noir / Blanc, seulement avec la case. */
.champ-pendule-blanc,
.entete-pendules-par-camp {
  display: none;
}
.pendules-par-camp .champ-pendule-blanc {
  display: inline-block;
  margin-left: 6px;
}
.pendules-par-camp .entete-pendules-par-camp {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  margin: 0;
  font-size: 12px;
  color: #9a9a9a;
}
.pendules-par-camp .entete-pendules-par-camp span {
  width: 70px; /* la largeur des champs, .ligne-nombre-pendule input */
  text-align: center;
}
/* Avec la colonne de Blanc : le libelle, le champ de Noir, celui de Blanc, alignes. Les champs des pendules
   seulement (#section-temps-pendule) : la classe est sur toute la boite, et la grille prenait aussi la
   Réflexion max d'une machine, dont le + passait a la ligne (saab, 2026-10-28). */
.pendules-par-camp #section-temps-pendule .ligne-nombre-pendule,
.pendules-par-camp .entete-pendules-par-camp {
  display: grid;
  grid-template-columns: 1fr 70px 70px;
  column-gap: 8px;
}
.pendules-par-camp .entete-pendules-par-camp span:first-child {
  grid-column: 2;
}
.pendules-par-camp .champ-pendule-blanc {
  margin-left: 0;
}


.message-fin-entrainement { color: #e4e4e4; font-weight: bold; }

/* Un rond de l'icone Entrainement ne se montre qu'avec une couleur (interface/entrainement.js). */
#bouton-entrainement .rond-ceinture:not(.rond-visible) { display: none; }

/* Le tableau des reglages de l'Entrainement (interface/entrainement-reglages.js) : une
   grande boite, une case par reglage (saab, 2026-10-10 : les valeurs a la largeur de
   « 999 », les en-tetes sur 2 lignes, la colonne Grade figee, la coche et sa valeur en
   un groupe entoure de la couleur de la ceinture, un point par Dan sur son trait du bas). */
.dialogue-tableau-entrainement { max-width: min(98vw, 1200px); width: 98vw; }
.tableau-regles-grades th { font-size: 11px; line-height: 1.15; white-space: nowrap; text-align: center; vertical-align: bottom; }
.tableau-regles-grades td, .tableau-regles-generales td { padding: 3px 3px 5px; }
.cellule-regle { white-space: nowrap; text-align: center; }
.tableau-regles-generales td.cellule-regle { width: 1%; text-align: left; }
/* Les valeurs d'un grade, centrees sous la couleur de sa ceinture (saab, 2026-10-18 ; la regle
   generale des tableaux, .tableau-historique td, les poussait a droite). */
.tableau-regles-grades td.cellule-regle { text-align: center; }
/* Les fleches pour augmenter et diminuer, toujours visibles (saab, 2026-10-14 : « trop
   compliqué sans les flèches » ; un appui prolonge va vite) : dans le tableau des
   reglages, les listes d'une ceinture et les tableaux Ceintures × Variantes / PZL. */
/* La largeur de « 999 » et ses fleches (saab, 2026-10-15 : « ajuster tous les champs sur
   999 + flèches, ce qui revient à 9999 en tout ») ; les nombres de jeux sur « 99 ». */
.cellule-regle .nombre-reglage {
  width: calc(3ch + 20px);
  padding: 0 2px;
  text-align: right;
}
.cellule-regle .nombre-reglage::-webkit-inner-spin-button,
.quota-type .nombre-reglage::-webkit-inner-spin-button,
.tableau-ceintures-jeux .nombre-reglage::-webkit-inner-spin-button { opacity: 1; }
.cellule-regle select { max-width: 5.5em; font-size: 10px; padding: 0 1px; }
.cellule-regle.reglage-court .nombre-reglage { width: calc(2ch + 20px); }
.groupe-regle {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 1px 3px;
  border: 2px solid var(--couleur-grade, #666);
  border-radius: 5px;
}
/* La noire sur fond sombre : un liseré clair (comme l'icone). */
.grade-noire .groupe-regle { box-shadow: 0 0 0 1px #8a8a8a; }
.grade-blanche-rouge .groupe-regle { border-image: repeating-linear-gradient(45deg, #f2f2f2 0 4px, #d22f2f 4px 8px) 2; }
.points-dan {
  position: absolute;
  left: 50%;
  bottom: -4px;
  transform: translateX(-50%);
  display: flex;
  gap: 3px;
}
.points-dan i { display: block; width: 5px; height: 5px; border-radius: 50%; background: #d9b62b; box-shadow: 0 0 0 1px #1e1e1e; }
.grade-blanche-rouge .points-dan i, .grade-rouge .points-dan i { background: #f2f2f2; }
.bouton-liste-reglage { font-size: 11px; min-height: 22px; white-space: nowrap; padding: 0 4px; }
.nom-grade { white-space: nowrap; text-align: left; }
.tableau-regles-grades .nom-grade { position: sticky; left: 0; z-index: 2; background: #1e1e1e; }
.titre-groupe-regles th { color: #d9b62b; text-align: left; padding-top: 8px; }
.tableau-regles-generales .libelle-regle { font-size: 12px; text-align: left; }
.nom-ceinture { display: inline-block; vertical-align: middle; line-height: 1.1; }
.dan-ceinture { font-size: 11px; color: #bbb; }

/* La boite Entrainement / Ceinture (interface/entrainement.js) : le choix du mode, les
   jeux proposes sous la ceinture ouverte, leur image et leurs deux sens. */
.bouton-mode-entrainement { width: 100%; font-size: 16px; margin-top: 8px; }
.ligne-onglets-entrainement { flex-wrap: wrap; }
.ligne-propositions > td { background: rgba(217, 182, 43, 0.07); }
.consigne-entrainement { font-size: 13px; margin: 2px 0 6px; }
.jeux-proposes { display: flex; flex-wrap: wrap; gap: 4px; }
.bouton-jeu-propose { font-size: 13px; }
.choix-jeu-entrainement { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 6px; }
.apercu-entrainement { width: 180px; height: 180px; }
.sens-jeu-entrainement { display: flex; flex-direction: column; gap: 6px; }
.resultat-reussi { color: #3fbf5a; font-weight: bold; }
.resultat-rate { color: #e04848; font-weight: bold; }
.titre-jeu-historique { font-size: 11px; word-break: break-all; }
/* La liste des jeux d'un grade (interface/entrainement-listes.js). */
.ligne-liste-jeu { display: flex; align-items: center; gap: 8px; min-height: var(--hauteur-ligne-liste); font-size: 13px; }
.ligne-liste-jeu .case-inclus { flex: 1; }
.ligne-liste-jeu[hidden] { display: none; }

/* L'onglet de l'Entrainement en cours : orange, comme tout ce qui est actif (saab). */
.onglet-entrainement.actif { background: #cc6a00; color: #fff; border-color: #cc6a00; }
.bouton-visee { min-height: var(--hauteur-commande); }

/* L'Aide : le titre du chapitre qu'on lit reste en haut (saab, 2026-10-09 : « figer
   la rubrique qu'on lit pour éviter de scroller si on veut sortir »). */
.dialogue-aide .aide-corps details[open] > summary {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #1a1a1a;
}
/* Le jeu touche et la ceinture choisie : orange, comme tout ce qui est actif (saab). */
.bouton-jeu-propose.bouton-actif, .tableau-ceintures [data-ouvrir].bouton-actif { background: #cc6a00; color: #fff; border-color: #cc6a00; }
.sens-jeu-entrainement .bouton-dialogue:disabled, .jeux-proposes .bouton-dialogue:disabled { opacity: 0.45; }

/* Le bouton Test (interface/apercu-test.js) : jamais dans le vrai KAAH_Test ; orange
   pendant l'apercu. */
body:not(.version-locale) .bouton-version-locale { display: none; }
#bouton-apercu-test.bouton-actif { background: #cc6a00; color: #fff; }

/* Le tableau des grades : sa propre zone, a la hauteur de la fenetre, pour que ses
   deux barres de defilement restent visibles (saab, 2026-10-10 : « on voit la barre
   de défilement, elle est hors fenêtre ») ; l'en-tete reste en haut, la colonne
   Grade a gauche. */
.dialogue-tableau-entrainement .defilement-horizontal {
  overflow: auto;
  max-height: calc(100dvh - 150px);
}
.tableau-regles-grades tr:first-child th { position: sticky; top: 0; z-index: 3; background: #1e1e1e; }
.tableau-regles-grades tr:first-child th.nom-grade { left: 0; z-index: 4; }
/* Les types d'une liste de jeux, chacun avec son nombre impose (saab, 2026-10-10). */
.section-type-jeux { margin-bottom: 6px; }
.titre-type-jeux { display: flex; justify-content: space-between; align-items: center; color: #d9b62b; font-size: 13px; border-bottom: 1px solid #3a3a3a; margin: 4px 0 2px; }
.quota-type { font-size: 12px; color: #ddd; }
.quota-type .nombre-reglage { width: calc(3ch + 26px); }
.section-type-jeux[hidden] { display: none; }

/* Le tableau des grades TRANSPOSE (interface/entrainement-tableau.js) : une colonne par
   grade, pas plus large que son mot le plus long ; le Dan en derniere ligne. */
.tableau-regles-transpose th.grade-en-colonne { white-space: normal; width: 1%; vertical-align: bottom; line-height: 1.15; }
.tableau-regles-transpose td.nom-grade { font-size: 12px; }

/* Le tableau des reglages : le profil, Valider, Abandonner et Transposer restent en haut
   quand on defile (saab, 2026-10-11 : « figer les btn Valider/Abandonner, car chaque
   fois on les cherche »). Le tableau des grades laisse la place de cette barre. */
.barre-reglages-entrainement {
  position: sticky;
  top: 0;
  z-index: 6;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
  background: #1a1a1a;
  border-bottom: 1px solid #3a3a3a;
}
.dialogue-tableau-entrainement .defilement-horizontal { max-height: calc(100dvh - 215px); }

/* Les tableaux Ceintures × Variantes et × PZL (interface/entrainement-ceintures-jeux.js) : sa
   propre zone de defilement a la hauteur de la fenetre (ses barres restent visibles),
   les ceintures figees en haut, le nom de la variante a gauche. */
.dialogue-ceintures-jeux { max-width: min(98vw, 1000px); width: 98vw; }
.zone-ceintures-jeux { overflow: auto; max-height: calc(100dvh - 275px); min-height: 160px; }
.tableau-ceintures-jeux th, .tableau-ceintures-jeux td { padding: 0 3px; text-align: center; white-space: nowrap; height: var(--hauteur-ligne-liste); }
.tableau-ceintures-jeux tr:first-child th { position: sticky; top: 0; z-index: 3; background: #1e1e1e; line-height: 1.15; vertical-align: bottom; }
.tableau-ceintures-jeux .nom-grade { position: sticky; left: 0; z-index: 2; background: #1e1e1e; text-align: left; font-size: 13px; }
.tableau-ceintures-jeux tr:first-child th.nom-grade { z-index: 4; }
.tableau-ceintures-jeux tr[hidden] { display: none; }
.tableau-ceintures-jeux .nombre-reglage { width: calc(2ch + 26px); padding: 0 2px; }
/* Le nom d'un jeu se touche : son image, posee par-dessus le tableau (interface/
   entrainement-ceintures-jeux.js) ; la toucher la referme. */
.nom-jeu-ceintures { cursor: pointer; text-decoration: underline dotted #777; }
/* Coller ne se montre qu'une colonne copiee (interface/entrainement-ceintures-jeux-colonnes.js). */
.tableau-ceintures-jeux [data-coller-grade] { display: none; }
.tableau-ceintures-jeux.colonne-copiee [data-coller-grade], .colonne-copiee [data-coller-grade] { display: inline-block; }
.dialogue-ceintures-jeux { position: relative; }
.image-ceintures-jeux { position: absolute; right: 26px; bottom: 26px; z-index: 8; width: 210px; padding: 4px; background: #1a1a1a; border: 2px solid #cc6a00; border-radius: 8px; cursor: pointer; text-align: center; }
.image-ceintures-jeux[hidden] { display: none; }
.image-ceintures-jeux svg { width: 200px; height: 200px; }
.titre-type-jeux-ceintures td { border-top: 1px solid #5a5a5a; padding-top: 3px; padding-bottom: 3px; line-height: 1.1; }
.tableau-ceintures-jeux .titre-type-jeux-ceintures .bouton-liste-reglage { min-height: 18px; margin-bottom: 2px; }
.titre-type-jeux-ceintures .nom-grade { color: #d9b62b; }
/* Un nom de PZL est long : il passe a la ligne plutot que d'elargir la colonne figee. */
.tableau-ceintures-jeux td.nom-grade { white-space: normal; overflow-wrap: anywhere; min-width: 150px; max-width: 215px; line-height: 1.15; }
/* En PZL : la case d'un autre grade que celui du PZL, pale. */
.tableau-ceintures-jeux td.hors-grade input { opacity: 0.35; }
.tableau-ceintures-jeux td.hors-grade input:checked { opacity: 1; }
/* Les jeux imposes dans la serie de chaque ceinture ; orange : plus que la serie n'en avait. */
/* « Imposés / série » reste en haut, sous les ceintures (saab, 2026-10-15 : « qu'on voie
   toujours ce total ») ; --hauteur-entete-ceintures : la hauteur de l'en-tete, posee a
   l'ouverture (interface/entrainement-ceintures-jeux.js). */
.ligne-imposes-serie td { font-size: 12px; color: #bbb; position: sticky; top: var(--hauteur-entete-ceintures, 56px); z-index: 3; background: #262626; border-bottom: 1px solid #5a5a5a; }
.ligne-imposes-serie td.nom-grade { z-index: 4; }
.ligne-imposes-serie td.trop-d-imposes { color: #ff9a2e; font-weight: bold; }
/* Le 📌 d'une case : pale tant que la variante n'est pas imposee. */
.epingle { appearance: none; -webkit-appearance: none; margin: 0 0 0 2px; width: 18px; height: 18px; vertical-align: middle; cursor: pointer; }
.epingle::before { content: '📌'; font-size: 13px; opacity: 0.22; filter: grayscale(1); }
.epingle:checked::before { opacity: 1; filter: none; }
.epingle:disabled { cursor: default; }

/* Le tableau des reglages (saab, 2026-10-14) : un groupe de reglages sur deux sur fond
   gris ; un reglage de l'autre mode de pendule (Bonus ou Délai), pale et inactif. */
.tableau-regles-grades .fond-gris, .tableau-regles-grades .nom-grade.fond-gris { background: #444; }
.tableau-regles-grades .hors-mode { opacity: 0.4; }

/* Le choix des variantes et des PZL du banc (interface/banc-essais-jeux.js) : une liste
   repliable, a sa hauteur. */
.banc-choix-jeux summary { cursor: pointer; color: #d9b62b; }
.banc-choix-jeux-barre { display: flex; gap: 4px; align-items: center; margin: 2px 0; }
.banc-choix-jeux-liste { max-height: 220px; overflow-y: auto; border: 1px solid #3a3a3a; padding: 2px 4px; }
.banc-choix-jeux-liste label[hidden] { display: none; }

/* Regler l'essai (interface/banc-essais-reglage.js) : ses fleches toujours visibles. */
.banc-reglage-essai .nombre-reglage { width: calc(4ch + 22px); }
.banc-reglage-essai .nombre-reglage::-webkit-inner-spin-button { opacity: 1; }
.banc-reglage-essai tr.banc-change td, .banc-reglage-essai tr.banc-change th { color: #e0832a; }

/* Revoir un fichier du banc (interface/banc-essais-revoir.js) : une partie deja vue a son titre (le nom
   de l'essai) en violet, comme dans le tableau des resultats (saab, 2026-10-23 : « mets le titre en violet
   qd elle est vue »). */
.partie-labalone-vue td:nth-child(3) { color: #b070e0; }

/* Les groupes de l'evaluation a l'ecran (interface/groupes-ia.js) : leur titre, et le
   filet de leur couleur devant chaque reglage (le texte garde la couleur de validation). */
.titre-groupe-ia {
  margin: 6px 0 0;
  font-weight: bold;
}
.ligne-groupe-ia {
  border-left: 3px solid var(--couleur-groupe-ia);
  padding-left: 4px;
}
.ligne-titre-groupe-ia th {
  text-align: left;
  font-weight: bold;
  padding-top: 4px;
}

/* La reflexion de l'IA dans Conseils (interface/conseil-ia.js) : une ligne serree. */
.ligne-conseil-ia {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 6px;
  margin-bottom: 4px;
}

.ligne-conseil-ia select {
  max-width: 12em;
}

.ligne-conseil-ia input[type='number'] {
  width: 3.5em;
}

.ligne-conseil-ia .bouton-dialogue {
  margin: 0;
  padding: 0 8px;
}

/* Le graphique des 4 groupes (interface/graphique-groupes.js) : un panneau de la colonne
   de droite, comme Conseils (jamais par-dessus le plateau). Sur ordinateur, plus large que
   la Sequence, et son coin en bas a droite l'elargit (resize). */
#panneau-graphique-groupes {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 4px;
  background: #1a1a1a;
  color: #e4e4e4;
  font: 12px/1.2 sans-serif;
  border-top: 1px solid #3a3a3a;
}

#panneau-graphique-groupes[hidden] {
  display: none;
}

/* Le face-a-face n'en a pas besoin (saab, 2026-10-16) : la colonne y tourne. */
body.face-a-face #panneau-graphique-groupes,
body.face-a-face .tableau-barres-groupes {
  display: none;
}

.poignee-largeur-graphique {
  display: none;
}

/* Ordinateur : toute la largeur de la colonne, que sa poignee de gauche elargit aux depens
   du plateau (--largeur-sequence) ; son coin en bas a droite l'allonge. Telephone : un
   apercu seulement (saab, 2026-10-16 : « inutile de surcharger sur tél ») — les courbes,
   sans les barres. */
@media (min-width: 700px) {
  #panneau-graphique-groupes {
    position: relative;
    resize: vertical;
    overflow: auto;
    border-left: 1px solid #3a3a3a;
  }

  body:not(.face-a-face) .poignee-largeur-graphique {
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 8px;
    cursor: ew-resize;
    touch-action: none;
    z-index: 2;
  }

  body:not(.face-a-face) .poignee-largeur-graphique:hover,
  body:not(.face-a-face) .poignee-largeur-graphique:active {
    background: #3a3a3a;
  }
}

@media (max-width: 699px) {
  #bouton-barres-graphique-groupes,
  .tableau-barres-groupes {
    display: none;
  }
}

.entete-graphique-groupes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
}

.entete-graphique-groupes h2 {
  margin: 0;
  font-size: 14px;
}

.entete-graphique-groupes .bouton-dialogue {
  margin: 0;
  padding: 0 8px;
}

.entete-graphique-groupes input[type='number'] {
  width: 4em;
}

#coup-graphique-groupes {
  width: 100%;
}

.zone-graphique-groupes {
  position: relative;
}

.graphique-groupes {
  display: block;
  width: 100%;
  height: auto;
  background: #1e1e1e;
  border: 1px solid #3a3a3a;
  cursor: pointer;
}

/* Sous les courbes ; detachees (tirees par leur poignee), au-dessus de tout, ou l'on veut. */
.tableau-barres-groupes {
  padding: 2px 6px 6px;
  font: 11px/1.2 sans-serif;
  color: #e4e4e4;
  background: rgba(20, 20, 20, 0.95);
  border: 1px solid #555;
  border-radius: 4px;
}

.tableau-barres-groupes.barres-detachees {
  position: fixed;
  z-index: 60;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.6);
}

.entete-barres-groupes {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 2px;
}

.entete-barres-groupes .bouton-dialogue {
  margin: 0 0 0 auto;
  padding: 0 6px;
  min-height: 0;
  height: 20px;
}

.entete-barres-groupes .bouton-dialogue + .bouton-dialogue {
  margin-left: 0;
}

.tableau-barres-groupes[hidden] {
  display: none;
}

.poignee-barres-groupes {
  cursor: move;
  user-select: none;
  color: #9a9a9a;
  touch-action: none;
}

.barres-groupes {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}

.barre-groupe {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.total-barre-groupe {
  font-weight: bold;
  margin-bottom: 2px;
}

/* Un terme : son libelle et sa valeur a gauche, son morceau de barre a droite. */
.morceau-barre-groupe {
  display: flex;
  align-items: stretch;
  gap: 4px;
}

.morceau-barre-groupe span {
  align-self: center;
  white-space: nowrap;
  font-size: 10px;
}

.morceau-barre-groupe b {
  width: 14px;
  border-bottom: 1px solid #1a1a1a;
}

/* Un terme negatif (une perte, un bord a soi) : hachure. */
.morceau-barre-groupe b.morceau-negatif {
  background-image: repeating-linear-gradient(45deg, rgba(0, 0, 0, 0.55) 0 3px, transparent 3px 6px);
}

/* L'occupation du stockage (interface/sauvegarde-complete.js) : une cle par ligne. */
.occupation-stockage { white-space: pre-line; }

/* Les couleurs des boutons d'action, partout (saab, 2026-10-14 et 15) : VERT, ce qui reste
   a faire pour ne rien perdre (Valider quand une retouche attend, Exporter quand un essai
   est fini) et Fermer, qui ne perd rien ; ROUGE, ce qui peut effacer des donnees
   (Abandonner, Vider, Supprimer, Arreter un essai) et un Fermer qui oublierait des
   changements (.bouton-danger) ; ORANGE, deja exporte. */
.bouton-dialogue.bouton-a-faire:not(:disabled) { background: var(--vert-demande); border-color: var(--vert-demande); color: #fff; }
button[id^='bouton-fermer'], #bouton-annuler-liste-entrainement { background: var(--vert-demande); border-color: var(--vert-demande); color: #fff; }
.bouton-dialogue.bouton-danger:not(:disabled),
.bouton-dialogue[data-abandonner]:not(:disabled), #bouton-abandonner-profil-ia:not(:disabled),
button[id^='bouton-vider']:not(:disabled), button[id^='bouton-supprimer']:not(:disabled), .bouton-dialogue[data-supprimer],
#bouton-confirmer-suppression, #bouton-arreter-banc:not(:disabled) { background: #7c2424; border-color: #9c3a3a; color: #fff; }
.bouton-dialogue.deja-exporte { background: #cc6a00; border-color: #cc6a00; color: #fff; }
/* Un bouton bascule allume (ce qu'il montre est affiche) : orange ; eteint : vert (bouton-a-faire). */
.bouton-dialogue.bouton-allume { background: #cc6a00; border-color: #cc6a00; color: #fff; }
/* Lancer, tant que la serie finie n'est pas exportee (interface/banc-essais.js). */
.bouton-dialogue.bouton-grise { opacity: 0.45; }

/* Ce qui n'existe que dans une version de travail (jamais dans KAAH_Test, ni dans son apercu). */
body:not(.version-de-travail) .seulement-version-de-travail { display: none; }
.actions-type-jeux { display: flex; align-items: center; gap: 6px; }

/* Les mises a la ligne d'un message de confirmation (« \n », ex. l'installation) se voient. */
#message-confirmation {
  white-space: pre-line;
}
/* Ce que coute l'installation (« (quelques Mo) », interface/confirmation.js, enRouge) : le rouge du
   bouton Installer, en pastille — un texte rouge ne se lirait pas sur le vert de la boite. */
.message-en-rouge {
  background: #7c2424;
  color: #fff;
  border-radius: 3px;
  padding: 0 3px;
}

/* L'en-tete de Conseils : le titre, puis Fermer a droite (interface/next-move.js). */
.entete-conseils {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}

.entete-conseils .bouton-dialogue {
  margin: 0;
  padding: 0 8px;
}

/* Le petit plateau des sequences : une fenetre qui ne bloque rien, au-dessus de la page
   (interface/sequence-prevue.js) ; son titre la deplace. */
#dialogue-sequence-prevue {
  position: fixed;
  z-index: 55;
}

#titre-sequence-prevue {
  cursor: move;
  user-select: none;
}

/* L'infobulle au doigt (interface/infobulle-tactile.js) : au-dessus de tout. */
.infobulle-tactile {
  position: fixed;
  z-index: 100;
  max-width: min(90vw, 360px);
  padding: 6px 8px;
  background: #fffbe0;
  color: #1a1a1a;
  font: 13px/1.3 sans-serif;
  border-radius: 6px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}

.infobulle-tactile[hidden] {
  display: none;
}

/* Un appui long montre l'infobulle : pas le menu du navigateur par-dessus (iOS). */
button[title],
label[title] {
  -webkit-touch-callout: none;
}

/* Vider les recherches : en rouge quand elles passent les 3/4 du maximum (saab, 2026-10-17),
   interface/recherche-ia.js. */
.bouton-vider-recherches.vider-a-faire {
  background: #7c2424;
  border-color: #c03a3a;
  color: #fff;
}

/* Une confirmation qui n'efface rien (l'alerte des ceintures) : en vert, pas en rouge. */
#bouton-confirmer-suppression.confirmation-verte {
  background: var(--vert-demande);
  border-color: var(--vert-demande);
  color: #fff;
}
/* Un bouton vert dans une boite verte disparaissait (saab, 2026-10-23 : « Later ... n'a rien comme il
   est dans le vert » ; 2026-10-24 : le Fermer de la boite Fin de partie) : une pastille d'un vert plus
   sombre, bordee de clair. */
#dialogue-confirmation .bouton-dialogue.bouton-a-faire:not(:disabled),
#bouton-confirmer-suppression.confirmation-verte,
#dialogue-fin-de-partie button[id^='bouton-fermer'] {
  background: #135227;
  border-color: #cfe9d6;
}

/* Les nouveaux PZL a valider, sur la plus haute ceinture reussie (interface/entrainement-nouveaux.js). */
.nouveaux-pzl {
  color: #e0832a;
  font-weight: bold;
}

/* Ce qu'on apprend a la ceinture ouverte (interface/objectifs-ceintures.js). */
.objectif-ceinture {
  margin: 2px 0 4px;
  font-size: 0.9em;
}

/* Le bouton de taille des billes d'un PZL, sous son bandeau (index.html). */
#bouton-taille-billes-pzl {
  align-self: flex-start;
  min-height: var(--hauteur-commande);
  padding: 0 8px;
}
#bouton-taille-billes-pzl[hidden] {
  display: none;
}

/* Bonus / Délai du Tableau des reglages d'Entrainement : un bouton qui bascule. */
.bouton-mode-reglage {
  min-height: calc(var(--hauteur-commande) - 6px);
  padding: 0 4px;
  cursor: pointer;
}

/* La ceinture ouverte de l'Entrainement (saab, 2026-10-17 : « mettre le focus sur la
   couleur de ceinture et de son texte, et figer pour avoir le valider visible qd on fait
   défiler les jeux ») : sa ligne, pastille agrandie et nom en gras, reste en haut de la
   zone qui defile ; l'image du jeu touche et ses boutons Noir / Blanc restent en bas. */
.ceinture-visee td {
  position: sticky;
  top: 0;
  z-index: 2;
  background: linear-gradient(rgba(217, 182, 43, 0.18), rgba(217, 182, 43, 0.18)), #1a1a1a;
}
.ceinture-visee .ceinture {
  width: 34px;
  height: 14px;
  box-shadow: 0 0 0 2px #cc6a00;
}
.ceinture-visee .nom-ceinture {
  font-weight: bold;
  color: #f2d23c;
}
.ligne-propositions .choix-jeu-entrainement {
  position: sticky;
  bottom: 0;
  z-index: 1;
  padding: 4px 0;
  background: linear-gradient(rgba(217, 182, 43, 0.07), rgba(217, 182, 43, 0.07)), #1a1a1a;
  border-top: 1px solid #cc6a00;
}

/* Le tableau des noms des profils IA (interface/noms-profils-ia-tableau.js). */
#tableau-noms-profils-ia td { white-space: nowrap; }
#tableau-noms-profils-ia .nom-actuel-ia { font-weight: bold; }

/* La langue (interface/langue.js) : ce qui ne se montre qu'en anglais, le bouton Fra/Eng. */
.seulement-en-anglais { display: none; }
.en-anglais .seulement-en-anglais { display: flex; }
.aide-a-traduire { flex-wrap: wrap; align-items: center; gap: 6px; margin: 4px 0; color: #e0832a; font-size: 13px; }
.boutons-entete-aide { display: flex; gap: 6px; align-items: flex-start; }
/* Sous le hors-ligne, a gauche (index.html) : sa largeur, pas celle de la colonne. */
.aide-entete .bouton-nouvelle-version { display: block; justify-self: start; margin: 2px 0 6px; }
.aide-entete .bouton-nouvelle-version[hidden] { display: none; }
#bouton-langue-chargement { margin: 0 0 6px; }

/* LabAl : l'essai en Blanc en blanc, en Noir en gris (interface/banc-essais-page.js) ; une
   partie se touche pour la regarder — orange : regardee, violet : deja vue
   (interface/banc-essais-regarder.js). */
.banc-essai-noir td { color: #8c8c8c; }
.banc-essai-blanc td { color: #ffffff; }
#banc-resultats tr[data-partie-banc], .banc-ligne-en-cours { cursor: pointer; }
#banc-resultats tr[data-partie-banc]:hover td { background: rgba(255, 255, 255, 0.05); }
#banc-resultats tr.banc-regardee td:nth-child(2) { color: #e0832a; font-weight: bold; }
#banc-resultats tr.banc-vue td:nth-child(2) { color: #b070e0; }

/* Les parties en cours de LabAl : la couleur du camp de l'essai, comme dans le tableau. */
.banc-ligne-en-cours.banc-essai-noir { color: #8c8c8c; }
.banc-ligne-en-cours.banc-essai-blanc { color: #ffffff; }
.banc-ligne-en-cours.banc-regardee .banc-nom-en-cours { color: #e0832a; font-weight: bold; }
.banc-ligne-en-cours.banc-vue .banc-nom-en-cours { color: #b070e0; }

/* LabAl : ce qu'est devenue la retouche de l'essai, en fin de serie (interface/banc-essais-reglage.js). */
.banc-validation-auto { color: #e0832a; font-weight: bold; }

/* Les valeurs PAR DEFAUT en marron (saab, 2026-10-22 : l'orange dit deja « retouche pas
   encore validee », le jaune « validee il y a longtemps », le violet est aux branches) :
   l'IA par defaut partout ou un profil se montre (interface/noms-profils-ia.js,
   marquerSiProfilParDefaut), avant les couleurs de ses reglages ; la reflexion et
   l'elagage d'une machine (interface/choix-joueurs.js) ; les morceaux de son nom
   (interface/nom-machine-couleurs.js). */
.profil-ia-par-defaut, option.profil-ia-par-defaut, select.profil-ia-par-defaut { color: #c8925c !important; font-weight: bold; }
input.valeur-par-defaut, input.valeur-par-defaut::placeholder, span.valeur-par-defaut { color: #c8925c; font-weight: bold; }
/* « ∞ » (sans limite), le champ de reflexion vide : bien lisible, pas en gris pale. */
.choix-reflexion-max::placeholder { color: #ddd; opacity: 1; font-weight: bold; }

/* LabAl, partie en cours : le camp qui cherche, vert si son evaluation est positive, rouge si negative. */
.banc-eval-positive { color: #3fcf7a; font-weight: bold; }
.banc-eval-negative { color: #e05a5a; font-weight: bold; }

/* Les tableaux de l'Entrainement en lecture seule (KAAH_Test ; saab, 2026-10-18 : « tous les
   btn de réglage sont inutiles pour les joueurs ... il ne reste que ce qui indique au joueur
   ce qu'il a à faire ») : ni outils de colonne ou de ligne, ni fleches (les coches des regles
   restent : elles disent si une regle joue) ;
   restent les jeux proposes (✓), imposes (📌), les nombres imposes et « Imposés / série ». */
.seulement-lecture { display: none; }
.lecture-seule .seulement-lecture { display: inline; }
.lecture-seule .seulement-modifiable { display: none; }
.lecture-seule .tableau-ceintures-jeux th .bouton-liste-reglage,
.lecture-seule [data-cocher-jeu],
.lecture-seule [data-cocher-type],
.lecture-seule .actions-type-jeux { display: none; }
.lecture-seule input[type='number'] {
  appearance: textfield;
  -moz-appearance: textfield;
  border: none;
  background: transparent;
  color: inherit;
  opacity: 1;
  text-align: center;
}
.lecture-seule input[type='number']::-webkit-inner-spin-button,
.lecture-seule input[type='number']::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.lecture-seule input[type='checkbox']:disabled { opacity: 1; }

/* L'historique des versions du profil d'Entrainement : rien pour les joueurs (KAAH_Test). */
.lecture-seule .historique-entrainement-regles { display: none; }

/* La pause de la machine (Entrainement, interface/ia.js) : orange tant qu'elle reflechit,
   verte quand son coup attend votre clic. */
.bouton-pendule.pause-machine-demandee .cadre-pendule { fill: #cc6a00; }
.bouton-pendule.pause-machine-demandee .pendule-camp { fill: #e4e4e4; }
.bouton-pendule.coup-en-attente .cadre-pendule { fill: var(--vert-demande); }
.bouton-pendule.coup-en-attente .pendule-camp { fill: #e4e4e4; }

/* Deux choix egaux (le camp d'une partie par correspondance) : sans couleur. */
#bouton-confirmer-suppression.confirmation-neutre { background: #3a3a3a; border-color: #555; color: #e4e4e4; }

/* Valider de Profil IA (saab, 2026-10-21) : sa barre reste visible en bas de Reglages ;
   orange juste apres la validation (.bouton-valide), meme grise. */
.barre-valider-profil-ia { position: sticky; bottom: 0; z-index: 3; background: var(--couleur-fond-fenetre, #595959); padding: 4px 0; }
.bouton-dialogue.bouton-valide { background: #cc6a00; border-color: #cc6a00; color: #fff; opacity: 1; }

/* Le choix des joueurs (saab, 2026-10-21 : « mettre Noir dans un encadré noir et Blanc dans un
   blanc, et aussi mettre Noir en dessous de Blanc, pour être cohérent avec la position sur le
   plateau ») : Blanc en haut, Noir en bas, comme leurs billes ; le nom du camp sur sa couleur. */
.section-adversaire:not([hidden]) { display: flex; flex-direction: column; }
.section-adversaire > .choix-joueur[data-camp='blanc'] { order: 1; }
.section-adversaire > .choix-joueur[data-camp='noir'] { order: 2; border-top: 1px solid #3a3a3a; margin-top: 6px; }
.section-adversaire > .choix-joueur + .choix-joueur[data-camp='blanc'] { border-top: none; margin-top: 0; }
.choix-joueur[data-camp] > .ligne-choix-machine:first-child > span { box-sizing: border-box; padding: 2px 8px; border-radius: 4px; text-align: center; font-weight: bold; }
.choix-joueur[data-camp='noir'] > .ligne-choix-machine:first-child > span { background: #111; color: #f2f2f2; border: 1px solid #888; }
.choix-joueur[data-camp='blanc'] > .ligne-choix-machine:first-child > span { background: #f2f2f2; color: #111; border: 1px solid #888; }

/* Fermer des panneaux d'une bille et de l'aire (saab, 2026-10-21) : en vert, comme les autres Fermer. */
.entete-panneau-bille .bouton-fermer-panneau { background: var(--vert-demande); border-color: var(--vert-demande); color: #fff; }

/* L'apercu de KAAH_Test (interface/apercu-test.js) : les tableaux des ceintures, en lecture seule,
   le disent (saab, 2026-10-22 : « je ne peux plus modifier les tableaux », il etait en aperçu). */
.note-apercu-test { display: none; margin: 2px 0 6px; color: #e0832a; font-weight: bold; font-size: 13px; }
body.apercu-kaah-test .note-apercu-test { display: block; }

/* La boite de la Nouvelle partie (saab, 2026-10-27 : « Mettre aussi les réglages du joueur Blanc sur fond
   blanc, comme ça on verra bien ce qui lui est attribué ») : le bloc de Blanc sur fond clair, texte sombre. */
.choix-joueur[data-camp="blanc"] {
  background: #e8e8e8;
  color: #111111;
  border-radius: 6px;
  padding: 4px 6px;
}
.choix-joueur[data-camp="blanc"] .note-reglages {
  color: #333333;
}
.choix-joueur .choix-nom-joueur {
  width: 12em;
  min-height: var(--hauteur-commande);
}
.section-nouvelle-partie {
  margin-bottom: 6px;
}

/* Les noms de fin de partie (interface/noms-fin-de-partie.js ; saab, 2026-10-28 : « en fond blanc pour Blanc et
   noir pour Noir ») : chaque camp sur sa couleur, comme dans la boite Nouvelle partie. */
.ligne-nom-fin {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 4px 0;
  padding: 4px 8px;
  border: 1px solid #888888;
  border-radius: 6px;
}
.ligne-nom-fin[hidden] {
  display: none;
}
.ligne-nom-fin span {
  width: 4em;
  font-weight: bold;
}
.ligne-nom-fin input {
  flex: 1;
  min-height: var(--hauteur-commande);
}
.ligne-nom-fin[data-camp='blanc'] {
  background: #f2f2f2;
  color: #111111;
}
.ligne-nom-fin[data-camp='blanc'] input {
  background: #ffffff;
  color: #111111;
}
.ligne-nom-fin[data-camp='noir'] {
  background: #111111;
  color: #f2f2f2;
}
#bouton-valider-noms-fin {
  margin-top: 6px;
}
