@import url("https://fonts.googleapis.com/css?family=Raleway:100,300,400,500,700,900");
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, div
pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q,
s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li,
figure, header, nav, section, article, aside, footer, figcaption {
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
}

.clearfix:after {
  content: ".";
  display: block;
  clear: both;
  visibility: hidden;
  line-height: 0;
  height: 0;
}

.clearfix {
  display: inline-block;
}

html[xmlns] .clearfix {
  display: block;
}

* html .clearfix {
  height: 1%;
}

ul, li {
  padding: 0;
  margin: 0;
  list-style: none;
}

header, nav, section, article, aside, footer, hgroup {
  display: block;
}

* {
  box-sizing: border-box;
}

html, body {
  font-family: "Raleway", sans-serif;
  font-weight: 400;
  background-color: #fff;
  font-size: 16px;
  -ms-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  text-decoration: none !important;
}

h1, h2, h3, h4, h5, h6 {
  margin-top: 0px;
  margin-bottom: 0px;
}

ul {
  margin-bottom: 0px;
}

/* 
---------------------------------------------
global styles
--------------------------------------------- 
*/
html,
body {
  background: #17202A;
  font-family: "Raleway", sans-serif;
}

::selection {
  background: #e84c3d;
  color: #fff;
}

::-moz-selection {
  background: #e84c3d;
  color: #fff;
}

.section {
  position: relative;
  padding-top: 100px;
  padding-bottom: 80px;
}

.section.colored {
  background: #e84c3d;
}

.hr {
  bottom: 0px;
  width: 100%;
  height: 1px;
  margin-top: 100px;
  border-bottom: 1px solid #eee;
}

.left-heading.light .section-title {
  color: #ffffff;
}

.left-heading .section-title {
  font-weight: 500;
  font-size: 24px;
  line-height: 42px;
  color: #fff;
  letter-spacing: 0.25px;
  margin-bottom: 30px;
  position: relative;
}

.center-heading {
  text-align: center;
}

.center-heading .section-title {
  font-weight: 500;
  font-size: 28px;
  color: #fff;
  letter-spacing: 1.75px;
  line-height: 38px;
  margin-bottom: 20px;
}

.center-heading.colored .section-title {
  color: #ffffff;
}

.center-text {
  text-align: center;
  font-weight: 400;
  font-size: 16px;
  color: #777;
  line-height: 28px;
  letter-spacing: 1px;
  margin-bottom: 50px;
}

.center-text.colored {
  color: #fff;
}

.center-text p {
  font-size: 15px;
  color: #fff;
  margin-bottom: 30px;
}

.left-text {
  font-weight: 400;
  font-size: 16px;
  color: #fff;
  line-height: 28px;
  letter-spacing: 1px;
}

.left-text.light {
  color: #fff;
}

.left-text p {
  margin-bottom: 30px;
}

.left-text p.dark {
  color: #3B566E;
}

.padding-bottom-top-60 {
  padding-top: 60px !important;
  padding-bottom: 60px !important;
}

.padding-bottom-80 {
  padding-bottom: 80px !important;
}

.padding-bottom-100 {
  padding-bottom: 100px !important;
}

.border-bottom {
  border-bottom: 1px solid #eee !important;
}

.mbottom-30 {
  margin-bottom: 30px !important;
}

.align-self-center {
  -ms-flex-item-align: center !important;
  align-self: center !important;
}

.align-self-bottom {
  -ms-flex-item-align: flex-end !important;
  align-self: flex-end !important;
}

.padding-bottom-0 {
  padding-bottom: 0px !important;
}

.padding-top-0 {
  padding-top: 0px !important;
}

.padding-top-80 {
  padding-top: 80px !important;
}

.padding-top-70 {
  padding-top: 70px !important;
}

.padding-top-20 {
  padding-top: 20px !important;
}

.margin-bottom-0 {
  margin-bottom: 0px !important;
}

.margin-bottom-30 {
  margin-bottom: 30px !important;
}

.margin-top-30 {
  margin-top: 30px !important;
}

.margin-top-15 {
  margin-top: 15px !important;
}

.margin-bottom-45 {
  margin-bottom: 45px !important;
}

.margin-bottom-20 {
  margin-bottom: 20px !important;
}

.margin-bottom-60 {
  margin-bottom: 60px !important;
}

.margin-bottom-100 {
  margin-bottom: 100px !important;
}

@media (max-width: 991px) {
  html, body {
    overflow-x: hidden;
  }
  .mobile-top-fix {
    margin-top: 30px;
    margin-bottom: 0px;
  }
  .mobile-bottom-fix {
    margin-bottom: 30px;
  }
  .mobile-bottom-fix-big {
    margin-bottom: 60px;
  }
}

a.main-button-slider {
  font-size: 13px;
  border-radius: 20px;
  padding: 12px 20px;
  background-color: #e84c3d;
  text-transform: uppercase;
  color: #fff;
  letter-spacing: 0.25px;
  -webkit-transition: all 0.3s ease 0s;
  -moz-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
}

a.main-button-slider:hover {
  background-color: #983a31;
}
a.main-button-slider-xonaria {
  font-size: 13px;
  border-radius: 20px;
  padding: 12px 20px;
  background-color: #ba9023;
  text-transform: uppercase;
  color: #fff;
  letter-spacing: 0.25px;
  -webkit-transition: all 0.3s ease 0s;
  -moz-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
}

a.main-button-slider-xonaria:hover {
  background-color: #e84c3d;
}

a.main-button {
  font-size: 13px;
  border-radius: 20px;
  padding: 12px 20px;
  background-color: #e84c3d;
  text-transform: uppercase;
  color: #fff;
  letter-spacing: 0.25px;
  -webkit-transition: all 0.3s ease 0s;
  -moz-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
}

a.main-button:hover {
  background-color: #983a31;
}

button.main-button {
  outline: none;
  border: none;
  cursor: pointer;
  font-size: 13px;
  border-radius: 20px;
  padding: 12px 20px;
  background-color: #8261ee;
  text-transform: uppercase;
  color: #fff;
  letter-spacing: 0.25px;
  -webkit-transition: all 0.3s ease 0s;
  -moz-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
}

button.main-button:hover {
  background-color: #ff589e;
}


/* 
---------------------------------------------
header
--------------------------------------------- 
*/
.header-area {
  position: fixed;
  top: 24px;
  left: 0;
  right: 0;
  z-index: 100;
  padding: 0 15px;
  /* La capsule se centre d'elle-meme : l'en-tete ne fait que la porter
     et ne doit pas intercepter les clics autour d'elle. */
  display: flex;
  justify-content: center;
  pointer-events: none;
  transition: top 0.35s cubic-bezier(0.22, 1, 0.36, 1),
              opacity 0.4s ease,
              transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
              visibility 0s;
}

