/* KataGo — jouer au Go contre la politique de son reseau
   Copyright (c) 2026 Tristan Cazenave. Tous droits réservés — voir LICENSE. */
:root {
  /* ── LE CODE COULEUR DES JEUX DE GO ────────────────────────────────────────
     CELUI DE LA PORTE : les huit jeux reprennent les couleurs de la page
     d'accueil, et ce qu'il faut pour que LES CHOIX SE VOIENT COMME DES CHOIX.

     Ces deux jeux-ci etaient sombres quand les six autres etaient beiges ; les
     noms de variables ne changent pas, seulement ce qu'ils designent.

     Trois etats, trois traitements, et jamais la couleur seule :
       a prendre    fond `--fond-3`, bord `--bord`        3,9:1
       retenu       fond `--accent`, texte clair, gras    8,4:1
       impossible   `--texte-doux`, sans bord
     ──────────────────────────────────────────────────────────────────────── */
  --fond: #E6E7E1;              /* le gris de la porte */
  --fond-2: #F6F6F1;            /* une carte posee dessus */
  --fond-3: #EDEDE6;            /* le fond d'un choix qu'on peut prendre */
  --bord: #6E7684;              /* 3,9:1 sur ce fond — un vrai contour */
  --texte: #171A20;             /* 16,1:1 sur la carte */
  --texte-doux: #4E5663;        /*  6,8:1 sur la carte */
  --accent: #2C4E7E;            /* CE QUI EST RETENU, et rien d'autre */
  --accent-sombre: #1F3A5F;
  --danger: #A63C50;            /* 5,3:1 sur la carte */
  --bois: #D6B173;              /* un bois de goban, pas un jaune d'ecran */
  /* Les deux bouts du degrade de chaque pierre : la lumiere, puis le bord. */
  --pierre-n1: #5A626C; --pierre-n2: #0B0E12;
  --pierre-b1: #FFFFFF; --pierre-b2: #D8CFBA;
  --bois-trait: #6B5326;
  --rayon: 10px;
  --panneau-l: 340px;
  color-scheme: light;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100dvh;
  background: var(--fond);
  color: var(--texte);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
}
button, input, select { font: inherit; color: inherit; }
.ecran { height: 100%; min-width: 0; }
[hidden] { display: none !important; }
.pousse { flex: 1; }

