/* ==========================================================================
   190 — Enter / Exit Pack
   Primitives d'apparition/disparition : 8 presets appariés (entrée + sortie
   cohérentes), posables sur n'importe quel élément via .eep-enter--<preset>
   et .eep-exit--<preset>. `eep` = Enter/Exit Pack (préfixe documenté README).
   Réglables via --eep-duration / --eep-distance / --eep-delay (fallbacks).
   Les sorties ne sont PAS l'entrée inversée : plus rapides (0.6×), easing
   ease-in, et elles CONTINUENT le mouvement au lieu de le rembobiner.
   Le pack CSS marche seul ; anim.js (optionnel) ajoute stagger, entrée
   viewport et dismiss animé. Démo : .eep-demo (panneau + cartes).
   ========================================================================== */

/* --- Entrées : rythme commun ----------------------------------------------
   fill-mode both = l'élément reste caché pendant --eep-delay (stagger sans
   flash), puis conserve son état final. */

.eep-enter--fade-up,
.eep-enter--fade-down,
.eep-enter--scale-pop,
.eep-enter--blur-in,
.eep-enter--slide-left,
.eep-enter--slide-right,
.eep-enter--flip-in,
.eep-enter--reveal-clip {
  animation-duration: var(--eep-duration, 0.5s);
  animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  animation-delay: var(--eep-delay, 0s);
  animation-fill-mode: both;
}

/* --- Sorties : rythme commun ----------------------------------------------
   Plus courtes (0.6× l'entrée), ease-in, pas de délai : une sortie demandée
   part tout de suite. forwards = l'élément reste caché après l'animation
   (le retrait du DOM est du ressort de anim.js ou du code appelant). */

.eep-exit--fade-up,
.eep-exit--fade-down,
.eep-exit--scale-pop,
.eep-exit--blur-in,
.eep-exit--slide-left,
.eep-exit--slide-right,
.eep-exit--flip-in,
.eep-exit--reveal-clip {
  animation-duration: calc(var(--eep-duration, 0.5s) * 0.6);
  animation-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2);
  animation-fill-mode: forwards;
}

/* --- 1. fade-up : monte en fondu / sort en continuant vers le haut -------- */

.eep-enter--fade-up { animation-name: eep-in-fade-up; }
.eep-exit--fade-up { animation-name: eep-out-fade-up; }

@keyframes eep-in-fade-up {
  from { opacity: 0; transform: translateY(var(--eep-distance, 16px)); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes eep-out-fade-up {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(calc(var(--eep-distance, 16px) * -0.6)); }
}

/* --- 2. fade-down : descend en fondu / sort en continuant vers le bas ----- */

.eep-enter--fade-down { animation-name: eep-in-fade-down; }
.eep-exit--fade-down { animation-name: eep-out-fade-down; }

@keyframes eep-in-fade-down {
  from { opacity: 0; transform: translateY(calc(var(--eep-distance, 16px) * -1)); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes eep-out-fade-down {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(calc(var(--eep-distance, 16px) * 0.6)); }
}

/* --- 3. scale-pop : pop avec overshoot / sortie en contraction ------------ */

.eep-enter--scale-pop { animation-name: eep-in-scale-pop; }
.eep-exit--scale-pop { animation-name: eep-out-scale-pop; }

@keyframes eep-in-scale-pop {
  0%   { opacity: 0; transform: scale(0.84); }
  65%  { opacity: 1; transform: scale(1.045); }
  100% { opacity: 1; transform: scale(1); }
}

@keyframes eep-out-scale-pop {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(0.9); }
}

/* --- 4. blur-in : mise au point / sortie en défocus rapide ---------------- */

.eep-enter--blur-in { animation-name: eep-in-blur; }
.eep-exit--blur-in { animation-name: eep-out-blur; }

@keyframes eep-in-blur {
  from { opacity: 0; filter: blur(10px); }
  to   { opacity: 1; filter: blur(0); }
}

@keyframes eep-out-blur {
  from { opacity: 1; filter: blur(0); }
  to   { opacity: 0; filter: blur(6px); }
}

/* --- 5. slide-left : voyage vers la gauche (entre par la droite) ----------
   Le nom = direction du déplacement. Distance doublée : un slide se lit
   mieux avec plus d'amplitude qu'un fade. La sortie continue vers la
   gauche — parfait pour des vues séquentielles (wizard, carrousel). */

.eep-enter--slide-left { animation-name: eep-in-slide-left; }
.eep-exit--slide-left { animation-name: eep-out-slide-left; }

@keyframes eep-in-slide-left {
  from { opacity: 0; transform: translateX(calc(var(--eep-distance, 16px) * 2)); }
  to   { opacity: 1; transform: translateX(0); }
}

@keyframes eep-out-slide-left {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(calc(var(--eep-distance, 16px) * -2)); }
}