/* Accueil : la capsule s'efface. Le hero porte deja le mot-symbole et
   son bouton d'entree ; la barre lui passait par-dessus sans rien
   ajouter. Elle revient des la page suivante (classe posee par
   custom.js, dans les deux modes : diaporama et flux normal).
   "visibility" plutot que "display: none" : l'en-tete conserve ses
   dimensions, dont custom.js se sert pour reserver la place en haut
   des pages, tout en sortant du parcours clavier. */
.header-area.est-masquee {
  opacity: 0;
  visibility: hidden;
  transform: translateY(-12px);
  transition: opacity 0.4s ease,
              transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
              visibility 0s linear 0.4s;
}

/* La capsule reprend "pointer-events: auto" : sans cela elle resterait
   cliquable pendant le fondu, et indefiniment si les transitions sont
   neutralisees (mouvement reduit). */
.header-area.est-masquee .main-nav {
  pointer-events: none;
}

/* Capsule flottante : sans logo a caler a gauche, une barre pleine
   largeur n'aurait plus rien a ancrer. Elle se dimensionne sur son
   contenu et reste centree. */
.header-area .main-nav {
  pointer-events: auto;
  padding: 6px;
  border-radius: 40px;
  background-color: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  box-shadow: 0 8px 30px rgba(16, 24, 40, 0.10),
              0 1px 2px rgba(16, 24, 40, 0.06);
  transition: padding 0.35s cubic-bezier(0.22, 1, 0.36, 1),
              background-color 0.35s ease,
              box-shadow 0.35s ease;
}

/* Etat compact une fois la page defilee */
.header-area.is-defilee {
  top: 12px;
}

.header-area.is-defilee .main-nav {
  padding: 4px;
  background-color: rgba(255, 255, 255, 0.94);
  box-shadow: 0 6px 24px rgba(16, 24, 40, 0.14),
              0 1px 2px rgba(16, 24, 40, 0.08);
}

.header-area .main-nav .nav {
  display: flex;
  align-items: center;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
  flex-wrap: nowrap;
}

.header-area .main-nav .nav li {
  padding: 0;
}

.header-area .main-nav .nav li a {
  display: block;
  padding: 10px clamp(14px, 2.4vw, 22px);
  font-size: clamp(12px, 1.4vw, 13px);
  font-weight: 500;
  letter-spacing: 0.04em;
  white-space: nowrap;
  color: #3b566e;
  border-radius: 40px;
  transition: color 0.25s ease, background-color 0.25s ease;
}

.header-area .main-nav .nav li a:hover {
  color: #e84c3d;
  background-color: rgba(59, 86, 110, 0.07);
}

/* Section courante : pastille teintee plutot qu'un soulignement. Dans
   une capsule arrondie, la meme forme se repete a l'echelle du lien. */
.header-area .main-nav .nav li a.active {
  color: #e84c3d;
  background-color: rgba(232, 76, 61, 0.12);
}

/*
---------------------------------------------
chaque categorie occupe un ecran
---------------------------------------------
*/

/* Selecteurs doubles (.section / .mini) : "main > section" seul ne
   suffirait pas a battre le "min-height: 215px" de .mini. */
/* Le glissement horizontal deplace le contenu de 70px : sans garde, cela
   creerait une barre de defilement horizontale.
   "clip" et non "hidden" : hidden ferait de <main> un conteneur de
   defilement, et view() resoudrait alors sa timeline sur <main> au lieu
   du document, ce qui casserait les animations. */
main {
  overflow-x: clip;
}

main > section.section,
main > section.xo {
  /* 110px = scroll-padding-top : la section remplit exactement l'espace
     visible sous la barre fixe une fois aimantee. */
  min-height: calc(100vh - 110px);
  min-height: calc(100svh - 110px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/*
---------------------------------------------
animations pilotees par le defilement
---------------------------------------------
*/

/* 
---------------------------------------------
welcome
--------------------------------------------- 
*/
.welcome-area {
  overflow: hidden;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #17202A;
  height: 100vh;
  /* svh : evite le saut de mise en page quand la barre d'adresse
     mobile se retracte. Repli sur 100vh ci-dessus si non supporte. */
  height: 100svh;
}

/* ---------------------------------------------------------------
   Fond anime : formes organiques en aplats
   --------------------------------------------------------------- */
.hero-fond {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  z-index: 0;
}

.hero-fond svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* Assombrissement general des formes. Il porte seul la lisibilite du
   texte blanc : sans lui on tomberait a 3,35:1 sur l'aplat rouge et a
   2,96:1 sur l'or. Le degrade est plein cadre et sans bord visible, il
   se lit comme une ambiance et non comme une tache posee sur le fond
   (un voile radial centre sur le texte avait ete essaye : il se voyait).
   Le creux est place vers 58 %, la ou le bloc de texte se trouve. */
.hero-fond::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(to bottom,
              rgba(23, 32, 42, 0.30) 0%,
              rgba(23, 32, 42, 0.44) 38%,
              rgba(23, 32, 42, 0.52) 58%,
              rgba(23, 32, 42, 0.36) 100%);
  pointer-events: none;
}

/* Seul transform est anime : la composition reste sur le GPU, sans
   recalcul de trace a chaque image. */
.hf-forme {
  transform-box: fill-box;
  transform-origin: center;
  will-change: transform;
}

.hf-1 { animation: hfDerive1 54s ease-in-out infinite alternate; }
.hf-2 { animation: hfDerive2 47s ease-in-out infinite alternate; }
.hf-3 { animation: hfDerive3 61s ease-in-out infinite alternate; }
.hf-4 { animation: hfDerive4 43s ease-in-out infinite alternate; }
.hf-5 { animation: hfDerive5 38s ease-in-out infinite alternate; }

/* Durees volontairement premieres entre elles : la boucle globale ne se
   repete pas de facon perceptible. La rotation d'une forme irreguliere
   suffit a donner l'impression qu'elle se deforme. */
@keyframes hfDerive1 {
  from { transform: translate(0, 0) rotate(0deg) scale(1); }
  to   { transform: translate(4px, -3px) rotate(14deg) scale(1.05); }
}

@keyframes hfDerive2 {
  from { transform: translate(0, 0) rotate(0deg) scale(1); }
  to   { transform: translate(-5px, 3px) rotate(-17deg) scale(1.06); }
}

@keyframes hfDerive3 {
  from { transform: translate(0, 0) rotate(0deg) scale(1); }
  to   { transform: translate(-3px, 4px) rotate(19deg) scale(1.07); }
}

@keyframes hfDerive4 {
  from { transform: translate(0, 0) rotate(0deg) scale(1); }
  to   { transform: translate(5px, -4px) rotate(-13deg) scale(1.08); }
}

@keyframes hfDerive5 {
  from { transform: translate(0, 0) rotate(0deg) scale(1); }
  to   { transform: translate(-4px, 5px) rotate(22deg) scale(1.1); }
}

/* Decoupe courbe du bas : calee sur le bord inferieur quelle que soit
   la hauteur du hero. */
.hero-courbe {
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 100%;
  height: clamp(58px, 9vw, 130px);
  z-index: 1;
  display: block;
}

.welcome-area .header-text {
  position: relative;
  /* au-dessus du fond anime et de la courbe */
  z-index: 2;
  width: 100%;
  text-align: center;
  /* Remonte le bloc pour degager la decoupe courbe, qui occupe
     les ~15 % inferieurs du visuel. */
  padding-bottom: 6vh;
}

.welcome-area .header-text .container {
  position: relative;
}

.welcome-area .header-text h1 {
  margin-bottom: 0;
  color: #fff;
}

/* Le logotype remplace l'ancien sigle typographique. Dimensionne en
   largeur (c'est une image de texte), avec une ombre portee douce qui
   reprend le role de l'ancien text-shadow sur la photo. */
.welcome-area .hero-wordmark {
  display: block;
  margin: 0 auto;
  width: clamp(158px, 24vw, 260px);
}

.welcome-area .hero-wordmark img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 3px 22px rgba(0, 0, 0, 0.38));
}

