/* ===========================================================================
   4 — MOUVEMENT
   ---------------------------------------------------------------------------
   POURQUOI CE FICHIER EST SEPARE

   Toutes les animations du site sont ici, et nulle part ailleurs. Le jour
   ou le client dit « c'est trop, calmez-moi ca », il y a un seul fichier a
   ouvrir — et, a la limite, une seule balise <link> a commenter dans
   layout.njk pour tout desactiver d'un coup sans rien casser.

   LES TROIS REGLES SUIVIES ICI

   1. Une animation doit dire quelque chose de vrai.
      Le cartouche monte parce qu'il arrive au premier plan. Les sections
      apparaissent l'une apres l'autre parce qu'on les decouvre en
      descendant. Une etoile qui scintille ou une balle qui roule sur des
      montagnes ne dit rien : ca occupe l'ecran, ca detourne l'oeil du
      bouton « Reserver », et ca vieillit tres mal. Elles ont ete
      supprimees, ce n'est pas un oubli.

   2. On n'anime que `transform` et `opacity`.
      Ces deux proprietes sont traitees par le processeur graphique, sans
      recalcul de mise en page ni repeinture. Animer `width`, `height`,
      `top` ou `margin` force le navigateur a tout recalculer a chaque
      image : c'est la cause numero un des animations qui saccadent sur un
      telephone d'entree de gamme — c'est-a-dire chez une bonne partie des
      visiteurs.

   3. Tout est court et amorti.
      140 ms pour une reaction (survol), 420 ms pour une arrivee. Au-dela
      de 500 ms, l'interface parait lente ; en dessous de 100 ms, le
      mouvement n'est pas percu et n'apporte donc rien.

   FILET DE SECURITE
   La section finale desactive integralement ce fichier si le systeme du
   visiteur demande de reduire les animations. Cette section doit rester
   la DERNIERE du dernier fichier CSS charge.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1. ARRIVEE DE LA PAGE
   ---------------------------------------------------------------------------
   Une sequence orchestree, jamais un empilement d'effets simultanes :
     0 ms    la photographie se pose (leger dezoom)
     120 ms  le cartouche monte et apparait
     260 ms  les donnees courtes s'affichent

   Le decalage se lit comme une mise en place, pas comme un chargement lent.
   Total : moins d'une seconde.
--------------------------------------------------------------------------- */