/* --- 6. slide-right : voyage vers la droite (entre par la gauche) --------- */

.eep-enter--slide-right { animation-name: eep-in-slide-right; }
.eep-exit--slide-right { animation-name: eep-out-slide-right; }

@keyframes eep-in-slide-right {
  from { opacity: 0; transform: translateX(calc(var(--eep-distance, 16px) * -2)); }
  to   { opacity: 1; transform: translateX(0); }
}

@keyframes eep-out-slide-right {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(calc(var(--eep-distance, 16px) * 2)); }
}

/* --- 7. flip-in : bascule 3D charnière haute ------------------------------- */

.eep-enter--flip-in,
.eep-exit--flip-in {
  transform-origin: 50% 0;
}

.eep-enter--flip-in { animation-name: eep-in-flip; }
.eep-exit--flip-in { animation-name: eep-out-flip; }

@keyframes eep-in-flip {
  from { opacity: 0; transform: perspective(600px) rotateX(-55deg); }
  to   { opacity: 1; transform: perspective(600px) rotateX(0deg); }
}

@keyframes eep-out-flip {
  from { opacity: 1; transform: perspective(600px) rotateX(0deg); }
  to   { opacity: 0; transform: perspective(600px) rotateX(28deg); }
}

/* --- 8. reveal-clip : rideau vertical (clip-path) --------------------------
   Entrée : se dévoile du haut vers le bas. Sortie : le rideau retombe
   (recouvrement du bas vers le haut) — pas un simple rembobinage. */

.eep-enter--reveal-clip { animation-name: eep-in-reveal-clip; }
.eep-exit--reveal-clip { animation-name: eep-out-reveal-clip; }

@keyframes eep-in-reveal-clip {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}

@keyframes eep-out-reveal-clip {
  from { clip-path: inset(0 0 0 0); }
  to   { clip-path: inset(100% 0 0 0); }
}

/* --- États utilitaires (posés/retirés par anim.js) -------------------------
   .eep-waiting : masque un élément AVANT son entrée orchestrée (posée par le
   JS uniquement → sans JS, rien n'est jamais caché).
   .eep-collapse : repli de hauteur après la sortie d'un élément congédié,
   pour que la liste se referme en douceur avant le retrait du DOM. */

.eep-waiting {
  visibility: hidden;
}

