/* Layout principal — pas de scroll, tout dans le viewport */
body {
  min-height: 100vh;
  min-height: 100dvh;
  position: relative;
}

/* Header — positionné en haut, indépendant du flux pour ne pas décaler la nav */
.header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: var(--space-lg) var(--space-lg) 0;
  text-align: center;
  opacity: 0;
  animation: fadeIn var(--duration-base) var(--ease-out) 100ms forwards;
}

.header__name {
  font-size: var(--fs-name);
  font-weight: 500;
  line-height: 1.1;
}

.header__tagline {
  margin-top: var(--space-xs);
  font-size: var(--fs-tagline);
  font-weight: 400;
  line-height: 1.2;
}

/* Navigation centrée verticalement par rapport à la fenêtre entière.
   - Padding symétrique --safe-top haut/bas : préserve une zone safe sous le
     titre (et symétrique en bas pour garder le vrai centrage viewport).
   - align-items: safe center : centre quand le contenu tient, mais bascule
     en alignement haut quand le contenu déborde — ce qui rend le header
     intouchable et active le scroll de la page. */
.nav {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: safe center;
  justify-content: center;
  padding: var(--safe-top) 0;
  opacity: 0;
  animation: fadeIn var(--duration-base) var(--ease-out) 250ms forwards;
}

.nav__list {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

.nav__item {
  text-align: center;
}

.nav__link {
  display: inline-block;
  font-size: var(--fs-nav);
  font-weight: 500;
  line-height: 1.2;
  padding: 0 var(--space-sm);
  font-family: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease-out);
}

.nav__link:hover,
.nav__link:focus-visible {
  opacity: 0.55;
}

.nav__link:focus-visible {
  outline: 1px solid var(--color-fg);
  outline-offset: 4px;
}

/* Panneau Clients — replié par défaut, animé en ouverture */
.nav__item--panel {
  width: 100%;
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--duration-base) var(--ease-inout);
}

.nav__item--panel.is-open {
  grid-template-rows: 1fr;
}

.nav__panel {
  overflow: hidden;
  min-height: 0;
}

.nav__panel[hidden] {
  display: block;
}

.nav__panel-inner {
  padding: 1.5rem 70px 2.5rem;
  opacity: 0;
  transform: translateY(-4px);
  transition:
    opacity var(--duration-base) var(--ease-inout),
    transform var(--duration-base) var(--ease-inout);
}

.nav__item--panel.is-open .nav__panel-inner {
  opacity: 1;
  transform: translateY(0);
}

.nav__divider {
  border: 0;
  border-top: 1px solid var(--color-divider);
  margin: 0 0 1.5rem;
  width: 100%;
  opacity: 0;
  transition: opacity 1000ms ease-in;
}

.nav__item--panel.is-open .nav__divider {
  opacity: 1;
}

/* Fermeture : la barre commence à fondre dès le clic, en 1s.
   .is-closing est posée par JS au moment du clic (avant le retrait de
   .is-open), et son opacity:0 prime sur le opacity:1 ci-dessus grâce à
   l'ordre source. */
.nav__item--panel.is-closing .nav__divider {
  opacity: 0;
  transition: opacity 1000ms ease-out;
}

/* Grille des clients : nombre de colonnes piloté par JS via --column-count
   (4 par défaut, 2 sous 800px). Les colonnes prennent toute la largeur
   disponible (la largeur est définie par le padding 70px de .nav__panel-inner). */
.clients {
  display: grid;
  grid-template-columns: repeat(var(--column-count, 4), 1fr);
  gap: var(--space-lg);
  width: 100%;
}

/* Bloc About : même grille 4 colonnes que clients pour préserver les
   alignements visuels. Bloc gauche occupe 1 colonne, bloc droit 3 colonnes.
   --max-row : indice de la rangée la plus basse (services a 5 items, max 4).
   Sert à inverser la vague à la fermeture (bottom → top). */
.about {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-lg);
  width: 100%;
  --max-row: 4;
}

.about__location {
  grid-column: span 1;
  font-size: var(--fs-about);
  font-weight: 600;
  color: var(--color-muted);
  line-height: 1.5;
  text-align: left;
  opacity: 0;
}

.about__services {
  grid-column: span 1;
  font-size: var(--fs-about);
  font-weight: 600;
  color: var(--color-muted);
  line-height: 1.5;
  text-align: left;
}

.about__services li {
  opacity: 0;
}

.about__text {
  /* Occupe les 2 colonnes de droite (3 et 4) */
  grid-column: 3 / span 2;
  font-size: var(--fs-about);
  font-weight: 600;
  color: var(--color-muted);
  line-height: 1.5;
  text-align: left;
  /* Mesure de lecture : ~50-60 caractères par ligne (unité `ch` ≈ largeur
     du caractère "0" dans la police courante). */
  max-width: 60ch;
}