@keyframes scene-pose {
  from { transform: scale(1.06); }
  to   { transform: scale(1); }
}
@keyframes monte-et-apparait {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes apparait {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Le dezoom porte sur le voile, qui couvre exactement la photo : animer un
   `background-image` est impossible, animer un calque par-dessus l'est.
   `will-change` previent le navigateur de preparer un calque dedie. */
.scene__voile {
  animation: scene-pose 1400ms var(--courbe) both;
  will-change: transform;
}
.scene__cartouche {
  animation: monte-et-apparait var(--duree-douce) var(--courbe) 120ms both;
}
.scene__cartouche .donnee {
  animation: apparait 600ms var(--courbe) 260ms both;
}

/* ---------------------------------------------------------------------------
   2. REVELATION AU DEFILEMENT
   ---------------------------------------------------------------------------
   Chaque section se leve legerement quand elle entre dans l'ecran. Une
   seule fois : rejouer l'animation en remontant la page est desagreable et
   donne l'impression que le site est instable.

   POINT CRITIQUE — la garde `html.js`.
   L'etat de depart (invisible) n'est applique QUE si JavaScript s'execute :
   ui.js pose la classe `js` sur <html> des sa premiere ligne. Sans cette
   garde, un visiteur dont le JavaScript est bloque — extension de securite,
   reseau coupe en cours de chargement, robot d'indexation — verrait une
   page entierement blanche, puisque personne ne viendrait jamais retirer
   l'opacite nulle. C'est un accident classique, et il est silencieux :
   il ne se voit pas en developpement.
--------------------------------------------------------------------------- */
html.js .a-reveler {
  opacity: 0;
  transform: translateY(18px);
}
html.js .a-reveler.revele {
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--duree-douce) var(--courbe),
              transform var(--duree-douce) var(--courbe);
}

/* Decalage en cascade a l'interieur d'un groupe (cartes d'avis, vignettes
   de la galerie). 60 ms d'ecart : assez pour que l'oeil percoive un ordre,
   assez peu pour que l'ensemble reste rapide.
   Le decalage s'arrete a la sixieme carte — au-dela, l'attente devient
   perceptible et l'effet se retourne contre lui-meme. */
html.js .cascade > *:nth-child(1) { transition-delay:   0ms; }
html.js .cascade > *:nth-child(2) { transition-delay:  60ms; }
html.js .cascade > *:nth-child(3) { transition-delay: 120ms; }
html.js .cascade > *:nth-child(4) { transition-delay: 180ms; }
html.js .cascade > *:nth-child(5) { transition-delay: 240ms; }
html.js .cascade > *:nth-child(n+6) { transition-delay: 300ms; }

/* ---------------------------------------------------------------------------
   3. VISIONNEUSE DE PHOTOS
   ---------------------------------------------------------------------------
   Ouverte au clic sur une vignette (voir ui.js). Sans JavaScript, le lien
   de la vignette ouvre simplement l'image en pleine page : la galerie reste
   utilisable, elle est juste moins confortable.
--------------------------------------------------------------------------- */
/* IMPORTANT — le selecteur porte `[open]`.
   Un <dialog> ferme est masque par la feuille de style du navigateur
   (`display: none`). Ecrire `.visionneuse { display: grid }` ECRASE cette
   regle : le dialogue reste alors affiche en permanence, sous la forme d'un
   carre sombre avec son bouton de fermeture, par-dessus la page. C'est
   exactement le bug qu'on voyait sur la page Photos.
   En ciblant `[open]`, le style ne s'applique qu'au dialogue reellement
   ouvert, et le comportement natif reprend ses droits le reste du temps. */
.visionneuse[open] {
  position: fixed; inset: 0; z-index: 50;
  display: grid; place-items: center;
  padding: var(--e5);
  background: rgb(12 16 14 / 92%);
  border: 0;
  animation: apparait 200ms var(--courbe) both;
}
.visionneuse[open] img {
  max-width: min(1400px, 100%);
  max-height: 88vh;
  width: auto;
  border-radius: var(--rayon-petit);
  box-shadow: var(--ombre-2);
  animation: monte-et-apparait 320ms var(--courbe) both;
}
.visionneuse__fermer {
  position: absolute; top: var(--e4); right: var(--e4);
  min-height: 48px; min-width: 48px;
  font: inherit; font-size: 1.5rem; line-height: 1;
  color: var(--blanc); background: rgb(255 255 255 / 12%);
  border: 1px solid rgb(255 255 255 / 30%);
  border-radius: 999px; cursor: pointer;
}
.visionneuse__fermer:hover { background: rgb(255 255 255 / 24%); }
.visionneuse__legende {
  position: absolute; bottom: var(--e5); left: 50%;
  transform: translateX(-50%);
  max-width: 60ch; text-align: center;
  color: var(--chaux-creuse); font-size: 0.9375rem;
}

/* ---------------------------------------------------------------------------
   4. CHARGEMENT DES IMAGES
   ---------------------------------------------------------------------------
   Une photo en chargement differe apparait brutalement quand elle arrive.
   Un fondu de 400 ms suffit a rendre le remplissage de la galerie fluide
   au lieu de clignotant. La classe est posee par ui.js a l'evenement
   `load` de chaque image.
--------------------------------------------------------------------------- */
html.js .galerie__vignette img { opacity: 0; }
html.js .galerie__vignette img.chargee { opacity: 1; transition: opacity 400ms var(--courbe); }
/* Si l'image vient du cache, elle est deja complete avant que le script
   ne s'attache : ui.js pose alors `chargee` immediatement. Ce cas est
   couvert cote script, pas ici. */

/* ---------------------------------------------------------------------------
   5. GARDE-FOU — « reduire les animations »
   ---------------------------------------------------------------------------
   Ce reglage systeme n'est pas un caprice esthetique : pour les personnes
   sujettes au vertige, aux migraines vestibulaires ou a certaines formes
   d'epilepsie, une animation non desiree provoque un malaise physique.
   Quand il est actif, on ne ralentit pas les animations : on les supprime.

   `!important` est justifie ici, et seulement ici : cette regle doit
   l'emporter sur absolument tout, y compris sur du CSS ajoute plus tard
   par quelqu'un qui n'aurait pas lu ce fichier.
--------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Le contenu doit rester VISIBLE : on ne se contente pas de couper la
     transition, on force aussi l'etat final. Sans ces deux lignes, les
     sections resteraient invisibles pour les personnes qui ont justement
     demande moins de mouvement. */
  html.js .a-reveler { opacity: 1 !important; transform: none !important; }
  html.js .galerie__vignette img { opacity: 1 !important; }
}