/* Un seul mot est affiche a la fois : on peut donc doubler la taille et
   passer en graisse 500, bien plus lisible sur une photo chargee que
   l'ancienne ligne complete en graisse 300. */
.welcome-area .hero-tagline {
  display: block;
  margin-top: clamp(26px, 4.5vh, 44px);
  font-size: clamp(1.45rem, 4.4vw, 2.5rem);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.01em;
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.55);
}

/* Classe posee par le JavaScript quand la frappe prend la main.
   Hauteur figee : le curseur en inline-flex fait varier la boite de ligne
   selon qu'un mot est present ou non, ce qui deplacait le texte et le
   bouton situes en dessous. La regle est conditionnee a l'animation pour
   que le repli sans JavaScript garde une hauteur libre et puisse passer
   sur deux lignes en petite largeur. */
.welcome-area .hero-tagline.is-animee {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 1.5em;
}

/* Repli sans JavaScript (ou en mouvement reduit) : la phrase complete
   reste affichee, avec le "et" en retrait comme avant. */
.welcome-area .hero-tagline em {
  font-style: normal;
  opacity: 0.6;
}

.welcome-area .hero-typed {
  display: inline-flex;
  align-items: center;
}

.welcome-area .hero-typed-curseur {
  display: inline-block;
  width: 2px;
  height: 1.06em;
  margin-left: 0.1em;
  background-color: #e84c3d;
  animation: curseurClignote 1.05s steps(2, start) infinite;
}

@keyframes curseurClignote {
  to {
    visibility: hidden;
  }
}

/* Texte lu par les lecteurs d'ecran et indexe : la phrase complete reste
   dans le DOM, l'animation etant purement decorative (aria-hidden). */
.hero-tagline-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Filet d'accent sous le titre */
.welcome-area .header-text h1::after {
  content: '';
  display: block;
  width: 64px;
  height: 2px;
  margin: clamp(22px, 3.4vh, 36px) auto 0;
  border-radius: 2px;
  background-color: rgba(255, 255, 255, 0.55);
}

.welcome-area a.main-button-slider {
  display: inline-block;
  padding: 15px 34px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  border-radius: 40px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.28);
}

.welcome-area a.main-button-slider:hover,
.welcome-area a.main-button-slider:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.34);
}

/* Apparition en cascade a l'ouverture de la page.
   Le bouton est anime via son conteneur .hero-cta : animer le bouton
   lui-meme figerait son transform et casserait l'effet au survol. */
