/* ==========================================================================
   Gabarit : conteneurs, bandeaux, rythme vertical, grilles génériques.

   Une règle traverse tout le fichier : rien n'est centré « par défaut ».
   Le contenu de lecture est aligné à gauche dans une colonne de largeur
   limitée, les sections vitrines (chiffres, prestations) sont centrées
   volontairement. C'est ce mélange assumé qui évite l'effet « page de
   démonstration » où tout est centré sans raison.
   ========================================================================== */

/* --- Conteneurs ------------------------------------------------------------ */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.shell--wide { max-width: var(--shell-wide); }
.shell--narrow { max-width: 780px; }
.shell--text { max-width: 44rem; }

/* Sort un bloc du conteneur pour le mettre pleine largeur, sans casser le
   flux ni créer de défilement horizontal. */
.full-bleed {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}

/* --- Rythme vertical ------------------------------------------------------- */

.section {
  padding-block: var(--section-y);
  position: relative;
}

.section--lg { padding-block: var(--section-y-lg); }
.section--tight { padding-block: calc(var(--section-y) * 0.6); }
.section--flush-top { padding-top: 0; }
.section--flush-bottom { padding-bottom: 0; }

/* --- Bandeaux --------------------------------------------------------------
   Trois fonds qui alternent pour créer le rythme : blanc cassé, sable,
   olive profond. Une page ne devrait jamais enchaîner deux bandeaux de même
   couleur, sinon le rythme disparaît et tout redevient plat.
   --------------------------------------------------------------------------- */

.band--sand { background: var(--c-sand); }

.band--dark {
  background: var(--c-brand-deep);
  color: var(--c-ink); /* --c-ink vaut crème dans ce contexte, cf. tokens.css */
}

/* `:not(.btn)` n'est pas cosmétique. Sans lui, cette règle est plus
   spécifique que `.btn--primary` et repeint le texte du bouton doré en
   lavande claire : 1,36:1 sur fond doré, illisible. */
.band--dark a:not(.btn):not(.link-arrow) { color: var(--c-accent-strong); }
.band--dark a:not(.btn):not(.link-arrow):hover { color: #fff; }
.band--dark .link-arrow { color: var(--c-accent-strong); }
.band--dark .link-arrow:hover { color: #fff; }

/* Liseré décoratif entre deux bandeaux clairs, pour marquer la séparation
   sans ajouter de trait dur. */
.band--edge-top { border-top: 1px solid var(--c-line-soft); }

/* --- En-tête de section ----------------------------------------------------
   Trois briques : surtitre optionnel, titre, chapô optionnel.
   Variante centrée pour les sections vitrines.
   --------------------------------------------------------------------------- */

.sec-head {
  max-width: 42rem;
  margin-bottom: var(--s-7);
}

.sec-head--center {
  margin-inline: auto;
  text-align: center;
}

.sec-head__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-family: var(--font-body);
  font-size: var(--t-eyebrow);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-brand);
  margin: 0 0 var(--s-3);
}

.sec-head__eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 2px;
  background: var(--c-action);
  border-radius: 2px;
}

.sec-head--center .sec-head__eyebrow::after {
  content: "";
  width: 1.75rem;
  height: 2px;
  background: var(--c-action);
  border-radius: 2px;
}

.sec-head__title { margin-bottom: var(--s-4); }
.sec-head__title:last-child { margin-bottom: 0; }

.sec-head__lead {
  font-size: var(--t-lead);
  color: var(--c-muted);
  line-height: 1.65;
  margin-bottom: 0;
}

.sec-head__actions {
  margin-top: var(--s-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}

.sec-head--center .sec-head__actions { justify-content: center; }

/* --- Grilles génériques ----------------------------------------------------
   Le motif `repeat(auto-fit, minmax(min(<base>, 100%), 1fr))` évite le
   débordement sur très petit écran : sous <base>, la colonne se limite à
   100 % au lieu de forcer la largeur.
   --------------------------------------------------------------------------- */

.grid { display: grid; gap: var(--s-5); }
.grid--gap-lg { gap: var(--s-6); }
.grid--gap-sm { gap: var(--s-4); }

.grid--auto-xs { grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr)); }
.grid--auto-sm { grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr)); }
.grid--auto-md { grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr)); }
.grid--auto-lg { grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr)); }