.eep-collapse {
  transition:
    height 0.3s cubic-bezier(0.4, 0, 0.2, 1),
    margin 0.3s cubic-bezier(0.4, 0, 0.2, 1),
    padding 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ==========================================================================
   Démo galerie : panneau de contrôle + cartes notification congédiables
   ========================================================================== */

.eep-demo {
  width: min(320px, 100%);
  display: flex;
  flex-direction: column;
  gap: 12px;
  color: var(--ml-fg, #e8eaf2);
}

/* --- Barre de contrôle ------------------------------------------------------ */

.eep-demo__bar {
  display: flex;
  gap: 8px;
}

.eep-demo__select {
  flex: 1;
  min-width: 0;
  appearance: none;
  -webkit-appearance: none;
  padding: 8px 30px 8px 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  background:
    linear-gradient(45deg, transparent 50%, var(--ml-muted, #8b91a3) 50%) right 16px top 55% / 5px 5px no-repeat,
    linear-gradient(135deg, var(--ml-muted, #8b91a3) 50%, transparent 50%) right 12px top 55% / 5px 5px no-repeat,
    var(--ml-surface, #151a24);
  color: var(--ml-fg, #e8eaf2);
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 550;
  line-height: 1.2;
  cursor: pointer;
  transition: border-color 0.2s ease;
}

.eep-demo__select:hover {
  border-color: rgba(255, 255, 255, 0.22);
}

.eep-demo__select:focus-visible {
  outline: 2px solid var(--ml-accent, #7c8cff);
  outline-offset: 2px;
}

.eep-demo__replay {
  padding: 8px 14px;
  border: 1px solid color-mix(in srgb, var(--ml-accent, #7c8cff) 45%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, var(--ml-accent, #7c8cff) 14%, transparent);
  color: var(--ml-accent, #7c8cff);
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.eep-demo__replay:hover {
  background: color-mix(in srgb, var(--ml-accent, #7c8cff) 24%, transparent);
  border-color: color-mix(in srgb, var(--ml-accent, #7c8cff) 70%, transparent);
}

.eep-demo__replay:active {
  transform: translateY(1px);
}

.eep-demo__replay:focus-visible {
  outline: 2px solid var(--ml-accent, #7c8cff);
  outline-offset: 2px;
}

/* --- Cartes notification ----------------------------------------------------
   Marges (pas de gap flex sur la liste) : le repli de hauteur d'une carte
   congédiée emporte sa marge → la liste se referme sans à-coup. */

.eep-demo__list {
  /* Démo ralentie pour bien lire chaque preset (défaut du pack : 0.5s) */
  --eep-duration: 1s;
  list-style: none;
  margin: 0;
  padding: 0;
}

.eep-demo__card {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  padding: 11px 12px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--ml-surface, #151a24) 88%, white);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.eep-demo__dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ml-muted, #8b91a3);
  box-shadow: 0 0 8px color-mix(in srgb, var(--ml-muted, #8b91a3) 60%, transparent);
}

.eep-demo__dot--ok {
  background: var(--ml-accent-2, #2dd4bf);
  box-shadow: 0 0 8px color-mix(in srgb, var(--ml-accent-2, #2dd4bf) 60%, transparent);
}

.eep-demo__dot--info {
  background: var(--ml-accent, #7c8cff);
  box-shadow: 0 0 8px color-mix(in srgb, var(--ml-accent, #7c8cff) 60%, transparent);
}

.eep-demo__msg {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
}

.eep-demo__msg strong {
  font-size: 0.76rem;
  font-weight: 600;
  line-height: 1.25;
}

.eep-demo__msg span {
  font-size: 0.66rem;
  color: var(--ml-muted, #8b91a3);
}

.eep-demo__close {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--ml-muted, #8b91a3);
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.2s ease, color 0.2s ease, background-color 0.2s ease;
}

.eep-demo__close:hover {
  opacity: 1;
  color: var(--ml-fg, #e8eaf2);
  background: rgba(255, 255, 255, 0.08);
}

.eep-demo__close:focus-visible {
  outline: 2px solid var(--ml-accent, #7c8cff);
  outline-offset: 1px;
  opacity: 1;
}

.eep-demo__close svg {
  display: block;
  width: 9px;
  height: 9px;
}

/* --- Reduced motion ---------------------------------------------------------
   Apparitions/disparitions quasi instantanées, délais annulés : rien n'est
   jamais caché plus d'une frame. Durée non nulle (0.01 s) pour que
   animationend continue de piloter le retrait du DOM côté anim.js. */

@media (prefers-reduced-motion: reduce) {
  .eep-enter--fade-up,
  .eep-enter--fade-down,
  .eep-enter--scale-pop,
  .eep-enter--blur-in,
  .eep-enter--slide-left,
  .eep-enter--slide-right,
  .eep-enter--flip-in,
  .eep-enter--reveal-clip,
  .eep-exit--fade-up,
  .eep-exit--fade-down,
  .eep-exit--scale-pop,
  .eep-exit--blur-in,
  .eep-exit--slide-left,
  .eep-exit--slide-right,
  .eep-exit--flip-in,
  .eep-exit--reveal-clip {
    animation-duration: 0.01s;
    animation-delay: 0s;
  }

  .eep-collapse {
    transition-duration: 0.01s;
  }

  .eep-demo__replay:active {
    transform: none;
  }
}