/* Chaque mot du paragraphe est dans un <span> (généré par JS) pour
   permettre l'animation individuelle.
   inline-block est nécessaire pour que transform: translateY fonctionne. */
.about__text span {
  display: inline-block;
  opacity: 0;
}

/* Sous 800px : passage à 2 colonnes pour clients, et stack vertical pour about */
@media (max-width: 800px) {
  .about {
    grid-template-columns: 1fr;
  }

  .about__location,
  .about__services,
  .about__text {
    grid-column: 1;
  }
}

.clients__column {
  text-align: center;
}

.clients__list {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.clients__list li {
  font-size: var(--fs-clients);
  line-height: 1.5;
  font-weight: 600;
  color: var(--color-fg);
  opacity: 0;
  white-space: nowrap; /* un nom = toujours une seule ligne */
}

/* Vague d'apparition — animation partagée par tous les éléments animés,
   seuls les staggers (animation-delay) diffèrent par type d'élément. */
.nav__item--panel.is-open .clients__list li,
.nav__item--panel.is-open .about__location,
.nav__item--panel.is-open .about__services li,
.nav__item--panel.is-open .about__text span {
  animation:
    clientReveal 1000ms linear forwards,
    clientLift 400ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

/* === STAGGERS PAR SECTION ===
   Trois jeux de réglages indépendants. Pour chacun :
   - row : écart entre rangées (haut → bas dans une colonne)
   - col : écart entre colonnes (gauche → droite)
   - +Xms : délai initial avant le 1er élément */

/* Clients */
.nav__item--panel.is-open .clients__list li {
  animation-delay: calc(
    var(--row, 0) * 60ms +
    var(--col, 0) * 300ms +
    300ms
  );
}

/* About — bloc location + services. Col stagger plus court que clients
   (moins d'éléments à révéler par colonne, donc rythme plus serré). */
.nav__item--panel.is-open .about__location,
.nav__item--panel.is-open .about__services li {
  animation-delay: calc(
    var(--row, 0) * 60ms +
    var(--col, 0) * 150ms +
    300ms
  );
}

/* About — mots du paragraphe. Stagger entre mots beaucoup plus court
   (il y en a beaucoup, sinon la phrase met 3s à apparaître). */
.nav__item--panel.is-open .about__text span {
  animation-delay: calc(
    var(--row, 0) * 30ms +
    var(--col, 0) * 150ms +
    300ms
  );
}

@keyframes clientLift {
  0% {
    transform: translateY(30px);
  }
  100% {
    transform: translateY(0);
  }
}

@keyframes clientReveal {
  /* Phase 1 : apparition — opacité 0→1, blanc */
  0% {
    opacity: 0;
    color: var(--color-fg);
  }
  /* Phase 2 : virage au gris, opacité stable */
  50% {
    opacity: 1;
    color: var(--color-fg);
  }
  100% {
    opacity: 1;
    color: var(--color-muted);
  }
}

/* Vague de fermeture : rangée par rangée, top → bottom.
   Toutes les colonnes d'une même rangée disparaissent ensemble.
   La classe .is-closing est posée par JS au moment du clic. */
.nav__item--panel.is-closing .clients__list li,
.nav__item--panel.is-closing .about__location,
.nav__item--panel.is-closing .about__services li {
  /* `both` = backwards + forwards : pendant le délai (avant que la rangée ne
     parte), l'item garde l'état du keyframe 0% (opacité 1, gris) au lieu de
     retomber à la valeur de base (opacité 0). Sans ça, les rangées
     disparaissent puis réapparaissent. */
  animation: clientHide 220ms linear both;
  /* Sens inversé : rangée du bas (--max-row) part en premier, puis on remonte. */
  animation-delay: calc((var(--max-row, 0) - var(--row, 0)) * 40ms);
}

/* About paragraph : ferme ligne visuelle par ligne visuelle (les mots d'une
   même ligne ferment ensemble, ligne du bas en premier).
   --line est l'index de ligne visuelle, --max-line est le total - 1 ;
   les deux sont calculés en JS après mise en page. */
.nav__item--panel.is-closing .about__text span {
  animation: clientHide 220ms linear both;
  animation-delay: calc((var(--max-line, 0) - var(--line, 0)) * 40ms);
}

@keyframes clientHide {
  0% {
    opacity: 1;
    color: var(--color-muted);
  }
  100% {
    opacity: 0;
    color: var(--color-fg);
  }
}

/* Animation d'apparition */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Respect des préférences de mouvement */
@media (prefers-reduced-motion: reduce) {
  .header,
  .nav {
    animation: none;
    opacity: 1;
  }

  .nav__link {
    transition: none;
  }

  .nav__item--panel,
  .nav__panel-inner,
  .nav__divider,
  .clients__list li {
    transition: none;
  }
}