@keyframes heroApparition {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.welcome-area .hero-wordmark,
.welcome-area .hero-tagline,
.welcome-area .hero-cta {
  animation: heroApparition 0.9s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.welcome-area .hero-tagline {
  animation-delay: 0.12s;
}

/* La marge haute remplace celle que portait le paragraphe supprime :
   sans elle le bouton venait se coller au filet d'accent du titre. */
.welcome-area .hero-cta {
  display: inline-block;
  margin-top: clamp(34px, 5vh, 56px);
  animation-delay: 0.24s;
}

@media (max-width: 765px) {
  .welcome-area {
    margin-bottom: 100px;
  }
}

/*
---------------------------------------------
page « a propos »
---------------------------------------------
*/

.ap-colonne-intro {
  position: relative;
}

/* Le motif « strates » passe en filigrane derriere le titre : il apporte
   de la profondeur sans concurrencer la frise, qui porte desormais le
   contenu. Opacite tres basse pour ne pas gener la lecture. */
.ap-filigrane {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(420px, 120%);
  height: auto;
  transform: translate(-50%, -50%);
  color: rgba(255, 255, 255, 0.07);
  pointer-events: none;
  z-index: 0;
}

.ap-filigrane .am-anneau {
  transform-box: fill-box;
  transform-origin: center;
}

.ap-filigrane .am-a2 { transform: rotate(7deg); }
.ap-filigrane .am-a3 { transform: rotate(15deg); }
.ap-filigrane .am-a4 { transform: rotate(24deg); }

/* Respiration tres lente, dans l'esprit du fond anime de l'accueil.
   Chaque anneau part de sa propre inclinaison : des keyframes communes
   le feraient sauter a l'angle d'un autre au demarrage. */
@media (prefers-reduced-motion: no-preference) {
  .ap-filigrane .am-a2 { animation: amTourne2 64s linear infinite; }
  .ap-filigrane .am-a3 { animation: amTourne3 52s linear infinite; }
  .ap-filigrane .am-a4 { animation: amTourne4 44s linear infinite; }
}

@keyframes amTourne2 {
  from { transform: rotate(7deg); }
  to   { transform: rotate(367deg); }
}

@keyframes amTourne3 {
  from { transform: rotate(15deg); }
  to   { transform: rotate(-345deg); }
}

@keyframes amTourne4 {
  from { transform: rotate(24deg); }
  to   { transform: rotate(384deg); }
}

/* Le contenu passe au-dessus du filigrane. */
.ap-colonne-intro > :not(.ap-filigrane) {
  position: relative;
  z-index: 1;
}

.ap-surtitre {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 clamp(8px, 1.4vh, 14px);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  /* Teinte eclaircie de l'accent : #e84c3d ne donne que 4,33:1 sur ce
     fond, sous le seuil pour cette taille. Celle-ci atteint 5,85:1. */
  color: #f27466;
}

.ap-surtitre::before {
  content: '';
  width: clamp(24px, 4vw, 46px);
  height: 2px;
  border-radius: 2px;
  background-color: #f27466;
}

.ap-titre {
  margin: 0 0 clamp(18px, 3vh, 34px);
  font-weight: 500;
  font-size: clamp(2rem, 6vh, 3.4rem);
  line-height: 1.08;
  letter-spacing: -0.015em;
  color: #fff;
}

.ap-intertitre {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
}

.ap-texte {
  margin: 0 0 clamp(18px, 3vh, 32px);
  max-width: 44ch;
  font-size: clamp(0.95rem, 1.9vh, 1.05rem);
  line-height: 1.7;
  letter-spacing: 0.3px;
  color: #a8b0ba;
}

.ap-texte strong {
  color: #fff;
  font-weight: 600;
}

.ap-logotype {
  display: block;
  width: min(160px, 46%);
  height: auto;
}

/* --- Frise chronologique ------------------------------------------ */

/* Le parcours etait un seul paragraphe ou les quatre dates se
   noyaient. En frise, chaque etape se lit d'un coup d'oeil. */
.ap-frise {
  position: relative;
  margin: 0;
  padding: 0 0 0 clamp(26px, 3vw, 34px);
  list-style: none;
}

.ap-etape {
  position: relative;
  padding-bottom: clamp(16px, 2.8vh, 30px);
}

.ap-etape:last-child {
  padding-bottom: 0;
}

/* Segment de rail porte par chaque etape : il s'arrete naturellement a
   la derniere, sans calcul de hauteur. */
.ap-etape::before {
  content: '';
  position: absolute;
  left: calc(-1 * clamp(26px, 3vw, 34px) + 5px);
  top: 14px;
  bottom: 0;
  width: 2px;
  background-color: rgba(255, 255, 255, 0.16);
}

.ap-etape:last-child::before {
  display: none;
}

/* Pastille de l'etape */
.ap-etape::after {
  content: '';
  position: absolute;
  left: calc(-1 * clamp(26px, 3vw, 34px));
  top: 5px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background-color: #17202A;
  border: 2px solid #e84c3d;
}

.ap-etape-fin::after {
  background-color: #e84c3d;
}

.ap-annee {
  display: block;
  margin-bottom: 4px;
  font-size: clamp(0.95rem, 2vh, 1.15rem);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: #f27466;
}

.ap-etape p {
  margin: 0;
  font-size: clamp(0.88rem, 1.75vh, 1rem);
  line-height: 1.6;
  color: #a8b0ba;
}

.ap-etape strong {
  color: #fff;
  font-weight: 600;
}

@media (max-width: 991px) {
  .ap-colonne-intro {
    text-align: center;
    margin-bottom: clamp(20px, 3vh, 34px);
  }

  .ap-surtitre {
    justify-content: center;
  }

  .ap-surtitre::before {
    display: none;
  }

  .ap-texte {
    margin-left: auto;
    margin-right: auto;
  }

  .ap-logotype {
    margin-left: auto;
    margin-right: auto;
  }

  .ap-frise {
    text-align: left;
  }
}

/*
---------------------------------------------
page GitHub
---------------------------------------------
*/

/* Composition en deux colonnes, alignee a gauche : l'ancien encadre
   centre laissait la page presque vide autour de lui. Ici le texte tient
   la moitie gauche et le visuel occupe la droite. */
.gh-colonne-texte {
  text-align: left;
}

.gh-surtitre {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 clamp(10px, 1.8vh, 18px);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  /* Teinte eclaircie de l'accent : le #e84c3d du site ne donne que
     4,33:1 sur ce fond, sous le seuil de 4,5:1 pour cette taille.
     Celle-ci atteint 5,85:1 en restant la meme couleur de marque. */
  color: #f27466;
}

/* Petit filet avant le surtitre : ancre le bloc a gauche. */
.gh-surtitre::before {
  content: '';
  width: clamp(24px, 4vw, 46px);
  height: 2px;
  border-radius: 2px;
  background-color: #f27466;
}

/* Titre volontairement large : c'est lui qui remplit la page. */
.gh-titre {
  margin: 0 0 clamp(14px, 2.4vh, 26px);
  font-weight: 500;
  font-size: clamp(2.8rem, 9vh, 5.4rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: #fff;
}

/* L'ancien gris #777 ne donnait que 3,67:1 sur le fond navy, sous le
   seuil AA de 4,5:1. Celui-ci atteint 7,5:1. */
.gh-texte {
  margin: 0 0 clamp(22px, 3.6vh, 38px);
  max-width: 46ch;
  font-size: clamp(1rem, 2.1vh, 1.2rem);
  line-height: 1.7;
  letter-spacing: 0.3px;
  color: #a8b0ba;
}

.gh-bouton {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 15px 30px;
  border-radius: 40px;
  background-color: #e84c3d;
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.28);
  transition: background-color 0.3s ease, transform 0.3s ease,
              box-shadow 0.3s ease;
}

.gh-bouton svg {
  width: 17px;
  height: 17px;
  fill: currentColor;
  flex: 0 0 auto;
}

.gh-bouton:hover,
.gh-bouton:focus-visible {
  background-color: #983a31;
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.34);
}

/* L'adresse en clair : on sait ou mene le bouton avant de cliquer. */
.gh-adresse {
  margin: clamp(16px, 2.6vh, 26px) 0 0;
  font-size: 12px;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.42);
}

/* --- Colonne visuelle --------------------------------------------- */

.gh-visuel {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
}

/* Halo diffus derriere la marque : evite qu'elle flotte seule sur le
   fond, et rappelle les formes organiques de l'accueil.
   Contenu a 100 % de la colonne : la page etant en overflow-y auto, son
   axe horizontal l'est aussi, et le moindre depassement ferait
   reapparaitre une barre de defilement interne. Le degrade est deja
   transparent a 70 % du rayon, rien n'est visiblement rogne. */
.gh-halo {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%,
              rgba(232, 76, 61, 0.20) 0%,
              rgba(232, 76, 61, 0.07) 45%,
              rgba(232, 76, 61, 0) 70%);
  pointer-events: none;
}

.gh-marque {
  position: relative;
  width: min(320px, 100%);
  height: auto;
  fill: #fff;
  opacity: 0.9;
  filter: drop-shadow(0 18px 40px rgba(0, 0, 0, 0.35));
}

/* Sous 992px la colonne visuelle disparait : la place manque, et elle
   ne ferait qu'allonger une page qui doit tenir dans un ecran. */
@media (max-width: 991px) {
  .gh-colonne-marque {
    display: none;
  }

  .gh-colonne-texte {
    text-align: center;
  }

  .gh-surtitre {
    justify-content: center;
  }

  .gh-surtitre::before {
    display: none;
  }

  .gh-texte {
    margin-left: auto;
    margin-right: auto;
  }
}

/*
---------------------------------------------
page de cloture
---------------------------------------------
*/
.fin-contenu {
  text-align: center;
}

/* Mobile uniquement. En diaporama (>=992px) le pied de page occupe un
   ecran entier et son contenu est centre ; en flux normal il heritait du
   seul "padding-top: 30px" de la regle footer, sans aucune marge basse :
   les mentions se retrouvaient collees au bord inferieur.
   Le min-height evite en plus qu'il se reduise a un mince bandeau. */