/* ─────────────────────────────── boutons ─────────────────────────────── */
.btn {
  border: 1px solid var(--bord); background: var(--fond-3); color: var(--texte);
  padding: 8px 14px; border-radius: var(--rayon); cursor: pointer;
  transition: background .12s, border-color .12s; white-space: nowrap;
}
@media (hover: hover) { .btn:hover:not(:disabled) { background: var(--accent-clair, #e7e3f3);
    border-color: var(--accent); } }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn-primaire {
  background: var(--accent);
  border-color: var(--accent-sombre); color: #fff; font-weight: 650;
}
.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-mini { padding: 6px 10px; font-size: 13px; }

/* ───────────────────────────── configuration ───────────────────────────── */
#ecran-config {
  display: grid; place-items: center; padding: 24px; overflow: auto;
  background: radial-gradient(1100px 620px at 50% -8%, #ffffffaa 0%, transparent 70%), var(--fond);
}
.boite {
  width: min(680px, 100%); background: var(--fond-2); border: 1px solid var(--bord);
  border-radius: 16px; box-shadow: 0 24px 70px #0008; display: flex; flex-direction: column;
  min-height: 0; overflow: hidden;
}
.boite-tete {
  padding: 26px 28px 18px; border-bottom: 1px solid var(--bord); flex: 0 0 auto;
  display: flex; flex-direction: column;
}
/* le meme selecteur de langue que le reste de nestedplay, et le meme reglage */
.langues {
  display: inline-flex; align-self: flex-end; margin-bottom: 6px;
  border: 1px solid var(--bord); border-radius: 9px;
  overflow: hidden; background: var(--fond-3);
}
.langues button {
  border: 0; background: transparent; color: var(--texte-doux); font: inherit;
  font-size: 11px; letter-spacing: .08em; padding: 3px 9px; cursor: pointer;
}
.langues button + button { border-left: 1px solid var(--bord); }
.langues button[aria-pressed="true"] { background: var(--accent); color: #fff; }
.boite-tete h1 { margin: 0; font-size: 28px; letter-spacing: -.4px; }
.sous-titre { margin: 8px 0 0; color: var(--texte-doux); font-size: 14px; }
.sous-titre .rappel { opacity: .75; font-size: 13px; }
.boite-corps { padding: 22px 28px; display: grid; gap: 18px; overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.boite-pied {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  padding: 16px 28px; border-top: 1px solid var(--bord); background: var(--fond-3); flex: 0 0 auto;
}

.champ { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.champ > label { font-weight: 600; min-width: 118px; }
.libre { font-weight: 400 !important; color: var(--texte-doux); font-size: 14px; }
.champ-temperature input[type="range"] { flex: 1 1 160px; min-width: 120px; accent-color: var(--accent); }
.champ-temperature b { font-variant-numeric: tabular-nums; min-width: 42px; }
.champ-temperature em { flex: 1 0 100%; font-size: 12.5px; font-style: normal; }
.libre input { width: 64px; }
input[type="number"] {
  background: var(--fond-2); border: 1px solid var(--bord); border-radius: 8px;
  padding: 7px 9px; width: 88px;
}
.segment { display: flex; gap: 6px; flex-wrap: wrap; }
.segment button {
  min-width: 46px; min-height: 40px; padding: 0 12px;
  border: 1px solid var(--bord); background: var(--fond-3);
  border-radius: 9px; cursor: pointer; font-weight: 600;
}
.segment.large button { min-width: 128px; }
.segment button[aria-checked="true"] {
  background: var(--accent); color: #fff; border-color: var(--accent-sombre);
}
.case { display: flex; gap: 10px; align-items: center; cursor: pointer; font-size: 14px; }
.case em { color: var(--texte-doux); font-style: normal; }

/* ───────────────────────────────── jeu ───────────────────────────────── */
#ecran-jeu { display: grid; grid-template-rows: auto 1fr; height: 100%; min-width: 0; }
#barre {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-width: 0;
  padding: 9px 14px; padding-top: max(9px, env(safe-area-inset-top));
  background: var(--fond-2); border-bottom: 1px solid var(--bord);
}
.jeton { width: 15px; height: 15px; border-radius: 50%; flex: 0 0 auto; box-shadow: 0 0 0 2px #0006; }
.jeton.noir { background: #14171b; }
.jeton.blanc { background: #f6f3ea; }
.etiquette {
  font-size: 12.5px; color: var(--texte-doux);
  border: 1px solid var(--bord); background: var(--fond-3);
  padding: 3px 10px; border-radius: 999px;
}
.etiquette.attente { color: var(--accent); border-color: var(--accent-sombre); background: var(--accent-clair); }

#plateau { display: grid; grid-template-columns: 1fr var(--panneau-l); min-height: 0; min-width: 0; }
#zone-goban {
  position: relative; min-width: 0; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 10px; background: var(--fond-3);
}
#goban { width: 100%; flex: 1 1 auto; min-height: 0; display: block;
         touch-action: manipulation; cursor: pointer; }
#zone-goban.revue #goban { cursor: default; }

/* La liste des parties gardees sur le compte : une ligne par partie, cliquable.
   Chaque bouton porte ce qui identifie la partie a gauche, sa date a droite. */
.mes-parties { display: grid; gap: 6px; max-height: 46vh; overflow: auto;
  margin-bottom: 12px; }
.ligne-partie { display: flex; align-items: baseline; gap: 10px; width: 100%;
  text-align: left; }
.ligne-partie b { font-weight: 600; }
.ligne-partie em { margin-left: auto; font-style: normal; opacity: .65;
  font-size: 12.5px; white-space: nowrap; }
/* Reprendre une partie et la jeter sont deux gestes : deux boutons, cote a
   cote, et non un bouton dans un bouton -- ce que le HTML ne permet pas. */
.duo-partie { display: flex; gap: 6px; align-items: stretch; }
.duo-partie .ligne-partie { flex: 1; }
.duo-partie .jeter { flex: 0 0 auto; padding: 6px 10px; color: var(--texte-doux); }
@media (hover: hover) {
  .duo-partie .jeter:hover { color: var(--danger); border-color: var(--danger); }
}

/* Le ruban de revue : il ne rejoue rien, il montre une position deja atteinte. */
.ruban {
  flex: 0 0 auto; display: flex; align-items: center; gap: 6px;
  width: min(100%, 560px); padding: 0 2px;
}
/* Les quatre fleches sont des boutons de meme largeur : elles se lisent comme
   une seule commande, et le curseur garde toute la place qui reste. */
.ruban .btn-mini { flex: 0 0 auto; padding: 6px 8px; line-height: 1; }
.ruban .coup-n { margin-left: 4px; }
.ruban input[type="range"] { flex: 1; min-width: 0; accent-color: var(--accent); height: 24px; }
.coup-n {
  font-size: 12.5px; color: var(--texte-doux); font-variant-numeric: tabular-nums;
  min-width: 96px; text-align: right;
}
#zone-goban.revue .coup-n { color: var(--accent); }

/* non-scaling-stroke compte l'epaisseur en pixels d'ecran, pas en pas du
   goban : c'est justement ce qu'on veut ici -- un trait d'un pixel, net, que le
   goban fasse 5 lignes ou 19 -- mais il fallait l'ecrire en pixels. */
.ligne { stroke: var(--bois-trait); stroke-width: 1; vector-effect: non-scaling-stroke; }
.hoshi { fill: var(--bois-trait); }
.coord { fill: #7d6534; font-size: 0.5px; font-family: inherit; user-select: none; }
/* Les pierres ont un reflet : clair au point d'éclairage, sombre au bord, et
   une ombre portée dessous. Les valeurs sont celles de Geta. */
.ombre { fill: #00000038; }
.pierre { stroke: #00000055; stroke-width: 0.02; }
.pierre.noire { fill: url(#pierre-n); }
.pierre.blanche { fill: url(#pierre-b); }
.fantome { opacity: .42; pointer-events: none; }
.dernier { pointer-events: none; }
.dernier.sur-noire { fill: #f6f3ea; }
.dernier.sur-blanche { fill: #14171b; }
.jouable { fill: #00000018; pointer-events: none; }
.triangle { fill: none; stroke: #c0392b; stroke-width: 0.09; stroke-linejoin: round; pointer-events: none; }
/* Le carré du mauvais coup : plus vif que le triangle du meilleur, et doublé
   d'un liseré sombre pour tenir aussi bien sur une pierre blanche que noire. */
.mauvais { fill: none; stroke: #c0392b; stroke-width: 0.085; pointer-events: none; }
.mauvais-ombre { fill: none; stroke: rgba(255, 255, 255, .65); stroke-width: 0.15;
  pointer-events: none; }

.annonce {
  position: absolute; left: 50%; top: 16px; transform: translateX(-50%);
  background: #F6F6F1f0; border: 1px solid var(--accent); color: var(--accent);
  padding: 9px 20px; border-radius: 999px; font-weight: 650; z-index: 6;
  max-width: calc(100% - 24px); text-align: center;
}
/* Un avertissement ne se lit pas comme « la partie repart d'ici » — et il tient
   deux lignes sur un téléphone : la pastille arrondie d'un message court y
   deviendrait une bulle ovale posée en travers du goban. */
.annonce.alerte {
  border-color: var(--danger); color: var(--danger);
  border-radius: 12px; line-height: 1.35; max-width: min(430px, calc(100% - 20px));
}

/* ─────────────────────────────── panneau ─────────────────────────────── */
#panneau {
  background: var(--fond-2); border-left: 1px solid var(--bord);
  overflow: hidden; display: flex; flex-direction: column; min-width: 0;
}
.corps-panneau { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
.tete-feuille { display: none; }
.bloc { padding: 13px 15px; border-bottom: 1px solid var(--bord); }
.bloc h3 {
  margin: 0 0 9px; font-size: 12px; text-transform: uppercase;
  letter-spacing: .1em; color: var(--texte-doux);
}
.bloc-journal { flex: 1; min-height: 140px; display: flex; flex-direction: column; }
.aide { color: var(--texte-doux); font-size: 13.5px; margin: 10px 0 0; }

/* la note du coup : c'est l'information que l'on vient chercher ici */
.cote { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.cote b { font-size: 20px; }
.cote .proba { font-size: 20px; color: var(--accent); font-variant-numeric: tabular-nums; }
.cote .rang { font-size: 13px; color: var(--texte-doux); }
.cote-vide { color: var(--texte-doux); }
/* Ce qu'un coup a coûté : le chiffre reste sous les yeux jusqu'au coup suivant,
   là où l'on vient déjà lire la note. */
.cote .perte {
  font-size: 13px; font-weight: 650; color: var(--danger);
  border: 1px solid var(--danger); border-radius: 999px; padding: 2px 9px;
  font-variant-numeric: tabular-nums;
}

/* L'avance estimee : elle sort de la meme inference que la politique. */
.score { margin-top: 10px; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.score .score-t {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--texte-doux);
}
.score b { font-size: 15px; font-variant-numeric: tabular-nums; }

.actions { display: grid; gap: 8px; }
.actions .rangee { display: flex; gap: 8px; }
.actions .rangee > * { flex: 1; }

#journal {
  margin: 0; padding: 0 0 0 4px; list-style: none; overflow-y: auto; flex: 1;
  font-size: 13px; color: var(--texte-doux); font-variant-numeric: tabular-nums;
}
#journal li { padding: 2px 0; border-bottom: 1px solid var(--ligne, #e2dac6); }

/* ─────────────────────────────── modale ─────────────────────────────── */
.modale {
  position: fixed; inset: 0; background: #000a; display: grid; place-items: center;
  z-index: 50; padding: 20px;
}
.modale-boite {
  background: var(--fond-2); border: 1px solid var(--bord); border-radius: 14px;
  width: min(620px, 100%); max-height: 85dvh; display: flex; flex-direction: column;
  box-shadow: 0 26px 70px #000b;
}
.modale-tete { display: flex; align-items: center; gap: 12px; padding: 15px 18px; border-bottom: 1px solid var(--bord); }
.modale-tete h2 { margin: 0; font-size: 19px; }
.modale-tete button { margin-left: auto; }
.modale-corps { padding: 18px; overflow-y: auto; }
.modale-corps h4 { margin: 16px 0 6px; color: var(--accent); font-size: 14px; }
.modale-corps h4:first-child { margin-top: 0; }
/* CETTE LIGNE DATAIT DU FOND SOMBRE. Un gris très clair sur une carte très
   claire : le détail du score et le résumé de la revue y étaient à la limite du
   lisible. La teinte douce du thème donne 6,8:1. */
.modale-corps p { font-size: 14px; color: var(--texte-doux); }
.modale-corps a { color: var(--accent); }
.modale-corps .verdict { font-size: 18px; font-weight: 650; color: var(--texte); }
.modale-pied { display: flex; gap: 10px; justify-content: flex-end; padding: 14px 18px; border-top: 1px solid var(--bord); }

/* ─────────────────────────── revoir la partie ───────────────────────────
   LE BLOC SE LIT EN MÊME TEMPS QUE LE GOBAN, puisque c'est le goban qui porte
   le coup de KataGo. Il est donc en tête du panneau, encadré, et ses deux
   chiffres sont gros : ce sont eux qu'on vient chercher. */
.bloc-revue { border-color: var(--accent); background: #EEF2F8; }
.revue-tete { display: flex; align-items: baseline; gap: 10px; }
.revue-tete h3 { margin: 0; }
.revue-rang { margin-left: auto; font-size: 12px; color: var(--texte-doux);
  font-variant-numeric: tabular-nums; }
.revue-coup { display: flex; align-items: baseline; gap: 8px; margin: 8px 0 2px; }
.revue-nom { font-size: 26px; font-weight: 700; letter-spacing: -.5px; }
.revue-coup em { font-style: normal; color: var(--texte-doux); font-size: 14px; }
.revue-coup-n { margin-left: auto; font-size: 12px; color: var(--texte-doux); }
.revue-chiffres { display: flex; gap: 22px; margin: 6px 0 10px; }
.revue-chiffres .etiq { display: block; font-size: 11px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--texte-doux); }
.revue-chiffres b { font-size: 20px; font-variant-numeric: tabular-nums; }
.revue-chiffres em { font-style: normal; font-size: 12px; color: var(--texte-doux);
  margin-left: 6px; }
/* TROIS DEGRÉS, ET NON DEUX : au-dessus du seuil c'est un défaut signalé pendant
   la partie, entre deux et le seuil un coup tiède qu'on relit volontiers, en
   dessous rien du tout. Un seul rouge mettrait les trois sur le même plan. */
.revue-chiffres b.cher { color: var(--danger); }
.revue-chiffres b.tiede { color: #8A5A00; }
.revue-chiffres b.gain { color: #2F6B45; }
.revue-chiffres b.rien { color: var(--texte-doux); }
.revue-mieux { margin: 0; font-size: 14px; }
.revue-mieux .meme { color: #2F6B45; }
/* Le même triangle que sur le goban : la phrase et l'intersection se répondent. */
.marque-triangle { color: var(--accent); font-size: 15px; }
.revue-autre { margin: 8px 0; font-size: 14px; color: var(--texte-doux); }
.revue-pas { display: flex; gap: 8px; align-items: center; margin-top: 12px;
  flex-wrap: wrap; }
.revue-pas .btn { flex: 1 1 auto; min-width: 0; }
.revue-pas .pousse { flex-basis: 100%; height: 0; }

/* ───────────────────── téléphones et tablettes ─────────────────────
   Le goban prend tout ce qui reste, le panneau devient une feuille au bas,
   repliable d'un doigt. La tête de cette feuille ne défile pas et n'est pas
   collante : seul le corps défile. */
@media (max-width: 820px) and (min-height: 560px) {
  #plateau { grid-template-columns: 1fr; grid-template-rows: 1fr auto; }
  #panneau { border-left: none; border-top: 1px solid var(--bord); max-height: 40dvh; }
  #panneau.replie { max-height: none; }
  #panneau.replie .corps-panneau { display: none; }
  .corps-panneau { padding-bottom: env(safe-area-inset-bottom); }
  .tete-feuille {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 7px 10px; background: var(--fond-2);
    border-bottom: 1px solid var(--bord); flex: 0 0 auto;
  }
  .poignee {
    width: 40px; min-height: 34px; border: 1px solid var(--bord);
    background: var(--fond-3); border-radius: var(--rayon); cursor: pointer;
    display: grid; place-items: center;
  }
  .poignee::before {
    content: ""; width: 0; height: 0;
    border-left: 6px solid transparent; border-right: 6px solid transparent;
    border-top: 7px solid var(--texte-doux);
  }
  #panneau.replie .poignee::before { border-top: 0; border-bottom: 7px solid var(--texte-doux); }
  #barre { gap: 8px; padding: 8px 10px; padding-top: max(8px, env(safe-area-inset-top)); }
  /* la taille et le komi se lisent sur le goban lui-meme : sur un ecran etroit,
     l'etiquette ne vaut pas la seconde ligne qu'elle fait prendre a la barre */
  #taille-jeu { display: none; }
  .btn-mini { padding: 6px 9px; font-size: 12.5px; }
  .bloc { padding: 11px 13px; }
  .bloc-journal { min-height: 100px; }
  #zone-goban { padding: 4px; gap: 6px; }
  .coup-n { min-width: 66px; font-size: 12px; }
  .annonce { font-size: 13.5px; padding: 8px 14px; top: 8px; }
  .ruban { gap: 4px; }
  /* au doigt, une fleche de 24 px se rate : on leur donne de quoi etre visees,
     le curseur garde le reste. */
  .ruban .btn-mini { padding: 6px 6px; min-width: 34px; min-height: 32px; }
}

@media (max-width: 560px) {
  #ecran-config { padding: 0; place-items: stretch; overflow: hidden; }
  .boite { width: 100%; border: 0; border-radius: 0; box-shadow: none; }
  .boite-tete { padding: 16px; padding-top: max(16px, env(safe-area-inset-top)); }
  .boite-tete h1 { font-size: 23px; }
  .boite-corps { padding: 16px; gap: 14px; }
  .boite-pied { padding: 12px 16px; padding-bottom: max(12px, env(safe-area-inset-bottom)); }
  .boite-pied .btn { flex: 1 1 auto; }
  .champ > label { min-width: 0; flex: 1 0 100%; }
  .segment.large button { min-width: 110px; flex: 1; }
  .modale { padding: 10px; }
  .modale-boite { max-height: 88dvh; }
  .modale-pied { flex-wrap: wrap; }
  .modale-pied .btn { flex: 1 1 auto; }
}

/* RIEN NE ZOOME TOUT SEUL SUR UN ÉCRAN TACTILE. Deux appuis rapprochés sur un
   bouton sont lus par Safari, sur iPhone et iPad, comme un double appui — c'est
   à dire comme un ordre de grossir : le navigateur met alors le BOUTON à la
   largeur de l'écran, et le jeu sort du cadre. Le geste se fait sans y penser
   quand on presse deux fois « Annuler » pour revenir de deux coups en arrière.

   `manipulation` dit au navigateur qu'il n'y a pas de double appui à attendre
   ici : l'appui simple part aussitôt, le défilement reste, et le pincement — le
   zoom VOULU — reste lui aussi. On ne retire que le zoom accidentel, et jamais
   par `user-scalable=no`, qui fermerait les deux.

   Le plateau était protégé depuis longtemps ; les commandes ne l'étaient pas.
   La propriété ne s'hérite pas — le navigateur croise celle de la cible avec
   celle de ses ancêtres, de sorte que la première ligne suffirait —, mais on la
   redit sur les commandes : c'est là que le geste a lieu, et la protection ne
   doit pas dépendre d'un ancêtre qui changerait d'avis. */
html, body { touch-action: manipulation; }
button, select, input, textarea, a, label, summary { touch-action: manipulation; }

/* ET RIEN NE ZOOME NON PLUS EN ENTRANT DANS UN CHAMP : sous seize pixels,
   Safari grossit la page dès qu'un `input`, un `select` ou un `textarea` prend
   le focus — il rend le texte lisible — et il ne la redescend pas en sortant.
   Même symptôme que le double appui, autre cause. Seize pixels sur les écrans
   tactiles SEULEMENT : à la souris, les commandes restent discrètes.

   Mesuré avant d'être posé, sur l'écran d'un téléphone : aucun champ du site ne
   dépassait seize pixels — la règle ne rétrécit donc rien —, et aucune page ne
   déborde. */
@media (pointer: coarse) {
  input, select, textarea { font-size: 16px; }
}
