/* =========================================================================
   Couche d'animation d'ella-solution.xyz

   Fichier autonome, charge apres le bundle. Pour tout annuler, il suffit de
   retirer les deux balises correspondantes dans index.html : aucune ligne du
   bundle n'est modifiee.

   Regle appliquee partout : rien n'est jamais cache de facon definitive.
   Les etats invisibles ne sont poses que par le script, et un filet de
   securite les leve au bout de trois secondes quoi qu'il arrive.
   ========================================================================= */

:root {
  --violet: #833ab4;
  --rose: #e1306c;
  --orange: #f77737;
  --cyan: #00b7d7;
}

/* -------------------------------------------------------------------------
   1. Aurore de fond
   Trois masses colorees tres floues qui derivent lentement derriere le
   contenu. C'est ce qui donne la profondeur : le fond cesse d'etre un aplat
   noir et devient une matiere.
   ------------------------------------------------------------------------- */
#aurore {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  opacity: .55;
}
#aurore span {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  will-change: transform;
}
#aurore span:nth-child(1) {
  width: 46vw; height: 46vw; left: -10vw; top: -8vw;
  background: radial-gradient(circle, rgba(131, 58, 180, .55), transparent 68%);
  animation: derive-a 26s ease-in-out infinite;
}
#aurore span:nth-child(2) {
  width: 40vw; height: 40vw; right: -8vw; top: 18vh;
  background: radial-gradient(circle, rgba(225, 48, 108, .42), transparent 68%);
  animation: derive-b 32s ease-in-out infinite;
}
#aurore span:nth-child(3) {
  width: 38vw; height: 38vw; left: 22vw; bottom: -12vw;
  background: radial-gradient(circle, rgba(247, 119, 55, .34), transparent 68%);
  animation: derive-c 38s ease-in-out infinite;
}
@keyframes derive-a {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  33%      { transform: translate3d(8vw, 6vh, 0) scale(1.14); }
  66%      { transform: translate3d(-4vw, 12vh, 0) scale(.92); }
}
@keyframes derive-b {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(-10vw, 14vh, 0) scale(1.2); }
}
@keyframes derive-c {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  40%      { transform: translate3d(12vw, -8vh, 0) scale(1.1); }
  75%      { transform: translate3d(-6vw, -4vh, 0) scale(.95); }
}

/* Le contenu de l'application doit rester au-dessus de l'aurore. */
#root { position: relative; z-index: 1; }

/* -------------------------------------------------------------------------
   2. Barre de progression de lecture
   La page fait plus de vingt mille pixels. Un repere evite l'impression de
   defiler dans le vide.
   ------------------------------------------------------------------------- */
#lecture {
  position: fixed;
  top: 0; left: 0;
  height: 2px; width: 0;
  z-index: 120;
  background: linear-gradient(90deg, var(--violet), var(--rose), var(--orange));
  box-shadow: 0 0 12px rgba(225, 48, 108, .55);
  transition: width .1s linear;
  pointer-events: none;
}

/* -------------------------------------------------------------------------
   3. Revelation au defilement
   Etat pose par le script uniquement, jamais par defaut.
   ------------------------------------------------------------------------- */
.anim-cache {
  opacity: 0;
  transform: translateY(34px);
}
.anim-pret {
  transition: opacity .8s cubic-bezier(.16, 1, .3, 1),
              transform .8s cubic-bezier(.16, 1, .3, 1);
}
.anim-vu {
  opacity: 1 !important;
  transform: none !important;
}

/* Cascade : chaque carte arrive avec un leger retard sur la precedente. */
.anim-cascade > * { transition-delay: 0ms; }
.anim-cascade.anim-vu > *:nth-child(1) { transition-delay: 0ms; }
.anim-cascade.anim-vu > *:nth-child(2) { transition-delay: 80ms; }
.anim-cascade.anim-vu > *:nth-child(3) { transition-delay: 160ms; }
.anim-cascade.anim-vu > *:nth-child(4) { transition-delay: 240ms; }
.anim-cascade.anim-vu > *:nth-child(5) { transition-delay: 320ms; }
.anim-cascade.anim-vu > *:nth-child(6) { transition-delay: 400ms; }
.anim-cascade.anim-vu > *:nth-child(7) { transition-delay: 480ms; }
.anim-cascade.anim-vu > *:nth-child(8) { transition-delay: 560ms; }