@media (max-width: 991px) {
  footer.page {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 60svh;
    padding-top: clamp(56px, 12vh, 110px);
    padding-bottom: clamp(48px, 10vh, 96px);
  }
}

.fin-logotype {
  display: block;
  width: min(210px, 54%);
  height: auto;
  margin: 0 auto clamp(20px, 3.4vh, 40px);
}

.fin-titre {
  margin: 0 0 clamp(18px, 3vh, 32px);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #fff;
}

/* Pastilles nommees plutot que trois pictogrammes de 36px : sur une page
   entiere, des cibles minuscules et sans libelle etaient a la fois
   pauvres visuellement et penibles a viser. */
.fin-liens {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(10px, 1.6vw, 16px);
  margin: 0 0 clamp(28px, 5vh, 56px);
  padding: 0;
  list-style: none;
}

.fin-lien {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 22px;
  border-radius: 40px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  background-color: rgba(255, 255, 255, 0.10);
  color: #fff;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.08em;
  transition: background-color 0.3s ease, border-color 0.3s ease,
              color 0.3s ease, transform 0.3s ease;
}

.fin-lien svg {
  width: 17px;
  height: 17px;
  fill: currentColor;
  flex: 0 0 auto;
}

/* Le pseudo Discord n'est pas cliquable : meme pastille, mais sans
   affordance de lien. Le curseur texte et la selection facilitee
   indiquent qu'il est la pour etre recopie. */
.fin-lien-fixe {
  cursor: text;
}

.fin-pseudo {
  -webkit-user-select: all;
  user-select: all;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
}

/* Inversion au survol : reservee aux vraies pastilles cliquables. */
a.fin-lien:hover,
a.fin-lien:focus-visible {
  background-color: #fff;
  border-color: #fff;
  color: #8e3229;
  transform: translateY(-2px);
}

.fin-mentions {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* 62 % ne donnait que 3,05:1 sur l'arret le plus clair du degrade ;
     90 % atteint 4,77:1. La hierarchie tient a la taille, pas a la
     transparence. */
  color: rgba(255, 255, 255, 0.90);
}

