/**
 * PlayAwale — Ossature commune des pages
 * -----------------------------------------------------------------------------
 * Décor de fond, centrage du contenu et pied de page : tout ce que partagent
 * les pages du site, indépendamment de ce qu'elles affichent.
 *
 * Cette feuille est chargée sur TOUTES les pages. Ce qui ne concerne qu'une
 * seule page appartient à assets/css/pages/.
 *
 * @package   PlayAwale
 * @version   2.0
 * @author    Nicolas Lion — Développeur web — https://nlion.fr
 * @copyright 2026 Nicolas Lion
 */

/* =============================================================================
   FOND DE PAGE
   Deux couches superposées : un dégradé de sable peint sur le body, surmonté
   d'une photographie de village en fondu.
   ============================================================================= */

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  color: var(--color-text);
  font-family: var(--font-body);
  line-height: var(--line-height-base);

  background-color: var(--color-page-bg);
  background-image: var(--gradient-page);

  /* Le dégradé reste fixe pendant le défilement du contenu. */
  background-attachment: fixed;
  background-size: cover;

  /* Référence de positionnement pour la photographie d'arrière-plan. */
  position: relative;
}

/* Photographie d'arrière-plan, en pseudo-élément : purement décorative, elle
   n'a donc pas sa place dans le HTML et reste invisible aux lecteurs d'écran. */
body::before {
  content: '';

  /* CALÉE SUR LA FENÊTRE, ET NON SUR LA PAGE
     -----------------------------------------------------------------------------
     Elle était « absolute », donc mesurée sur le BODY, dont la hauteur est celle
     de la page : l'accueil en fait deux fenêtres et demie, l'écran du choix des
     niveaux une seule. La photographie étant centrée sur cette hauteur, on ne
     regardait pas la même bande de l'image d'une page à l'autre — et le décor
     changeait donc d'un écran à l'autre, ce que la note du voile ci-dessous
     interdit en toutes lettres.

     « fixed », comme le voile : la photographie est désormais centrée sur la
     FENÊTRE, la même partout, quelle que soit la longueur de la page.

     CE QUE CELA CHANGE AUSSI, ET C'EST VOULU : sur une page longue, elle ne
     défile plus avec le contenu. Le dégradé du sable ne défilait déjà pas
     (« background-attachment: fixed » plus haut) et le voile non plus : les
     trois couches du décor se tiennent maintenant ensemble. */
  position: fixed;
  inset: 0;

  /* Deux déclarations successives, du plus compatible au plus efficace.
     Un navigateur qui ne comprend pas image-set() ignore la seconde ligne et
     conserve le PNG ; les autres choisissent le WebP, huit fois plus léger
     (38 Ko contre 307 Ko) pour un rendu identique — l'image est floue. */
  background-image: url('../../img/blured_village-awale-oware-mancala.png');
  background-image: image-set(
    url('../../img/blured_village-awale-oware-mancala.webp') type('image/webp'),
    url('../../img/blured_village-awale-oware-mancala.png') type('image/png')
  );

  /* LE VILLAGE REMONTE, ET D'UN SEUL NOMBRE
     Centré, le hameau tombait derrière le bas de l'écran — la moitié basse de la
     page n'avait plus que du sable, et le décor ne se voyait qu'en défilant. Il
     remonte pour que les toits se tiennent derrière le titre et le plateau, là
     où le regard se pose en arrivant.

     POURQUOI « calc » ET NON UN POURCENTAGE
     Un pourcentage de position ne dit pas « à tant du haut » : il aligne le même
     point de l'image et du cadre. L'image est CARRÉE et posée en « 100 % » de
     large : sa hauteur affichée vaut donc la largeur de la fenêtre — 1 920 px sur
     un grand écran —, et elle est toujours plus haute que le cadre. Un
     pourcentage y glisserait avec la largeur de l'écran ; le calcul, lui,
     retranche toujours la même hauteur au centrage.

     QUARANTE PIXELS, ET NON QUATRE-VINGT-DIX
     Signalé sur l'écran du choix des niveaux : « c'est calé en bas alors qu'il y
     a de la place en haut ». Le bloc n'avait pas bougé — c'est le décor qui
     était remonté, et les toits trop hauts laissaient un vide au-dessus du
     contenu. La remontée est ramenée à la moitié, ce qui reste assez pour
     sortir le hameau du bas de l'écran.

     POUR AJUSTER : « --backdrop-lift », et rien d'autre. Le décor valant pour
     TOUTES les pages, un réglage par page est exclu. */
  --backdrop-lift: 40px;

  background-position: center calc(50% - var(--backdrop-lift));
  background-repeat: no-repeat;
  background-size: 100%;

  /* Placée derrière le contenu. */
  z-index: var(--z-backdrop);

  /* Invisible au départ : l'animation la fait apparaître en fondu. */
  opacity: 0;
  animation: backdrop-fade-in var(--duration-backdrop) ease forwards;
}

