@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');

/* Le reste de votre code CSS vient ici */

/* =============================================================================
   index0.css — l'écran d'entrée et le trailer.
   =============================================================================

   Trois moments successifs, tous dans la même page :
   1. L'écran noir avec « press space to enter the Astre Occlus »
   2. Le trailer en plein écran
   3. Le fondu au noir vers index1.html
============================================================================= */

/* Cette page n'a pas de format fixe : le noir occupe tout l'écran. */
body.page-index0 {
  cursor: none;    /* rien à cliquer, on cache le curseur : on est dans le noir */
}

/* ---------------------------------------------------------------------------
   L'ACTE I — la toute première image du site.

   Elle couvre tout, par-dessus l'écran d'entrée (z-index 100) et le trailer.
   Elle reste EN DESSOUS du voile noir des transitions (9500), pour que le
   fondu d'ouverture de la page passe devant elle comme devant le reste.

   Les réglages :
     --acte-fade-in  : combien de temps elle met à apparaître
     --acte-fade-out : combien de temps elle met à disparaître
     --acte-w        : sa largeur maximale

   Son fond est noir et plein : c'est une page de texte, elle ne doit rien
   laisser deviner de ce qu'il y a derrière.
--------------------------------------------------------------------------- */
:root {
  --acte-fade-in: 1200ms;
  --acte-fade-out: 700ms;
  --acte-w: min(92vw, 1500px);
}

.acte {
  position: fixed;
  inset: 0;
  z-index: 500;

  display: flex;
  align-items: center;
  justify-content: center;

  background: #000;

  opacity: 0;
  visibility: hidden;
  /* LE FONDU DE SORTIE.
     Une transition écrite sur la règle de base est celle qui joue quand on
     REVIENT à cet état — donc quand l'acte s'efface. Même logique que pour
     .zone-label dans global.css. */
  transition: opacity var(--acte-fade-out) ease, visibility var(--acte-fade-out);
}

/* LE FONDU D'ENTRÉE, plus lent : le texte se lève dans le noir.
   La classe is-open est écrite dans index0.html, donc l'acte est là dès la
   première image de la page — il n'attend pas que le JavaScript se charge. */
.acte.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--acte-fade-in) ease, visibility var(--acte-fade-in);
}

.acte__image {
  max-width: var(--acte-w);
  max-height: 92vh;
  object-fit: contain;
  display: block;
}

/* ---------------------------------------------------------------------------
   L'ÉCRAN D'ENTRÉE
--------------------------------------------------------------------------- */
.intro {
  position: fixed;
  inset: 0;
  z-index: 100;

  display: flex;
  align-items: center;
  justify-content: center;

  background: #000;
  transition: opacity 900ms ease;
}

.intro.is-hidden {
  opacity: 0;
  pointer-events: none;
}

/* LA PHRASE D'ACCUEIL, maintenant une image.

   ELLE EST AFFICHÉE À SA TAILLE RÉELLE, 1280 x 720, sans aucune mise à
   l'échelle : un pixel du fichier = un pixel de l'écran. C'est ce qui donne
   le rendu le plus net — un redimensionnement, même vers le bas, ajoute
   forcément du lissage, et sur une typographie dessinée en pixels comme
   celle-ci ça se voit tout de suite.

   Il n'y a donc volontairement ni max-width ni max-height ici : la moindre
   contrainte de taille déclencherait la mise à l'échelle qu'on veut éviter.

   La contrepartie, pour que tu la connaisses : sur une fenêtre plus étroite
   que 1280 pixels, l'image dépasse et ses bords sont coupés — elle ne
   rapetissera pas pour s'adapter. Comme son fond est noir, exactement comme
   celui de la page, ça ne se voit pas : on perd seulement le début et la fin
   de la phrase. Le jour où tu veux qu'elle s'adapte, c'est une ligne à
   ajouter : max-width: 100%.

   La respiration est conservée : elle portait sur le texte, elle porte
   maintenant sur l'image. Quatre secondes par cycle. */
.intro__image {
  display: block;

  animation: intro-breathe 4s ease-in-out infinite;
}

@keyframes intro-breathe {
  0%, 100% { opacity: .62; }
  50%      { opacity: 1; }
}

/* Le mot « loading » pendant la préparation des images de la chambre.
   Il remplace la phrase d'invite tant que tout n'est pas prêt. */
.intro__loading {
  position: absolute;
  bottom: 8%;
  left: 50%;
  transform: translateX(-50%);

  color: #4a4a4a;
  font-size: clamp(9px, .75vw, 12px);
  letter-spacing: .3em;

  opacity: 0;
  transition: opacity 400ms ease;
}

.intro__loading.is-visible {
  opacity: 1;
}

/* Les trois points qui défilent après « loading ». */
.intro__loading::after {
  content: '';
  animation: loading-dots 1.4s steps(4, end) infinite;
}

@keyframes loading-dots {
  0%   { content: ''; }
  25%  { content: '.'; }
  50%  { content: '..'; }
  75%  { content: '...'; }
  100% { content: ''; }
}

/* ---------------------------------------------------------------------------
   LE TRAILER
--------------------------------------------------------------------------- */
.trailer {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;

  /*LAISSEZ COVER */
  object-fit: cover;
  background: #000;

  opacity: 0;
  transition: opacity 600ms ease;
}

.trailer.is-playing {
  opacity: 1;
}

/* L'invitation à passer le trailer. Elle n'apparaît qu'au bout de quelques
   secondes, pour ne pas proposer de sauter avant même d'avoir vu quoi que ce
   soit. */
.skip {
  position: fixed;
  right: 3vw;
  bottom: 3vh;
  z-index: 200;

  color: rgba(255, 255, 255, .34);
  font-size: clamp(9px, .72vw, 12px);
  letter-spacing: .24em;

  opacity: 0;
  pointer-events: none;
  transition: opacity 900ms ease;
}

.skip.is-visible {
  opacity: 1;
}