/* Remplace un style en ligne "color: white" laisse par le modele. */
.fin-protege {
  display: block;
  margin-top: 8px;
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.fin-protege:hover,
.fin-protege:focus-visible {
  color: #fff;
}


/*
---------------------------------------------
page Xonaria
---------------------------------------------
*/

/* Xonaria a sa propre identite : noir sur blanc, trace geometrique fin,
   beaucoup de vide. On l'assume au lieu de la plier a la palette PZH.
   Le fond est celui du logo lui-meme (#fcfdfc), a peine adouci pour que
   le fondu depuis la page sombre precedente ne soit pas un flash. */
.xo {
  background-color: #f4f4f5;
  color: #111;
  overflow: hidden;
}

.xo-contenu {
  position: relative;
  z-index: 1;
  text-align: center;
}

.xo-logo {
  display: block;
  width: min(420px, 76%);
  height: auto;
  margin: 0 auto clamp(26px, 5vh, 56px);
}

/* Corps genereux et interlettrage large : la marque respire, comme sur
   la banniere. */
.xo-annonce {
  margin: 0 0 clamp(26px, 5vh, 52px);
  font-size: clamp(1.15rem, 3vh, 1.75rem);
  font-weight: 300;
  letter-spacing: 0.04em;
  color: #111;
}

/* Les points d'attente s'animent : le projet est en cours, pas fige. */
.xo-points {
  display: inline-block;
  letter-spacing: 0.12em;
}

@media (prefers-reduced-motion: no-preference) {
  .xo-points {
    animation: xoAttente 1.8s steps(4, end) infinite;
    clip-path: inset(0 100% 0 0);
  }
}

@keyframes xoAttente {
  to {
    clip-path: inset(0 0 0 0);
  }
}

/* Bouton en contour fin plutot qu'en aplat colore : l'identite Xonaria
   n'a pas de couleur d'accent, tout repose sur le trait. */
.xo-bouton {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 30px;
  border: 1.5px solid #111;
  border-radius: 40px;
  color: #111;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: background-color 0.3s ease, color 0.3s ease,
              transform 0.3s ease;
}

/* Icone de lien externe, en trait pour s'accorder au reste. */
.xo-bouton svg {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.xo-bouton:hover,
.xo-bouton:focus-visible {
  background-color: #111;
  color: #f4f4f5;
  transform: translateY(-2px);
}

/* Trace ascendant, cale en bas a droite comme sur la banniere. */
.xo-trace {
  position: absolute;
  right: 0;
  bottom: 0;
  width: min(620px, 62%);
  height: auto;
  opacity: 0.5;
  pointer-events: none;
  z-index: 0;
}

@media (max-width: 991px) {
  .xo-trace {
    width: 92%;
    opacity: 0.3;
  }
}

/* Utilitaire : visible des lecteurs d'ecran uniquement. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}


/*
---------------------------------------------
fleches de diapositive
---------------------------------------------
*/

/* Hors de <main>, donc elles ne suivent pas le fondu des pages et
   restent lisibles pendant les transitions. */
.diapo-nav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: clamp(18px, 3.5vh, 40px);
  z-index: 60;
  display: flex;
  justify-content: space-between;
  padding: 0 clamp(16px, 4vw, 48px);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.35s ease, visibility 0.35s;
}

/* Classe posee par le JavaScript a partir de la deuxieme page : sur
   l'accueil, le bouton du hero suffit a inviter a avancer. */
.diapo-nav.est-visible {
  opacity: 1;
  visibility: visible;
}

/* Seuls les boutons recoivent les clics : le conteneur s'etend sur toute
   la largeur et intercepterait sinon toute la bande basse de l'ecran. */
.diapo-nav.est-visible .diapo-fleche {
  pointer-events: auto;
}

/* Meme traitement que la capsule de navigation : un fond clair
   translucide avec un chevron sombre reste lisible aussi bien sur les
   pages sombres que sur la page Xonaria, qui est blanche. */
.diapo-fleche {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(42px, 6vh, 52px);
  height: clamp(42px, 6vh, 52px);
  padding: 0;
  border: 1px solid rgba(16, 24, 40, 0.10);
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  box-shadow: 0 8px 26px rgba(16, 24, 40, 0.16);
  color: #3b566e;
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease,
              transform 0.25s ease, opacity 0.25s ease;
}

.diapo-fleche svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.diapo-fleche:hover,
.diapo-fleche:focus-visible {
  background-color: #fff;
  color: #e84c3d;
  transform: scale(1.06);
}

/* Bout de course : le bouton reste en place pour ne pas faire sauter la
   mise en page, mais il est estompe et hors du parcours clavier. */
.diapo-fleche:disabled {
  opacity: 0.25;
  cursor: default;
  box-shadow: none;
}

.diapo-fleche:disabled:hover {
  background-color: rgba(255, 255, 255, 0.82);
  color: #3b566e;
  transform: none;
}


/* 
---------------------------------------------
features
--------------------------------------------- 
*/
.features-small-item {
  cursor: pointer;
  display: block;
  background: #FFFFFF;
  box-shadow: 0 2px 48px 0 rgba(0, 0, 0, 0.10);
  -webkit-border-radius: 20px;
  -moz-border-radius: 20px;
  border-radius: 20px;
  padding: 30px;
  text-align: center;
  -webkit-transition: all 0.3s ease 0s;
  -moz-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
  position: relative;
  margin-bottom: 30px;
}

.features-small-item:hover .icon {
  background-color: #e84c3d;
}

.features-small-item .icon {
  -webkit-transition: all 0.3s ease 0s;
  -moz-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
  width: 90px;
  height: 90px;
  line-height: 90px;
  margin: auto;
  position: relative;
  margin-bottom: 30px;
  background: #8261ee;
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  border-radius: 50%;
}

.features-small-item .icon i {
  font-size: 18px;
  color: #fff;
}

.features-small-item .features-title {
  font-weight: 500;
  font-size: 18px;
  color: #1e1e1e;
  letter-spacing: 0.7px;
  margin-bottom: 15px;
  position: relative;
  z-index: 2;
}

.features-small-item p {
  font-weight: 400;
  font-size: 13px;
  color: #777;
  letter-spacing: 0.5px;
  line-height: 25px;
  position: relative;
  z-index: 2;
}

.features-small-item a {
  float: right;
  position: relative;
  z-index: 2;
}

.home-feature {
  padding-bottom: 0px;
  padding-top: 30px;
  margin-top: -220px;
  z-index: 9;
}

@media (max-width: 991px) {
  .home-feature {
    padding-bottom: 0px;
    padding-top: 0px;
    margin-top: 0px;
  }
}

@media (max-width: 991px) {
  .parallax {
    padding-top: 60px;
    padding-bottom: 60px;
    min-height: auto;
  }
  .parallax .content {
    position: relative !important;
    top: 0% !important;
    transform: perspective(1px) translateY(0%) !important;
  }
}
/* 
---------------------------------------------
pricing
--------------------------------------------- 
*/
.pricing-item {
  background: #FFFFFF;
  box-shadow: 0 2px 48px 0 rgba(0, 0, 0, 0.1);
  border-radius: 20px;
  margin-bottom: 30px;
  margin-top: 20px;
  padding: 30px 0px 40px 0px;
}

.pricing-item.active .pricing-header {
  position: relative;
}

.pricing-item.active .pricing-header .pricing-title {
  color: #1e1e1e;
}

.pricing-item.active .pricing-body .price-wrapper {
  background-color: #e84c3d;
}

.pricing-item.active .pricing-body .price-wrapper .currency {
  color: #fff;
}

.pricing-item.active .pricing-body .price-wrapper .price {
  color: #fff;
}

.pricing-item.active .pricing-body .price-wrapper .period {
  color: #fff;
}

.pricing-item .pricing-header {
  text-align: center;
  display: block;
  position: relative;
  padding-bottom: 10px;
}

.pricing-item .pricing-header .pricing-title {
  font-weight: 500;
  font-size: 17px;
  letter-spacing: 0.25px;
  color: #1e1e1e;
  width: 180px;
  height: 40px;
  line-height: 40px;
  left: 0px;
  right: 0px;
  margin: auto;
}

.pricing-item .pricing-body {
  margin-bottom: 40px;
}

.pricing-item .pricing-body .price-wrapper {
  text-align: center;
  padding-top: 20px;
  padding-bottom: 13px;
  background: #8261ee;
  width: 80%;
  margin: auto;
  margin-bottom: 40px;
  margin-top: 5px;
  border-radius: 20px;
}

.pricing-item .pricing-body .price-wrapper .currency {
  height: 47px;
  font-weight: 500;
  font-size: 32px;
  color: #fff;
  position: relative;
  top: -1px;
}

.pricing-item .pricing-body .price-wrapper .price {
  font-weight: 500;
  font-size: 28px;
  color: #fff;
}

.pricing-item .pricing-body .price-wrapper .period {
  font-weight: 400;
  font-size: 14px;
  color: #fff;
  display: block;
  letter-spacing: 0.88px;
}

.pricing-item .pricing-body .list li {
  text-align: center;
  margin-bottom: 12px;
  font-weight: 400;
  font-size: 13px;
  color: #7a7a7a;
  letter-spacing: 0.25px;
  text-decoration: line-through;
}

.pricing-item .pricing-body .list li.active {
  color: #7a7a7a;
  text-decoration: none;
}

.pricing-item .pricing-footer {
  text-align: center;
  margin-top: 50px;
}

/* 
---------------------------------------------
blog
--------------------------------------------- 
*/
.blog-post-thumb {
  text-align: center;
  margin-bottom: 30px;
}

.blog-post-thumb.big .img {
  height: 400px;
}

.blog-post-thumb .img {
  overflow: hidden;
  border-radius: 20px;
  position: relative;
  height: 200px;
}

.blog-post-thumb .blog-content {
  margin-top: -30px;
  padding-top: 50px;
}

.blog-post-thumb h3 {
  margin-bottom: 20px !important;
}

.blog-post-thumb h3 a {
  font-weight: 500;
  font-size: 18px;
  color: #fff;
  letter-spacing: 0.25px;
  line-height: 26px;
  -webkit-transition: all 0.3s ease 0s;
  -moz-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
}

.blog-post-thumb h3 a:hover {
  color: #e84c3d;
}

.blog-post-thumb .text {
  font-weight: 400;
  font-size: 13px;
  color: #777;
  letter-spacing: 0.26px;
  line-height: 26px;
  margin-bottom: 15px;
}

.blog-post-thumb .post-footer span {
  float: left;
  height: 30px;
  line-height: 30px;
  font-weight: 300;
  font-size: 14px;
  color: #777;
  padding-left: 30px;
}

.blog-post-thumb a.main-button  {
  margin-top: 10px;
  display: inline-block;
}

.blog-list .blog-post-thumb {
  text-align: left;
}


/* 
---------------------------------------------
contact
--------------------------------------------- 
*/

#contact-us {
  padding: 160px 0px;
}

#contact-us h5 {
  font-weight: 500;
  font-size: 18px;
  color: #1e1e1e;
  letter-spacing: 0.25px;
  line-height: 26px;
}

.contact-text {
  font-weight: 400;
  font-size: 14px;
  color: #6F8BA4;
  letter-spacing: 0.6px;
  line-height: 26px;
}

.contact-text p {
  margin-bottom: 28px;
}