/* Le voile : un halo au centre, une pénombre dans les angles.

   POURQUOI IL EXISTE
   La photographie de village se lisait à peine et occupait pourtant tout
   l'écran : elle disputait l'attention aux titres et aux boutons sans rien
   apprendre à personne. Éclaircie au centre et assombrie sur les bords, elle
   redevient ce qu'elle est — un décor —, et le regard va au milieu parce que
   c'est là qu'il fait clair.

   IL EST FIXE, ET SUR TOUTES LES PAGES
   Fixe, comme une lampe au-dessus d'une table : il ne défile pas avec le
   contenu. Et posé ici plutôt que sur une page, parce qu'un décor qui change
   d'un écran à l'autre se remarque — c'est justement ce qu'un décor ne doit
   pas faire.

   Il ne se clique pas : il recouvre toute la page, et laisserait sinon le
   contenu hors d'atteinte. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;

  /* Derrière le contenu, devant la photographie. */
  z-index: var(--z-backdrop);

  background-image: var(--gradient-spotlight), var(--gradient-vignette);
}


/* Fondu d'entrée de la photographie, jusqu'à une opacité partielle qui laisse
   le dégradé transparaître. */
@keyframes backdrop-fade-in {
  from { opacity: 0; }
  to   { opacity: 0.75; }
}


/* =============================================================================
   CONTENU
   ============================================================================= */

/* Conteneur principal : centre le contenu et ménage une marge sur les bords. */
.page {
  width: 100%;
  padding: var(--space-2xl) var(--space-md);
  text-align: center;

  /* Au-dessus de la photographie d'arrière-plan. */
  position: relative;
  z-index: var(--z-content);
}


/* =============================================================================
   PIED DE PAGE
   ============================================================================= */

.page-footer {
  margin-top: var(--space-sm);
  font-family: var(--font-display);
  font-size: 0.95rem;
  color: var(--color-text);
  text-shadow: 0 2px 2px rgba(0, 0, 0, 0.12);
  text-align: center;
}

.page-footer a {
  text-decoration: underline;
  transition: color var(--duration-base) ease;
}

.page-footer a:hover {
  color: #000;
}


/* =============================================================================
   ADAPTATION AUX PETITS ÉCRANS
   ============================================================================= */

/* Tablettes et grands mobiles : la photographie est agrandie pour rester
   lisible dans un cadrage vertical. */
@media (max-width: 800px) {
  body::before {
    background-size: 150%;
  }
}

/* Mobiles : mise en page resserrée et pied de page plus discret. */
@media (max-width: 480px) {
  .page {
    padding: var(--space-md);
  }

  .page-footer {
    margin-top: var(--space-xs);
    font-size: 0.75rem;
    color: var(--color-text-muted);
    text-shadow: none;
  }
}


