/* Sésame — la feuille de style.
   Copyright (c) 2026 Tristan Cazenave. Tous droits réservés — voir LICENSE.

   PAS D'IMAGES. Une case est un carré, le clavier des rectangles, et tout
   tient dans `--c`, la taille d'une case : la grille se met à l'échelle en
   changeant un seul nombre.

   La palette est celle de Sokoban et de Déboîter — qui passe de l'un à
   l'autre doit se sentir chez lui. Trois couleurs s'ajoutent, et ce sont
   elles qui font le jeu : le vert de la lettre bien placée, l'or de celle qui
   est ailleurs, le gris de celle qui n'y est pas. Le vert est celui des
   « gagné » du site, et l'or tranche avec lui même pour un œil qui confond le
   rouge et le vert — la forme de la grille, elle, ne dépend pas des
   couleurs : une lettre placée reste à sa place. */

:root {
  color-scheme: light dark;
  --fond: #f4f1ea; --surface: #fffdf8; --surface-2: #efeadf;
  --ink: #1d2126; --ink-2: #4a525c; --ink-3: #7b838d; --line: #d9d2c5;
  --accent: #2c4e7e; --accent-2: #24406a; --bad: #a6402f; --bon: #2f6b45;
  --place: #2f6b45; --place-haut: #3d8456;
  --ailleurs: #c8a33a; --ailleurs-haut: #d9b64f;
  --absent: #9a9488; --absent-haut: #a8a296;
  --case-vide: #e6dfd0;
}
@media (prefers-color-scheme: dark) {
  :root {
    --fond: #14171b; --surface: #1c2026; --surface-2: #242932;
    --ink: #e8eaed; --ink-2: #b3bac3; --ink-3: #868e98; --line: #333a44;
    --accent: #7aa2d6; --accent-2: #9dbce5; --bad: #e08b7c; --bon: #7fc79c;
    --place: #2f6b45; --place-haut: #3d8456;
    --ailleurs: #a9872c; --ailleurs-haut: #bb9a3d;
    --absent: #4a5159; --absent-haut: #565e67;
    --case-vide: #2a2f36;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--fond); color: var(--ink);
  font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
  padding-bottom: env(safe-area-inset-bottom);
}
.page { max-width: 1060px; margin: 0 auto; padding: 10px 12px 28px; }

/* RIEN NE ZOOME TOUT SEUL SUR UN ÉCRAN TACTILE. Deux appuis rapprochés sur un
   bouton — et ce jeu-ci se joue au clavier de l'écran, c'est-à-dire par appuis
   rapprochés sur des boutons — 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 la grille sort du cadre. Le
   joueur perd sa partie des yeux au moment précis où il tapait.

   `manipulation` dit au navigateur de n'attendre aucun double appui ici :
   l'appui simple part aussitôt — il ne traîne plus les trois cents
   millisecondes de l'attente, ce qui rend le clavier nettement plus vif —, le
   défilement reste, et le pincement, qui est le zoom VOULU, reste aussi. On ne
   retire que le zoom accidentel. Jamais `user-scalable=no` dans l'en-tête :
   cela retirerait les deux. */
html, body { touch-action: manipulation; }
/* `touch-action` ne s'hérite pas : le navigateur croise celui de la cible avec
   celui de ses ancêtres, et la ligne du dessus suffirait donc. On le redit
   néanmoins sur les commandes elles-mêmes — c'est là que le geste a lieu, et
   la protection ne doit pas dépendre d'un ancêtre qui changerait d'avis. */
button, select, input, textarea, a, label, summary { touch-action: manipulation; }

header.tete { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.pousse { margin-left: auto; }

.langues {
  display: inline-flex; border: 1px solid var(--line); border-radius: 999px;
  overflow: hidden; background: var(--surface);
}
.langues button {
  font: inherit; font-size: 13px; line-height: 1; padding: 6px 10px;
  border: 0; background: none; color: var(--ink-2); cursor: pointer;
}
.langues button + button { border-left: 1px solid var(--line); }
.langues button[aria-pressed="true"] { background: var(--accent); color: #fff; }

.btn {
  font: inherit; font-size: 14px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: 9px; padding: 7px 12px; cursor: pointer;
}
.btn:hover:not(:disabled) { background: var(--surface-2); border-color: var(--accent); }
.btn:disabled { opacity: .45; cursor: default; }
.btn.primaire { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn[aria-selected="true"] { background: var(--accent); color: #fff; border-color: var(--accent); }

.modes { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.modes[hidden] { display: none; }

.titre-jeu { font-size: 19px; margin: 6px 2px 2px; font-weight: 600; }
.sous-jeu { font-size: 13.5px; color: var(--ink-3); margin: 0 2px 10px; max-width: 60ch; }
.rituel {
  margin: 0 2px 10px; font-size: 13.5px; color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.rituel[hidden] { display: none; }

/* L'invitation à se connecter : visible, mais pas criarde. */
.invite {
  margin: 0 0 10px; padding: 9px 12px; font-size: 13.5px; color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: 9px;
  max-width: 62ch;
}
.invite[hidden] { display: none; }
.invite a { color: var(--accent); font-weight: 600; }
.invite .ligne { display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-top: 8px; }
.invite input {
  font: inherit; font-size: 14px; color: var(--ink); background: var(--fond);
  border: 1px solid var(--line); border-radius: 9px; padding: 7px 10px;
  min-width: 10ch; flex: 0 1 18ch;
}
.invite .apres { font-size: 13px; color: var(--ink-3); }
.invite .mauvais { color: var(--bad); }
.invite .bon { color: var(--bon); font-weight: 600; }

/* ------------------------------------------------------------------ le jeu */

.jeu { display: flex; gap: 26px; align-items: flex-start; flex-wrap: wrap; }
/* `min-width: 0` N'EST PAS DÉCORATIF. Sans lui, un enfant de flex ne descend
   pas sous sa largeur de contenu : la phrase de victoire — « Trouvé du premier
   coup : « … ». Huit points. Vous avez égalé le solveur… » — tient sur une
   ligne de mille cinquante pixels, la colonne du jeu prenait cette largeur-là,
   et la page débordait de son cadre sur un téléphone. Mesuré : 1 059 pixels
   dans une fenêtre de 390. C'est un harnais qui l'a vu, pas l'œil — sur un
   écran large, rien ne paraissait. */
.plateau { flex: 1 1 330px; min-width: 0; max-width: 100%; }

/* LA GRILLE PREND LA PLACE QU'IL Y A : la case est la plus petite de trois
   contraintes — la largeur qui reste à côté des tableaux, la hauteur qui reste
   sous l'en-tête et au-dessus du clavier, et un plafond, sans lequel six
   rangées de cinq cases deviendraient un mur. */
.grille {
  --c: clamp(38px, min((100vw - 400px) / 5.6, (100vh - 420px) / 6.4), 62px);
  display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px;
}
.rangee { display: flex; gap: 6px; }
.case {
  width: var(--c); height: var(--c);
  display: flex; align-items: center; justify-content: center;
  font-size: calc(var(--c) * .52); font-weight: 700; line-height: 1;
  color: var(--ink);
  background: var(--case-vide);
  border: 1px solid var(--line); border-radius: 7px;
  font-variant-numeric: tabular-nums;
}
/* La case où l'on tape : un trait d'accent, pour qu'on voie où l'on en est. */
.case.tapee { border-color: var(--accent); }
.case.place, .case.ailleurs, .case.absent {
  color: #fff; border-color: transparent;
}
.case.place { background: linear-gradient(160deg, var(--place-haut), var(--place)); }
.case.ailleurs { background: linear-gradient(160deg, var(--ailleurs-haut), var(--ailleurs)); }
.case.absent { background: linear-gradient(160deg, var(--absent-haut), var(--absent)); }

/* ── LE CLAVIER ──────────────────────────────────────────────────────────── */

.clavier { display: flex; flex-direction: column; gap: 6px; max-width: 520px; }
.rangee-clavier { display: flex; gap: 5px; justify-content: center; }
.touche {
  font: inherit; font-size: 15px; font-weight: 600; line-height: 1;
  flex: 1 1 0; min-width: 0; padding: 12px 2px; cursor: pointer;
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: 7px;
}
.touche.large { flex: 1.6 1 0; font-size: 17px; }
.touche:hover:not(:disabled) { border-color: var(--accent); }
.touche.place { background: var(--place); color: #fff; border-color: transparent; }
.touche.ailleurs { background: var(--ailleurs); color: #fff; border-color: transparent; }
.touche.absent { background: var(--absent); color: #fff; border-color: transparent; opacity: .75; }
.trou { flex: .5 1 0; }

.dit { min-height: 1.5em; margin: 6px 2px 10px; font-size: 14.5px;
       color: var(--ink-2); max-width: 44ch; }
.dit.bon { color: var(--bon); font-weight: 600; }
.dit.mauvais { color: var(--bad); }

/* ------------------------------------------------- les tableaux d'honneur */

.cote { flex: 1 1 300px; min-width: 260px; }
.cote[hidden] { display: none; }
.cote h2 { font-size: 16px; margin: 0 0 6px; }
.cote > div + div { margin-top: 18px; }
.cote > div[hidden] { display: none; }
.note { font-size: 13.5px; color: var(--ink-3); margin: 6px 0; }

.tableau { list-style: none; counter-reset: rang; margin: 0; padding: 0; }
.tableau li {
  counter-increment: rang;
  display: flex; align-items: baseline; gap: 8px;
  padding: 5px 8px; border-bottom: 1px solid var(--line); font-size: 14px;
}
.tableau li::before {
  content: counter(rang) '.'; color: var(--ink-3); min-width: 1.6em;
  font-variant-numeric: tabular-nums;
}
.tableau li.moi { background: var(--surface-2); border-radius: 6px; }
.tableau .nom { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tableau .score { margin-left: auto; white-space: nowrap; }

/* ── LA FIN, LE PARTAGE, LA LEÇON ───────────────────────────────────────── */

.attente {
  margin: 10px 0 0; padding: 10px 14px; font-size: 14px;
  background: var(--surface); border: 1px solid var(--accent); border-radius: 12px;
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap; max-width: 460px;
}
.attente[hidden] { display: none; }

.fin {
  margin: 14px 0 0; padding: 14px 16px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  max-width: 520px;
}
.fin[hidden] { display: none; }
.fin h2 { margin: 0 0 2px; font-size: 19px; color: var(--bon); }
.fin .fin-mot { margin: 0; font-size: 15px; color: var(--ink); }
.fin .fin-score { margin: 8px 0 0; font-size: 15px; color: var(--ink-2); }
.fin .fin-serie { margin: 10px 0 0; font-size: 14.5px; color: var(--ink-2); font-weight: 600; }
.fin p { margin: 6px 0 0; }
.fin .apres { font-size: 13px; color: var(--ink-3); margin-left: 8px; }
.fin .apres.bon { color: var(--bon); }
.fin .apres.mauvais { color: var(--bad); }
/* Le ruban est en chasse fixe : les carrés doivent s'aligner en colonnes,
   sinon il ne ressemble à rien une fois collé ailleurs. */
.ruban {
  margin: 10px 0 0; font: 17px/1.25 ui-monospace, "Segoe UI Emoji", monospace;
  letter-spacing: 1px; white-space: pre-wrap; word-break: break-all;
}
.ruban:empty { display: none; }

.lecon { margin: 12px 0 0; }
.lecon[hidden] { display: none; }
.lecon summary {
  cursor: pointer; font-size: 14.5px; font-weight: 600; color: var(--accent);
}
.lecon .deux { display: flex; gap: 24px; flex-wrap: wrap; margin-top: 8px; }
.lecon h4 { margin: 0 0 4px; font-size: 13px; color: var(--ink-3); font-weight: 600; }
.lecon .coups { list-style: none; margin: 0; padding: 0; counter-reset: c; }
.lecon .coups li {
  counter-increment: c; font-size: 14px; display: flex; gap: 8px;
  align-items: baseline;
}
.lecon .coups li::before {
  content: counter(c) '.'; color: var(--ink-3); min-width: 1.4em;
  font-variant-numeric: tabular-nums; font-size: 12.5px;
}
.lecon code { font: 14px/1.5 ui-monospace, monospace; letter-spacing: .08em; }
.lecon .reste { color: var(--ink-3); font-size: 13px; font-variant-numeric: tabular-nums; }

.modale {
  position: fixed; inset: 0; background: rgba(10, 12, 16, .55);
  display: flex; align-items: center; justify-content: center; padding: 16px; z-index: 100;
}
.modale[hidden] { display: none; }
.boite {
  background: var(--surface); color: var(--ink); border: 1px solid var(--line);
  border-radius: 14px; padding: 20px; max-width: 560px; width: 100%;
  max-height: 84vh; overflow: auto;
}
.boite h2 { margin: 0 0 4px; font-size: 19px; }
.boite h3 { margin: 16px 0 4px; font-size: 15px; color: var(--ink-2); }
.boite p { margin: 4px 0; font-size: 14.5px; color: var(--ink-2); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.cache { display: none !important; }

@media (max-width: 860px) {
  /* Les tableaux passent dessous : toute la largeur revient à la grille et au
     clavier, qui sont le jeu. */
  .grille { --c: clamp(40px, min((100vw - 60px) / 5.4, (100vh - 400px) / 6.4), 62px); }
  .jeu { gap: 18px; }
  .clavier { max-width: none; }
}
/* SUR UN TÉLÉPHONE, LA GRILLE ET LE CLAVIER DOIVENT TENIR ENSEMBLE À L'ÉCRAN.
   C'est la seule exigence de mise en page de ce jeu, et elle n'est pas de
   goût : on regarde ce qu'on a trouvé et l'on tape dans le même mouvement, et
   faire défiler entre les deux à chaque lettre rendrait le jeu pénible.
   Mesuré sur 390 × 844 points — un iPhone courant : tout ce qui précède la
   grille a été resserré jusqu'à ce que le bas du clavier passe au-dessus de la
   ligne de flottaison, et le harnais le vérifie à chaque exécution. */
@media (max-width: 520px) {
  .page { padding: 6px; }
  .langues button { font-size: 12px; padding: 5px 7px; }
  .btn { font-size: 13px; padding: 6px 9px; }
  .modes { gap: 6px; margin-bottom: 8px; }
  .titre-jeu { font-size: 16px; margin: 4px 2px 0; }
  .sous-jeu { font-size: 12.5px; margin-bottom: 6px; }
  .invite { font-size: 12.5px; padding: 7px 10px; margin-bottom: 8px; }
  .rituel { font-size: 12.5px; margin-bottom: 6px; }
  .grille {
    /* Le plafond est tombé de 56 à 52 pixels le jour où le bloc du compte a
       posé son lien dans l'en-tête : une rangée de plus en haut, et le bas du
       clavier passait à 845 pour un écran de 844. Le harnais l'a vu au pixel
       près. Le terme en `100vh` fait le reste sur les écrans plus courts. */
    --c: clamp(34px, min((100vw - 56px) / 5.4, (100vh - 400px) / 6.4), 52px);
    gap: 5px; margin-bottom: 6px;
  }
  .rangee { gap: 5px; }
  .dit { margin: 3px 2px 5px; font-size: 13.5px; min-height: 1.2em; }
  .touche { padding: 9px 2px; font-size: 14px; }
  .touche.large { font-size: 15px; }
}

/* ET RIEN NE ZOOME NON PLUS EN ENTRANT DANS UN CHAMP : sous seize pixels,
   Safari grossit la page dès qu'un `input` 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. */
@media (pointer: coarse) {
  input, select, textarea { font-size: 16px; }
  /* Ce champ-là tient sa taille d'une règle plus précise — la ligne du dessus
     perdrait la cascade sans le nommer. */
  .invite input { font-size: 16px; }
}