.contact-form input,
.contact-form textarea {
  color: #777;
  font-size: 14px;
  border: 1px solid #eee;
  width: 100%;
  height: 50px;
  outline: none;
  padding-left: 20px;
  padding-right: 20px;
  border-radius: 25px;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  margin-bottom: 30px;
}

.contact-form textarea {
  height: 150px;
  resize: none;
  padding: 20px;
}

/* 
---------------------------------------------
footer
--------------------------------------------- 
*/
/* L'ancien fond etait un faux degrade : #e84c3d aux deux extremites,
   donc un aplat. Et le blanc dessus ne donnait que 3,80:1, sous le seuil
   AA. Ce degrade descend vers le navy du site, ce qui raccroche la page
   de cloture au reste ; tous ses arrets tiennent le blanc au-dessus de
   5,5:1. */
footer {
  background-image: linear-gradient(165deg,
                    #b8402f 0%,
                    #9c3529 42%,
                    #6d2a24 74%,
                    #17202A 100%);
  padding-top: 30px;
}

footer .social {
  overflow: hidden;
  margin-top: 10px;
  text-align: center;
}

footer .social li {
  margin: 0px 10px;
  display: inline-block;
}

footer .social li a {
  color: #983a31;
   text-align: center;
  background-color: #fff;
  width: 36px;
  height: 36px;
  line-height: 36px;
  border-radius: 50%;
  display: inline-block;
  font-size: 16px;
  -webkit-transition: all 0.3s ease 0s;
  -moz-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
}

footer .social li a:hover {
  background-color: #983a31;
  color: #fff;
}

footer .copyright {
  text-align: center;
  border-top: 1px solid rgba(250,250,250,0.2);
  margin-top: 30px;
  padding-top: 30px;
  padding-bottom: 30px;
  font-weight: 400;
  font-size: 12px;
  color: #fff;
  letter-spacing: 0.88px;
  text-transform: uppercase;
}

@media (max-width: 991px) {
  footer .text {
    margin-bottom: 30px;
  }
  footer h5 {
    margin-bottom: 15px;
  }
  footer .footer-nav {
    margin-bottom: 30px;
  }
}

/* 
---------------------------------------------
preloader
--------------------------------------------- 
*/
#preloader {
  overflow: hidden;
  background-image: linear-gradient(135deg, #e84c3d 0%, #e84c3d 100%);
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  position: fixed;
  z-index: 9999;
  color: #fff;
}

#preloader .jumper {
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  display: block;
  position: absolute;
  margin: auto;
  width: 50px;
  height: 50px;
}

#preloader .jumper > div {
  background-color: #fff;
  width: 10px;
  height: 10px;
  border-radius: 100%;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
  position: absolute;
  opacity: 0;
  width: 50px;
  height: 50px;
  -webkit-animation: jumper 1s 0s linear infinite;
  animation: jumper 1s 0s linear infinite;
}

#preloader .jumper > div:nth-child(2) {
  -webkit-animation-delay: 0.33333s;
  animation-delay: 0.33333s;
}

#preloader .jumper > div:nth-child(3) {
  -webkit-animation-delay: 0.66666s;
  animation-delay: 0.66666s;
}

@-webkit-keyframes jumper {
  0% {
    opacity: 0;
    -webkit-transform: scale(0);
    transform: scale(0);
  }
  5% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(1);
    transform: scale(1);
    opacity: 0;
  }
}

@keyframes jumper {
  0% {
    opacity: 0;
    -webkit-transform: scale(0);
    transform: scale(0);
  }
  5% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

/*
---------------------------------------------
icônes sociales (SVG inline, remplace Font Awesome)
---------------------------------------------
*/
footer ul.social li a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

footer ul.social li a svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

/* Respect de prefers-reduced-motion */
@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;
  }
}

/* Repli si JavaScript est désactivé : le préchargeur ne doit pas masquer la page */
.no-js #preloader {
  display: none;
}

/* Focus visible au clavier (accessibilité) */
a:focus-visible,
button:focus-visible {
  outline: 2px solid #e84c3d;
  outline-offset: 3px;
}


/*
---------------------------------------------
diaporama : pages superposees, fondu enchaine
---------------------------------------------
*/