/* =============================================================================
   UNE PAGE CALÉE EN HAUT
   -----------------------------------------------------------------------------
   Le corps centre verticalement, ce qui convient à une page courte posée sur
   une photographie : elle flotte au milieu de la fenêtre.

   Cela ne convient PAS à une page à rubriques. L'espace du compte en a cinq, de
   hauteurs très différentes — deux figures ici, un formulaire là, un tableau de
   parties ailleurs. Centré, le jeton du haut et le menu de gauche sautent d'une
   rubrique à l'autre : on croit avoir changé de page alors qu'on a changé
   d'onglet, et l'œil doit retrouver où se trouvent les repères.

   Une page qui le demande — « $pageBodyClass = 'page-top' » avant head.php — se
   cale donc en haut, et ses repères ne bougent plus.

   ON NE TOUCHE PAS AU « justify-content » DU CORPS : il vaut pour tout le site,
   et l'inverser déplacerait chaque page pour régler le cas d'une seule.
   ============================================================================= */

body.page-top {
  justify-content: flex-start;
}


/* =============================================================================
   LA BARRE DE DÉFILEMENT EST TOUJOURS LÀ, SUR ORDINATEUR
   -----------------------------------------------------------------------------
   DÉFAUT MESURÉ : une page qui défile réserve 15 px à sa barre ; une page qui
   tient dans la fenêtre n'en réserve aucun. Le site centre son contenu : passer
   de l'accueil — qui défile — au tableau de bord — qui ne défile pas — déplaçait
   donc TOUT de sept ou huit pixels sur le côté. On le voit, et on ne sait pas
   pourquoi.

   « overflow-y: scroll » plutôt que « scrollbar-gutter: stable » : la gouttière
   réserve la place SANS rien peindre, ce qui règle le déplacement mais laisse le
   bord droit vide et un peu étrange. Ici, la barre est dessinée, grisée, sans
   curseur quand il n'y a rien à faire défiler — ce qui a été demandé, et ce qui
   dit au passage « cette page tient entière ».

   SUR ORDINATEUR SEULEMENT, et c'est la même définition que partout ailleurs
   dans ces feuilles : un pointeur précis qui sait survoler. Sur un téléphone et
   une tablette, les barres FLOTTENT au-dessus du contenu et ne prennent aucune
   place : il n'y a rien à réserver, et forcer un défilement permanent n'y
   apporterait que des effets de bord.
   ============================================================================= */

@media (hover: hover) and (pointer: fine) {

  html {
    overflow-y: scroll;
  }
}


/* =============================================================================
   LA BARRE DE CHARGEMENT VERS UNE PAGE DE PARTIES — 25/09/2026
   -----------------------------------------------------------------------------
   Demandé : qu'on ne voie pas une page blanche de transition en ouvrant la
   liste des parties, une partie ou son analyse. Quand un lien de partie est
   suivi et que la page suivante tarde plus de 150 ms, assets/js/verification.js
   pose « awale-transition » sur <html> : une fine barre ambrée court alors en
   haut de l'écran, jusqu'à ce que la page suivante la remplace.

   Sur <html>, et non sur <body> : body::before et body::after portent déjà le
   décor du site. Au-dessus de tout — le jeton du compte compris —, sans
   intercepter un seul clic.
   ========================================================================== */

.awale-transition::after {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  z-index: calc(var(--z-overlay) + 10);

  width: 40%;
  height: 3px;

  background-color: var(--color-brand-amber-deep);
  border-radius: 0 2px 2px 0;
  box-shadow: 0 0 8px rgba(216, 164, 78, 0.6);
  pointer-events: none;

  animation: awale-transition 1.1s ease-in-out infinite;
}

@keyframes awale-transition {
  from { transform: translateX(-100%); }
  to   { transform: translateX(250%); }
}

/* Mouvement réduit : la barre reste, immobile et pleine largeur — le signe
   demeure, le mouvement non. */
@media (prefers-reduced-motion: reduce) {
  .awale-transition::after {
    width: 100%;
    animation: none;
    opacity: 0.8;
  }
}