.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }

@media (min-width: 720px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 900px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
}

/* Deux colonnes déséquilibrées : texte + média. */
.split {
  display: grid;
  gap: var(--s-6);
  align-items: center;
}

@media (min-width: 900px) {
  .split {
    grid-template-columns: 1fr 1fr;
    gap: var(--s-8);
  }

  .split--text-wide { grid-template-columns: 1.15fr 0.85fr; }
  .split--media-wide { grid-template-columns: 0.85fr 1.15fr; }
  .split--reverse > :first-child { order: 2; }
}

.split--top { align-items: start; }

/* --- Piles ----------------------------------------------------------------- */

.stack > * + * { margin-top: var(--s-4); }
.stack--sm > * + * { margin-top: var(--s-2); }
.stack--lg > * + * { margin-top: var(--s-6); }

.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
}

.row--center { justify-content: center; }
.row--between { justify-content: space-between; }

.center { text-align: center; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }

/* --- Apparition au défilement ----------------------------------------------
   Ces règles sont volontairement conditionnées à `.js-anim`, une classe que
   ui.js pose lui-même sur <html> au tout début de son exécution.

   C'est le point important : sans cette condition, un contenu masqué par
   `opacity: 0` attend un `.is-in` que seul JavaScript peut poser. Si le
   script ne se charge pas — réseau coupé en plein chargement, extension de
   navigateur, erreur de déploiement — la moitié de la page reste invisible
   pour toujours, sans message d'erreur. Le défaut le plus coûteux d'une
   animation d'apparition n'est pas son animation, c'est son état initial.

   Filet supplémentaire côté JS : un minuteur révèle tout au bout de deux
   secondes, même si IntersectionObserver n'a rien signalé.
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .js-anim [data-reveal] {
    opacity: 0;
    transform: translateY(1.25rem);
    transition:
      opacity var(--d-slow) var(--e-out),
      transform var(--d-slow) var(--e-out);
  }

  .js-anim [data-reveal].is-in {
    opacity: 1;
    transform: none;
  }

  /* Décalage en cascade pour les enfants d'une grille. */
  .js-anim [data-reveal-stagger] > * {
    opacity: 0;
    transform: translateY(1.25rem);
    transition:
      opacity var(--d-slow) var(--e-out),
      transform var(--d-slow) var(--e-out);
  }

  .js-anim [data-reveal-stagger].is-in > * {
    opacity: 1;
    transform: none;
  }

  .js-anim [data-reveal-stagger].is-in > :nth-child(1) { transition-delay: 0ms; }
  .js-anim [data-reveal-stagger].is-in > :nth-child(2) { transition-delay: 70ms; }
  .js-anim [data-reveal-stagger].is-in > :nth-child(3) { transition-delay: 140ms; }
  .js-anim [data-reveal-stagger].is-in > :nth-child(4) { transition-delay: 210ms; }
  .js-anim [data-reveal-stagger].is-in > :nth-child(5) { transition-delay: 280ms; }
  .js-anim [data-reveal-stagger].is-in > :nth-child(6) { transition-delay: 350ms; }
  .js-anim [data-reveal-stagger].is-in > :nth-child(7) { transition-delay: 420ms; }
  .js-anim [data-reveal-stagger].is-in > :nth-child(8) { transition-delay: 490ms; }

  /* Sortie de secours du minuteur de ui.js : on coupe la transition pour
     que l'opacité saute à 1 tout de suite, au lieu d'attendre une animation
     qu'un onglet en arrière-plan ne jouera peut-être jamais. */
  .js-anim .reveal-now,
  .js-anim .reveal-now > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}