/* Toute la mise en pile est conditionnee a la prise en charge des
   animations pilotees par le defilement. Sans elle (Safari < 26,
   Firefox < 144), rien ne s'applique : la page reste un document qui
   defile normalement, avec toutes ses sections lisibles. C'est le repli,
   et il doit rester intact — d'ou le fait que ce bloc n'ecrase rien en
   dehors de @supports.

   min-width: 992px — le diaporama est reserve aux grands ecrans.
   Sur mobile il se comportait mal, pour deux raisons de fond :

   1. La hauteur de la fenetre change quand la barre d'adresse se
      retracte. Les reperes d'aimantation sont figes en svh alors que le
      fondu est calcule sur la course reelle, qui varie : les deux se
      desynchronisent et l'on s'arrete entre deux pages.
   2. Au toucher, un geste commence dans le conteneur de defilement le
      plus proche et y reste. Des qu'une page deborde un tant soit peu,
      elle capte le geste et le document n'avance plus.

   Le mobile prend donc le meme repli : un document qui defile
   normalement, sans aimantation ni empilement. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 992px) {

    /* L'aimantation par section n'a plus de sens : toutes les pages
       occupent la meme position dans le document. */
    /* Aimantation obligatoire : on ne doit jamais pouvoir s'arreter au
       milieu d'un fondu. Les points d'ancrage ne sont pas les pages
       (elles sont toutes empilees au meme endroit) mais les reperes de
       la piste. */
    html {
      scroll-snap-type: y mandatory;
      scroll-padding-top: 0;
    }

    /* Les animations d'entree par section sont remplacees par le fondu. */
    #apropos > .container,
    #xonaria .xo-contenu,
    #github > .container {
      animation-name: none;
    }

    /* Une seule cellule de grille pour toutes les pages : elles se
       superposent exactement, donc aucune ne se deplace a l'ecran.
       C'est ce qui supprime toute sensation de defilement. */
    main {
      display: grid;
      /* Le glissement horizontal etant desactive ici, la garde
         "overflow-x: clip" ne sert plus. On la retire : un ancetre qui
         rogne peut perturber position: sticky, et toute la pile en
         depend. */
      overflow-x: visible;
    }

    main > .page,
    main > .piste {
      grid-area: 1 / 1;
      scroll-snap-align: none;
    }

    main > .page {
      position: sticky;
      top: 0;
      height: 100svh;
      min-height: 0;
      /* Filet indispensable : Xonaria depasse l'ecran sur mobile.
         Sans cela son bas serait purement inaccessible. */
      overflow-y: auto;
      overscroll-behavior: auto;
      opacity: 0;
      animation-fill-mode: both;
      animation-timing-function: linear;
      animation-timeline: scroll(root block);
    }

    /* La piste ne sert qu'a donner sa hauteur au document : six ecrans,
       soit cinq ecrans de defilement pour cinq transitions. */
    main > .piste {
      pointer-events: none;
    }

    /* Un repere par page. Sa hauteur fixe la distance de defilement
       entre deux pages ; "scroll-snap-stop: always" interdit d'en sauter
       plusieurs d'un seul geste, donc un coup de molette = une page. */
    main > .piste > .repere {
      height: 55svh;
      scroll-snap-align: start;
      scroll-snap-stop: always;
    }

    /* Le dernier occupe un ecran entier : sans lui, la derniere page
       n'aurait pas de quoi rester affichee en fin de course. */
    main > .piste > .repere-fin {
      height: 100svh;
    }

    /* La page "A propos" porte desormais deux paves : on resserre son
       rembourrage pour qu'elle tienne dans un ecran plus souvent. */
    #apropos.page-dense {
      padding-top: 40px;
      padding-bottom: 30px;
    }

    /* Chaque page occupe une tranche de 20 % de la course de defilement,
       et chevauche ses voisines : c'est ce chevauchement qui produit le
       fondu enchaine plutot qu'une coupure. */
    #menu {
      animation-name: fonduPremiere;
      animation-range: 0% 25%;
    }

    #apropos {
      animation-name: fonduMilieu;
      animation-range: 0% 50%;
    }

    #xonaria {
      animation-name: irisXonaria;
      animation-range: 25% 75%;
    }

    #github {
      animation-name: fonduMilieu;
      animation-range: 50% 100%;
    }

    #fin {
      animation-name: fonduDerniere;
      animation-range: 75% 100%;
    }


    /* ---------------------------------------------------------------
       Compression verticale
       Hors diaporama ces sections s'enchainent et peuvent respirer.
       Empilees, chacune doit tenir dans un seul ecran : sans cela un
       defilement interne apparait, ce qui contredit le principe meme du
       fondu enchaine. On resserre donc les rythmes verticaux.
       --------------------------------------------------------------- */
    main > .page.section {
      padding-top: clamp(16px, 4vh, 48px);
      padding-bottom: clamp(16px, 3vh, 40px);
    }

    /* Le filet separateur de la page fusionnee coute une trentaine de
       pixels pour un apport purement decoratif. */
    #apropos .hr {
      margin-top: clamp(8px, 2vh, 30px);
      margin-bottom: clamp(8px, 2vh, 30px);
    }


    /* Voile de saut. Le defilement fluide traverse toutes les positions
       intermediaires ; le fondu etant pilote par la position, les pages
       du milieu apparaissaient brievement. On masque donc le trajet, on
       saute instantanement, puis on decouvre. */
    .voile-saut {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: #17202A;
      opacity: 0;
      pointer-events: none;
      /* sous l'en-tete (z-index 100), qui reste visible pendant le saut */
      z-index: 50;
      transition: opacity 240ms ease;
    }

    .voile-saut.est-visible {
      opacity: 1;
    }

    /* Le pied de page devient une page a part entiere : on centre son
       contenu au lieu de le coller en haut. */
    footer.page {
      display: flex;
      flex-direction: column;
      justify-content: center;
    }
  }
}

/* pointer-events suit l'opacite : une page transparente ne doit pas
   intercepter les clics de celle qui est visible dessous. */
/* Transition « profondeur ».
   L'opacite seule donnait un fondu plat. Ici chaque page arrive de
   l'arriere-plan, legerement reduite et floue, puis se pose au net ; en
   partant elle recule et se defocalise. Le mouvement se lit comme une
   mise au point, pas comme un defilement.

   Toutes les echelles restent <= 1 : une page agrandie deborderait de la
   fenetre et provoquerait une barre de defilement horizontale.
   Le flou n'affecte pas la mise en page, lui, et ne pose pas ce risque. */
@keyframes fonduPremiere {
  0% {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
    pointer-events: auto;
  }
  38% {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
  }
  100% {
    opacity: 0;
    transform: scale(0.94);
    filter: blur(7px);
    pointer-events: none;
  }
}

@keyframes fonduMilieu {
  0% {
    opacity: 0;
    transform: scale(0.94);
    filter: blur(7px);
    pointer-events: none;
  }
  26% {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
    pointer-events: auto;
  }
  74% {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
  }
  100% {
    opacity: 0;
    transform: scale(0.94);
    filter: blur(7px);
    pointer-events: none;
  }
}

@keyframes fonduDerniere {
  0% {
    opacity: 0;
    transform: scale(0.94);
    filter: blur(7px);
    pointer-events: none;
  }
  62% {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
    pointer-events: auto;
  }
  100% {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
  }
}

/* Xonaria a un fond qui lui est propre : c'est la seule page ou une
   ouverture en iris est lisible. Elle ne se referme pas en sortant, ce
   qui serait redondant avec l'arrivee de la page suivante. */
@keyframes irisXonaria {
  0% {
    opacity: 0;
    clip-path: circle(16% at 50% 50%);
    filter: blur(6px);
    pointer-events: none;
  }
  26% {
    opacity: 1;
    clip-path: circle(150% at 50% 50%);
    filter: blur(0);
    pointer-events: auto;
  }
  74% {
    opacity: 1;
    clip-path: circle(150% at 50% 50%);
    filter: blur(0);
  }
  100% {
    opacity: 0;
    clip-path: circle(150% at 50% 50%);
    transform: scale(0.94);
    filter: blur(7px);
    pointer-events: none;
  }
}

/* Petits ecrans : deux flous plein ecran simultanes pendant une
   transition coutent cher aux GPU mobiles. On garde la profondeur, on
   retire le flou. */
@media (max-width: 767px) {
  @keyframes fonduPremiere {
    0% { opacity: 1; transform: scale(1); pointer-events: auto; }
    38% { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(0.94); pointer-events: none; }
  }

  @keyframes fonduMilieu {
    0% { opacity: 0; transform: scale(0.94); pointer-events: none; }
    26% { opacity: 1; transform: scale(1); pointer-events: auto; }
    74% { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(0.94); pointer-events: none; }
  }

  @keyframes fonduDerniere {
    0% { opacity: 0; transform: scale(0.94); pointer-events: none; }
    62% { opacity: 1; transform: scale(1); pointer-events: auto; }
    100% { opacity: 1; transform: scale(1); }
  }

  @keyframes irisXonaria {
    0% { opacity: 0; clip-path: circle(16% at 50% 50%); pointer-events: none; }
    26% { opacity: 1; clip-path: circle(150% at 50% 50%); pointer-events: auto; }
    74% { opacity: 1; clip-path: circle(150% at 50% 50%); }
    100% { opacity: 0; clip-path: circle(150% at 50% 50%); transform: scale(0.94); pointer-events: none; }
  }
}

