/* sutomotus.css - toute la mise en forme du jeu.
 *
 * Ecrite a la main, servie telle quelle : ni preprocesseur, ni framework, ni
 * etape de construction. C'est le choix de la note de conception, et il tient a
 * une raison simple - une feuille de style qu'on peut ouvrir et lire dans le
 * navigateur est une feuille qu'on peut corriger un soir sans rien reinstaller.
 *
 * La palette est celle de la page de chantier de la livraison 0 : le site ne
 * change pas d'apparence en devenant jouable.
 */

:root {
  --nuit: #0B1020;
  --carte: #141A2E;
  --texte: #E8ECF8;
  --texte-2: #9AA3C0;
  --texte-3: #6B7395;
  --trait: rgba(255, 255, 255, .09);
  --voile: rgba(255, 255, 255, .05);

  /* LES TROIS COULEURS DU JEU, ET RIEN D'AUTRE NE DOIT LES REDEFINIR.
     Bien placee, mal placee, absente. Elles servent a la grille, au clavier et
     a la repartition : trois endroits qui doivent dire la meme chose de la
     meme facon, sans quoi le joueur croit a deux informations differentes. */
  --bien: #2E6FF2;
  --present: #F2A03D;
  --absent: #3A4160;

  --vert: #34D399;
  --rouge: #F2555A;

  /* LES RESEAUX PORTENT LEUR PROPRE COULEUR, pas une teinte du jeu. Une marque
     se reconnait d'abord a sa couleur, et un pictogramme monochrome au milieu de
     quatre autres ne se distingue plus. Le partage systeme et la copie, eux,
     n'appartiennent a personne : ils gardent les teintes du jeu. */
  --bluesky: #1185FE;
  --x: #E7E9EA;
  --mastodon: #6364FF;
  --doux: cubic-bezier(.2, .7, .3, 1);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: radial-gradient(ellipse at 40% 0%, #131A31, #0B1020 70%);
  background-attachment: fixed;
  color: var(--texte);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  line-height: 1.5;
  /* Le jeu se joue au clavier, y compris virtuel : une selection de texte
     accidentelle sur telephone fait apparaitre la loupe de copie au milieu
     d'une partie. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;

  /* DEUX APPUIS RAPIDES NE DOIVENT PAS ZOOMER.
     Sur iPhone, un double appui rapproche la page. C'est utile sur un article,
     c'est une plaie dans un jeu : effacer trois lettres de suite, c'est trois
     appuis sur la meme touche en une seconde - et l'iPhone comprend « zoomer
     ici ». Le joueur se retrouve avec une grille agrandie de travers au milieu
     d'une partie, et doit pincer pour revenir.
     `manipulation` conserve le defilement et le pincement - on ne retire que
     le double appui, qui n'a aucun usage ici.
     C'est la bonne facon de le faire : `user-scalable=no` dans le viewport
     interdirait AUSSI le pincement, ce qui rendrait le jeu inutilisable a qui a
     besoin d'agrandir pour lire. iOS l'ignore d'ailleurs depuis longtemps,
     precisement pour cette raison. */
  touch-action: manipulation;
}

/* La page tient en une hauteur d'ecran : grille au centre, clavier en bas.
   `100dvh` et non `100vh` - sur telephone, `vh` compte la barre d'adresse
   comme si elle n'existait pas, et le clavier virtuel passait sous l'ecran. */
main {
  min-height: 100dvh;
  max-width: 34rem;
  margin: 0 auto;
  padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ------------------------------------------------------------- en-tete */

/* L'en-tete est construit par sutomotus.js ; ses styles sont plus bas, avec le
   menu. Ici, seulement ce qui appartient a la page de jeu. */

h1 {
  font-size: 1.15rem;
  font-weight: 800;
  letter-spacing: -.02em;
  margin: 0;
}
h1 a { color: inherit; text-decoration: none; }

.entrainement {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  background: rgba(242, 160, 61, .16);
  color: var(--present);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
}

/* -------------------------------------------------------------- grille */

.plateau {
  flex: 1;
  display: grid;
  place-items: center;
  min-height: 0;
}

/* La taille d'une case se calcule, elle ne se choisit pas.
   Neuf colonnes sur un telephone de 360 px, c'est 34 px par case : ecrire
   « 48px » en dur donnait une grille plus large que l'ecran, et le mot de neuf
   lettres - le plus difficile - devenait le seul illisible. */
.grille {
  --espace: 6px;
  --taille: min(52px, calc((min(100vw, 34rem) - 24px - (var(--colonnes) - 1) * var(--espace)) / var(--colonnes)));
  display: grid;
  grid-template-columns: repeat(var(--colonnes), var(--taille));
  gap: var(--espace);
  justify-content: center;
}

.case {
  width: var(--taille);
  height: var(--taille);
  display: grid;
  place-items: center;
  border: 2px solid var(--trait);
  border-radius: 8px;
  background: var(--voile);
  font-size: calc(var(--taille) * .52);
  font-weight: 800;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  transition: transform .12s var(--doux), border-color .12s var(--doux);
}

/* Une lettre qu'on vient de taper : le retour visuel remplace le clic sonore
   d'un vrai clavier, absent sur telephone. */
.case.pleine { border-color: var(--texte-3); animation: pousser .12s var(--doux); }
@keyframes pousser { 50% { transform: scale(1.06); } }

/* Les lettres reportees de la ligne precedente. Elles sont deja bleues : ce
   sont des positions acquises, et les afficher en gris ferait croire qu'elles
   sont a retrouver. */
.case.report { background: color-mix(in srgb, var(--bien) 26%, transparent); border-color: var(--bien); }

.case.bien    { background: var(--bien);    border-color: var(--bien);    color: #fff; }
.case.present { background: var(--present); border-color: var(--present); color: #14161F; }
.case.absent  { background: var(--absent);  border-color: var(--absent);  color: var(--texte-2); }

/* ------------------------------------------------------- volets d'aeroport */

/* UNE CASE QUI CHERCHE SA LETTRE.
   L'ancienne animation faisait pivoter la case sur son axe : propre, et muette.
   Un panneau a volets RACONTE une recherche - les lettres defilent, on voit la
   machine chercher, puis elle s'arrete.

   Pendant le defile, la case reste NEUTRE : fond sourd, bordure claire, aucune
   couleur de jeu. La couleur n'arrive qu'a l'arret du volet, sinon elle
   vendrait la reponse avant la fin du geste. */
.case.volet {
  background: rgba(255, 255, 255, .07);
  border-color: var(--texte-3);
  color: var(--texte-2);
  position: relative;
  overflow: hidden;
}

/* LA FENTE HORIZONTALE, au milieu de la case : c'est elle qui fait lire un
   panneau mecanique plutot qu'un texte qui clignote. */
.case.volet::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: rgba(0, 0, 0, .38);
  z-index: 2;
}

.case.volet .lettre {
  display: block;
  /* Plus courte que le pas de 46 ms : au-dela, un volet serait encore en train
     de tomber quand le suivant part, et le mouvement se brouille. */
  animation: volet .07s var(--doux);
  /* Le volet bascule depuis le HAUT, comme une palette qui retombe. La
     perspective est dans la transformation elle-meme : declaree sur le parent,
     elle s'appliquerait a toute la grille. */
  transform-origin: center top;
  will-change: transform;
}

@keyframes volet {
  0%   { transform: perspective(160px) rotateX(-78deg); opacity: .35; }
  100% { transform: perspective(160px) rotateX(0deg);   opacity: 1; }
}

/* Le volet s'arrete : la case se pose, avec un choc tres court. C'est lui qui
   donne l'impression d'une mecanique plutot que d'un fondu. */
.case.posee { animation: poser .17s var(--doux); }
@keyframes poser {
  0%   { transform: translateY(-2px) scaleY(.94); }
  60%  { transform: translateY(0) scaleY(1.03); }
  100% { transform: none; }
}

/* Un mot refuse secoue la ligne SANS l'effacer : le joueur corrige une lettre
   au lieu de tout retaper. Effacer sa saisie a chaque refus est la facon la
   plus sure de le faire abandonner. */
.ligne-refusee { animation: secouer .3s var(--doux); }
@keyframes secouer {
  10%, 90% { transform: translateX(-2px); }
  30%, 70% { transform: translateX(4px); }
  50%      { transform: translateX(-4px); }
}

/* ------------------------------------------------------------- message */

.message {
  min-height: 1.6rem;
  text-align: center;
  font-size: .9rem;
  color: var(--present);
  font-weight: 600;
}
.message:empty { visibility: hidden; }

/* ------------------------------------------------------------- clavier */

.clavier { display: grid; gap: 6px; }
.rangee { display: flex; gap: 5px; justify-content: center; }

.touche {
  flex: 1 1 auto;
  min-width: 0;
  height: 50px;
  border: 1px solid var(--trait);
  border-radius: 7px;
  background: #262C44;
  color: var(--texte);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  transition: transform .08s var(--doux), background .18s var(--doux);
  /* Repete ici, et pas seulement sur `body` : `touch-action` ne s'herite pas,
     et d'anciennes versions de WebKit ne consultent que l'element touche. */
  touch-action: manipulation;
  /* Un appui long sur une touche ouvrait le menu « Copier / Rechercher ». */
  -webkit-touch-callout: none;
}
.touche:active { transform: translateY(1px); }
.touche.large { flex: 1.6 1 auto; font-size: .8rem; letter-spacing: .02em; }

.touche.bien    { background: var(--bien);    border-color: var(--bien);    color: #fff; }
.touche.present { background: var(--present); border-color: var(--present); color: #14161F; }
.touche.absent  { background: var(--absent);  border-color: var(--absent);  color: var(--texte-3); }

/* --------------------------------------------------------------- confettis */

/* Le canevas couvre l'ecran ENTIER et laisse tout passer : il est pose
   au-dessus de l'ecran de fin - qui est en z-index 40 - pour que les carres
   tombent devant le panneau et non derriere. `pointer-events: none` est ce qui
   rend le bouton de partage cliquable pendant qu'ils tombent. */
.confettis {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
}

/* ------------------------------------------------------------ fin de partie */

/* C'EST LE VOILE QUI DEFILE, PLUS LA BOITE.
   La boite portait `max-height: 88dvh` et son propre defilement. Sur un
   navigateur de bureau ou `dvh` ne vaut pas ce qu'on croit - fenetre
   redimensionnee, barre d'outils, zoom - la contrainte tombait a cote et le
   panneau depassait de l'ecran, coupe en bas.
   `flex` plus `margin: auto` sur l'enfant : centre quand ca tient, defile sans
   rien couper quand ca ne tient pas. C'est la seule combinaison qui ne rogne
   pas le haut du panneau, `place-items: center` le faisant deborder par les
   deux bouts. */
.fin {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  padding: 18px;
  background: color-mix(in srgb, var(--nuit) 90%, transparent);
  backdrop-filter: blur(6px);
  animation: paraitre .2s var(--doux);
}
.fin[hidden] { display: none; }
@keyframes paraitre { from { opacity: 0; } to { opacity: 1; } }

/* LA BARRE DE DEFILEMENT NE DOIT PAS SE VOIR, ET LE DEFILEMENT DOIT RESTER.
   Ce sont deux choses differentes, et il faut les deux. Cet ecran arrive au
   moment ou le joueur vient de gagner : une barre grise en travers du panneau
   le fait paraitre trop plein, alors qu'il tient presque toujours en entier.
   « Presque » : sur un petit ecran en paysage, ou avec une grille de six
   essais, il deborde reellement. Supprimer `overflow` rendrait alors le bouton
   de partage inatteignable - on cache la barre, on ne coupe pas le defilement.
   `scrollbar-width` couvre Firefox, le pseudo-element couvre WebKit. */
.fin-boite {
  width: min(26rem, 100%);
  margin: auto;
  background: var(--carte);
  border: 1px solid var(--trait);
  border-radius: 18px;
  padding: 22px;
  text-align: center;
  /* Le texte de l'ecran de fin se selectionne : on veut pouvoir copier le mot
     pour le chercher dans un dictionnaire. */
  -webkit-user-select: text;
  user-select: text;
}

/* WebKit : la barre disparait sans que le defilement ne bouge. */
.fin::-webkit-scrollbar { width: 0; height: 0; }

/* LA LARGEUR SERT A GAGNER DE LA HAUTEUR.
   Des qu'il y a la place, la repartition et les carres se rangent cote a cote
   et le panneau perd pres de deux cents pixels. Le seuil est exprime en
   largeur ET en hauteur : sur un ecran large mais bas - un portable pose sur
   un bureau -, c'est precisement la ou la hauteur manque. */
.fin-corps { display: grid; gap: 4px; }

@media (min-width: 40rem) {
  .fin-boite { width: min(40rem, 100%); }
  .fin-corps {
    grid-template-columns: 1fr 1fr;
    gap: 22px;
    align-items: center;
  }
  .repartition { margin: 10px 0; }
}

.fin h2 { margin: 0 0 4px; font-size: 1.3rem; font-weight: 800; }
.fin .mot {
  display: inline-block;
  margin: 6px 0 12px;
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: .12em;
  color: var(--bien);
}
.fin .perdu .mot { color: var(--rouge); }
.fin .points { font-size: .95rem; color: var(--texte-2); margin: 0 0 12px; }
.fin .points strong { color: var(--texte); font-size: 1.1rem; }

/* -------------------------------------------------------- repartition */

/* Resserre : la repartition, le partage et les boutons occupaient a eux trois
   plus d'un ecran de telephone. Rien n'est retire, tout est rapproche. */
.repartition { text-align: left; margin: 14px 0; }
.repartition h3 {
  font-size: .74rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--texte-3);
  margin: 0 0 10px;
  font-weight: 700;
}
.barre-ligne {
  display: grid;
  grid-template-columns: 1.2rem 1fr;
  gap: 8px;
  align-items: center;
  margin-bottom: 3px;
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
}
.barre {
  background: var(--absent);
  border-radius: 4px;
  padding: 2px 7px;
  color: var(--texte-2);
  /* Une barre a zero garde une largeur minimale : sans elle, les colonnes
     vides disparaissent, la repartition change de forme d'un jour a l'autre,
     et l'on ne peut plus comparer sa journee d'hier a celle d'aujourd'hui. */
  min-width: 2.2rem;
  text-align: right;
  transition: width .5s var(--doux);
}
.barre.moi { background: var(--bien); color: #fff; font-weight: 700; }

/* --------------------------------------------------------------- boutons */

/* ------------------------------------------------------ les deux suites */

/* DEUX CHOIX AU MEME RANG.
   Garder trace pour soi, ou rendre public : ce sont deux facons de repondre a
   la meme envie, et aucune ne doit avoir l'air d'etre celle qu'on attend du
   joueur. Meme dessin, meme taille, aucune des deux mise en avant. */
.apres { margin: 14px 0 4px; text-align: left; }
.apres[hidden] { display: none; }

.apres-titre {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 10px;
  color: var(--texte-3);
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .1em;
}
.apres-titre .fil { flex: 1; height: 1px; background: var(--trait); }

.route {
  display: block;
  width: 100%;
  margin-bottom: 7px;
  padding: 12px 14px;
  border: 1px solid var(--trait);
  border-radius: 12px;
  background: var(--voile);
  color: var(--texte);
  font-family: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  transition: background .18s var(--doux), border-color .18s var(--doux);
}
.route:hover { background: rgba(255,255,255,.09); border-color: rgba(255,255,255,.2); }
.route[disabled] { opacity: .6; cursor: default; }

.route-titre { display: block; font-size: .95rem; font-weight: 700; }
.route-detail {
  display: block;
  margin-top: 3px;
  font-size: .78rem;
  line-height: 1.45;
  color: var(--texte-2);
}

/* Une fois la publication activee, la route prend la couleur du jeu : elle
   n'est plus une proposition, elle est un etat. */
.route.faite { border-color: var(--bien); background: rgba(46,111,242,.12); }
.route.faite .route-titre { color: var(--bien); }

.boutons { display: grid; gap: 7px; margin-top: 6px; }
.boutons-paire { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }

/* `.action` ET NON `button.action`, ET C'EST UNE CORRECTION.
   Le selecteur portait sur l'element : un lien presente comme un bouton -
   « Journées passées », « Mes statistiques » - n'heritait donc d'AUCUNE de ces
   regles. Il gardait les couleurs de lien du navigateur, et virait au violet
   une fois visite. Le defaut ne se voyait qu'apres avoir clique, ce qui est la
   pire facon de le decouvrir. */
.action {
  display: block;
  width: 100%;
  padding: 12px 16px;
  border: 0;
  border-radius: 11px;
  background: var(--bien);
  color: #fff;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.4;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-touch-callout: none;
}
.action.secondaire { background: var(--voile); color: var(--texte); border: 1px solid var(--trait); }

/* UN LIEN N'EST PAS UN BOUTON, ET LA COULEUR LE DIT.
   Un bouton agit sur ce qu'on a sous les yeux ; un lien emmene ailleurs. Les
   deux se ressemblent trop dans cet ecran de fin de partie pour qu'on les
   distingue par la forme seule. L'orange du jeu - celui des lettres mal
   placees - marque donc ce qui fait quitter la page.
   Les regles precedentes ne suffisent pas : `:visited` de l'agent utilisateur
   l'emporterait sinon sur la couleur heritee. */
a.action, a.action:visited { color: var(--present); }
a.action.secondaire, a.action.secondaire:visited { color: var(--present); }

.action:active { transform: translateY(1px); }

.carres {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.05rem;
  line-height: 1.15;
  letter-spacing: .06em;
  margin: 10px 0;
  white-space: pre;
}

.note { color: var(--texte-3); font-size: .8rem; margin: 12px 0 0; }
.note a { color: var(--texte-2); }

/* ----------------------------------------------------------- animations */

/* Certains joueurs regardent leur telephone en marchant, d'autres ont le mal
   des transports. Le systeme le sait, on l'ecoute. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ------------------------------------------------------------------ */
/* En-tete et menu                                                     */
/* ------------------------------------------------------------------ */

.entete-barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 2px 12px;
  /* Un trait plutot qu'une boite : l'en-tete se separe du jeu sans rien
     ajouter a l'ecran. */
  border-bottom: 1px solid var(--trait);
}

/* LE TITRE EST UN TITRE, PAS UNE LEGENDE.
   Il occupe sa ligne avec le bouton du menu, et rien d'autre. */
.marque {
  display: flex;
  align-items: center;
  gap: 13px;
  color: var(--texte);
  text-decoration: none;
  white-space: nowrap;
}

/* Le mot lui-meme : gros, serre, et coupe en TROIS a l'endroit ou Sutom et
   Motus s'emboitent. Le M bleu est la lettre commune aux deux noms ; il se
   detache des deux cotes, et l'on lit Sutom puis Motus sans qu'un mot
   d'explication soit necessaire. C'est la seule fantaisie de cette barre. */
.mot-marque {
  font-size: clamp(1.7rem, 8vw, 2.4rem);
  font-weight: 800;
  letter-spacing: -.045em;
  line-height: 1;
}
.pivot-marque { color: var(--bien); }
.fin-marque { color: var(--present); }

/* LA SIGNATURE : TROIS CARRES, BLEU, ORANGE, GRIS.
   Ce ne sont pas trois carres decoratifs - ce sont les trois etats d'une lettre,
   le seul vocabulaire du jeu, et exactement ce que le joueur partage a la fin
   d'une partie. Ils servent de marque, de bouton de menu et de puce. */
/* EMPILES EN COLONNE, PAS EN RANGEE. Trois carres cote a cote se lisent comme
   des puces decoratives ; empiles a cote du mot, ils forment trois lignes de
   grille - la forme meme d'une partie. Le bouton du menu, lui, garde la
   colonne : c'est le meme objet, vu autrement. */
.carres-marque { display: inline-flex; flex-direction: column; gap: 3px; }
.carres-marque i { width: 13px; height: 13px; border-radius: 3px; }
.carres-marque i.bien { background: var(--bien); }
.carres-marque i.present { background: var(--present); }
.carres-marque i.absent { background: var(--absent); }

/* La journee, sur sa propre ligne, alignee sous la marque. Elle tient
   desormais d'un seul tenant, quelle que soit la longueur du mot. */
.entete-info {
  padding: 5px 2px 2px;
  color: var(--texte-2);
  font-size: .9rem;
  font-variant-numeric: tabular-nums;
}
.entete-info:empty { display: none; }

/* Les deux boutons de la barre, groupes a droite. */
.entete-outils { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

/* LE BOUTON DU SON EST ETEINT PAR DEFAUT, ET SE VOIT ETEINT.
   Barre et gris, il annonce ce qu'il est - pas ce qu'il ferait. Allume, il
   prend le bleu du jeu : la difference se lit d'un coup d'oeil, sans avoir a
   dechiffrer une icone. */
.bouton-son {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border: 1px solid var(--trait);
  border-radius: 11px;
  background: var(--voile);
  color: var(--texte-3);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  transition: background .18s var(--doux), color .18s var(--doux),
              border-color .18s var(--doux);
}
.bouton-son svg { width: 20px; height: 20px; display: block; }
.bouton-son:hover { background: rgba(255,255,255,.09); }
.bouton-son.allume {
  color: var(--bien);
  border-color: rgba(46,111,242,.45);
  background: rgba(46,111,242,.14);
}

/* Le bouton du menu reprend les memes carres, empiles. Ouvert, ils pivotent :
   un seul mouvement, pas une croix dessinee par-dessus. */
.burger {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border: 1px solid var(--trait);
  border-radius: 11px;
  background: var(--voile);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  transition: background .18s var(--doux);
}
.burger:hover { background: rgba(255,255,255,.09); }
.burger .carres-marque {
  gap: 3px;
  transition: transform .26s var(--doux);
}
/* LE TROISIEME TRAIT EST ECLAIRCI, ET C'EST UNE CORRECTION.
   `--absent` est le gris des lettres absentes, choisi pour se fondre dans le
   fond de la grille. Sur le bouton du menu, il s'y fondait tout autant : le
   burger paraissait n'avoir que deux traits. */
.burger .carres-marque i { width: 18px; height: 3px; border-radius: 2px; }
.burger .carres-marque i.absent { background: var(--texte-3); }
.burger.ouvert .carres-marque { transform: rotate(90deg); }

.menu {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  grid-template-rows: 1fr auto;
  align-content: end;
  padding: 78px 16px calc(20px + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--nuit) 94%, transparent);
  backdrop-filter: blur(8px);
  animation: menu-paraitre .18s var(--doux);
}
.menu[hidden] { display: none; }
@keyframes menu-paraitre { from { opacity: 0; } to { opacity: 1; } }

.menu-liste {
  display: grid;
  gap: 4px;
  align-content: start;
  width: min(26rem, 100%);
  margin: 0 auto;
}
.menu-liste a {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 15px 16px;
  border-radius: 12px;
  color: var(--texte);
  text-decoration: none;
  font-size: 1.05rem;
  font-weight: 600;
  border: 1px solid transparent;
}
.menu-liste a:hover { background: var(--voile); }
.menu-liste a[aria-current="page"] {
  background: var(--voile);
  border-color: var(--trait);
}
/* La puce prend la couleur « bien placee » sur la page courante : le joueur sait
   ou il est sans avoir a lire. */
.menu-liste .puce {
  width: 9px; height: 9px; border-radius: 2px;
  background: var(--absent);
  flex: 0 0 auto;
}
.menu-liste a[aria-current="page"] .puce { background: var(--bien); }

/* LE SOUTIEN, ENTRE LES PAGES ET LE PIED.
   Separe des entrees par un trait : ce n'est pas une page de plus, et il ne
   doit pas se lire comme telle. Discret, mais pas cache - une demande qu'on
   dissimule est plus genante qu'une demande assumee. */
.menu-soutien {
  width: min(26rem, 100%);
  margin: 18px auto 0;
  padding-top: 16px;
  border-top: 1px solid var(--trait);
  text-align: center;
}
.menu-soutien-mot {
  margin: 0 0 12px;
  color: var(--texte-2);
  font-size: .82rem;
  line-height: 1.6;
}

/* Le bouton porte l'orange du jeu, pas le bleu : le bleu est la couleur de ce
   qui est bien place, elle appartient a la grille. L'orange dit « autre
   chose », ce qu'est exactement un depart vers un autre site. */
.menu-don {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 10px 18px;
  border: 1px solid rgba(242, 160, 61, .45);
  border-radius: 999px;
  background: rgba(242, 160, 61, .12);
  color: var(--present);
  text-decoration: none;
  font-size: .86rem;
  font-weight: 700;
  touch-action: manipulation;
  transition: background .18s var(--doux), border-color .18s var(--doux);
}
.menu-don:hover {
  background: rgba(242, 160, 61, .2);
  border-color: rgba(242, 160, 61, .7);
}
.menu-don svg { width: 18px; height: 18px; display: block; }

.menu-pied {
  width: min(26rem, 100%);
  margin: 16px auto 0;
  text-align: center;
}
.menu-qui { color: var(--texte-2); font-size: .88rem; margin: 0 0 6px; }
.menu-copyright { color: var(--texte-3); font-size: .8rem; margin: 0; }
.menu-copyright a { color: var(--texte-3); }

body.menu-ouvert { overflow: hidden; }

/* ------------------------------------------------------------------ */
/* Partage                                                             */
/* ------------------------------------------------------------------ */

.partage-titre {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 14px 0 10px;
  color: var(--texte-3);
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .1em;
}
.partage-titre .fil { flex: 1; height: 1px; background: var(--trait); }

.partage-ligne { display: flex; gap: 8px; justify-content: center; }

.part {
  flex: 1 1 0;
  max-width: 68px;
  height: 46px;
  display: grid;
  place-items: center;
  border: 1px solid var(--trait);
  border-radius: 11px;
  background: var(--voile);
  color: var(--teinte, var(--texte));
  cursor: pointer;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  transition: background .18s var(--doux), transform .08s var(--doux);
}
.part:hover { background: color-mix(in srgb, var(--teinte, #fff) 16%, transparent); }
.part:active { transform: translateY(1px); }
.part svg { width: 21px; height: 21px; display: block; }
.part[hidden] { display: none; }

/* ------------------------------------------------------------------ */
/* Pages de texte - regles, a propos, mentions                         */
/* ------------------------------------------------------------------ */

/* Ces trois pages se lisent d'une traite. Pas de colonne, pas de repli, pas de
   sommaire : elles sont courtes, et un sommaire sur trois ecrans est une
   coquetterie qui ajoute un clic. */
.texte {
  max-width: 34rem;
  -webkit-user-select: text;
  user-select: text;
}
.texte .oeil {
  color: var(--texte-3);
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .14em;
  margin: 22px 0 6px;
}
.texte h1 {
  font-size: clamp(1.7rem, 7vw, 2.3rem);
  font-weight: 800;
  letter-spacing: -.03em;
  margin: 0 0 10px;
}
.texte .chapeau { color: var(--texte-2); font-size: 1.02rem; margin: 0 0 8px; }

.bloc {
  border-top: 1px solid var(--trait);
  padding-top: 20px;
  margin-top: 30px;
}
/* Le titre de section porte un carre, comme le menu et la marque. C'est le meme
   vocabulaire d'un bout a l'autre du site. */
.bloc h2 {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  font-size: .78rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--texte-2);
}
.bloc h2::before {
  content: '';
  width: 9px; height: 9px; border-radius: 2px;
  background: var(--bien);
  flex: 0 0 auto;
}
.bloc p, .bloc li { font-size: .98rem; line-height: 1.68; }
.bloc p { margin: 0 0 14px; }
.bloc ul { margin: 0 0 14px; padding-left: 20px; }
.bloc li { margin-bottom: 6px; }
.bloc .discret { color: var(--texte-2); font-size: .92rem; }
.texte a { color: var(--bien); }

/* Les exemples de coloration, dans les regles : une vraie grille, en petit. */
.exemple { display: flex; gap: 5px; margin: 0 0 8px; flex-wrap: wrap; }
.exemple span {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 7px;
  font-weight: 800; font-size: .9rem;
  background: var(--absent); color: var(--texte-2);
}
.exemple span.bien { background: var(--bien); color: #fff; }
.exemple span.present { background: var(--present); color: #14161F; }

.signature { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; font-weight: 700; }
.signature .annee { color: var(--texte-3); font-weight: 500; font-variant-numeric: tabular-nums; }

.sites { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.sites li { display: flex; align-items: baseline; gap: 10px; }
.sites .puce {
  width: 8px; height: 8px; border-radius: 2px; flex: 0 0 auto;
  align-self: center; background: var(--teinte, var(--bien));
}
.sites a { font-weight: 600; text-decoration: none; }
.sites a:hover { text-decoration: underline; }
.sites .quoi { color: var(--texte-2); font-size: .88rem; }

.pied {
  margin: 40px 0 20px;
  padding-top: 18px;
  border-top: 1px solid var(--trait);
  color: var(--texte-3);
  font-size: .84rem;
}

/* Le focus reste VISIBLE partout. Le jeu se joue au clavier ; supprimer le
   contour parce qu'il ne plait pas rendrait le site inutilisable a qui n'a pas
   de souris. */
:focus-visible {
  outline: 2px solid var(--bien);
  outline-offset: 2px;
  border-radius: 4px;
}