/* -------------------------------------------------------------------------
   4. Titre principal : apparition mot a mot
   ------------------------------------------------------------------------- */
.anim-mot {
  display: inline-block;
  opacity: 0;
  transform: translateY(28px) rotate(2deg);
  animation: mot-entre .85s cubic-bezier(.16, 1, .3, 1) forwards;
}
@keyframes mot-entre {
  to { opacity: 1; transform: none; }
}

/* -------------------------------------------------------------------------
   5. Cartes : halo qui suit le curseur, et liseré en degrade
   Le halo est ce qui donne l'impression que la carte reagit vraiment, plutot
   que de simplement changer de couleur au survol.
   ------------------------------------------------------------------------- */
.glass-card {
  position: relative;
  isolation: isolate;
  transition: transform .35s cubic-bezier(.16, 1, .3, 1),
              box-shadow .35s ease;
}
.glass-card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(
    340px circle at var(--x, 50%) var(--y, 50%),
    rgba(225, 48, 108, .16),
    transparent 62%
  );
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
  z-index: -1;
}
.glass-card::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, var(--violet), var(--rose), var(--orange));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
}
@media (hover: hover) {
  .glass-card:hover {
    transform: translateY(-6px);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
  }
  .glass-card:hover::before { opacity: 1; }
  .glass-card:hover::after  { opacity: .6; }
}

/* -------------------------------------------------------------------------
   6. Boutons
   Une lueur qui balaie le bouton principal, et un enfoncement au clic qui
   confirme l'action sur mobile, ou le survol n'existe pas.
   ------------------------------------------------------------------------- */
.ig-gradient {
  position: relative;
  overflow: hidden;
}
.ig-gradient::after {
  content: "";
  position: absolute;
  top: 0; left: -120%;
  width: 60%; height: 100%;
  background: linear-gradient(
    100deg, transparent, rgba(255, 255, 255, .32), transparent
  );
  transform: skewX(-18deg);
  pointer-events: none;
}
@media (hover: hover) {
  .ig-gradient:hover::after { animation: reflet .85s ease; }
}
@keyframes reflet {
  to { left: 140%; }
}
a[href^="tel:"]:active,
a[href*="wa.me"]:active,
button:active {
  transform: scale(.97);
}
a[href^="tel:"], a[href*="wa.me"], button {
  transition: transform .16s ease;
}

/* -------------------------------------------------------------------------
   7. Reglage systeme
   Certaines personnes desactivent les animations pour raisons medicales.
   Rien n'etait prevu jusqu'ici. On coupe le mouvement sans rien masquer.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .anim-cache, .anim-mot { opacity: 1 !important; transform: none !important; }
  #aurore, #lecture { display: none; }
}

/* -------------------------------------------------------------------------
   8. Accessibilite (audit du 10 aout 2026)

   Mesures faites sur la page rendue, pas sur le code source. Ces regles ne
   sont dans aucune couche CSS : elles passent donc devant les utilitaires du
   bundle, qui sont dans @layer utilities, sans avoir besoin de !important et
   sans qu'un seul octet du fichier compile soit modifie.
   ------------------------------------------------------------------------- */

/* Gris trop pales sur fond sombre.
   Mesure : blanc a 30 % donnait 2,55:1 et blanc a 40 % donnait 3,80:1,
   pour un minimum exige de 4,5:1 sur du texte courant. */
.text-white\/30 { color: rgba(255, 255, 255, .50); }
.text-white\/40 { color: rgba(255, 255, 255, .52); }

/* Indicateur de focus au clavier.
   L'anneau herite du bundle mesure 1 px a 50 % d'opacite : invisible sur ce
   fond. Celui-ci atteint 9,5:1 contre le fond de page et 3,2:1 contre la
   couleur la plus foncee du degrade, donc il reste lisible sur les boutons. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid #cfa3ff;
  outline-offset: 2px;
}
