/* ==========================================================================
   111 — Form Validate
   Micro-formulaire email au feedback chorégraphié. Invalide : shake
   horizontal amorti du champ, bordure + icône en rouge, message d'erreur en
   slide + fade. Valide : le texte du bouton fond, le bouton se contracte en
   cercle, un check se dessine (stroke-dashoffset) suivi d'un ring d'onde.
   Les états .is-error / .is-success sont posés par anim.js sur la racine.
   ========================================================================== */

.form-validate {
  --fv-accent: var(--ml-accent, #7c8cff);
  --fv-accent-2: var(--ml-accent-2, #2dd4bf);
  --fv-error: var(--form-validate-error, #f87171);
  --fv-ease: cubic-bezier(0.22, 1, 0.36, 1);

  display: flex;
  flex-direction: column;
  gap: 6px;
  width: min(280px, 100%);
  color: var(--ml-fg, #e8eaf2);
}

.form-validate__label {
  color: var(--ml-muted, #8b91a3);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
}

/* --- Champ ------------------------------------------------------------------ */

.form-validate__field {
  position: relative;
  border-radius: 12px;
  background-color: var(--ml-surface, #151a24);
  border: 1px solid color-mix(in srgb, var(--ml-muted, #8b91a3) 28%, transparent);
  transition: border-color 0.25s var(--fv-ease);
}

.form-validate__field:focus-within {
  border-color: color-mix(in srgb, var(--fv-accent) 60%, transparent);
}

.form-validate__input {
  width: 100%;
  padding: 13px 16px 13px 44px;
  border: 0;
  border-radius: inherit;
  background: none;
  color: var(--ml-fg, #e8eaf2);
  font: inherit;
  font-size: 0.95rem;
  line-height: 1.3;
  outline: none; /* focus porté par la bordure du champ + :focus-visible ci-dessous */
  caret-color: var(--fv-accent);
}

.form-validate__input::placeholder {
  color: color-mix(in srgb, var(--ml-muted, #8b91a3) 65%, transparent);
}

.form-validate__field:has(.form-validate__input:focus-visible) {
  outline: 2px solid var(--fv-accent);
  outline-offset: 3px;
}

.form-validate__icon {
  position: absolute;
  left: 14px;
  top: 50%;
  width: 19px;
  height: 19px;
  color: var(--ml-muted, #8b91a3);
  transform: translateY(-50%);
  transition: color 0.25s var(--fv-ease);
  pointer-events: none;
}

.form-validate__svg {
  display: block;
  width: 100%;
  height: 100%;
}

.form-validate__field:focus-within .form-validate__icon {
  color: var(--fv-accent);
}

/* --- État erreur -------------------------------------------------------------- */

.form-validate.is-error .form-validate__field {
  border-color: var(--fv-error);
  animation: form-validate-shake 0.45s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

.form-validate.is-error .form-validate__field .form-validate__icon {
  color: var(--fv-error);
}

/* shake horizontal amorti : amplitude décroissante */
@keyframes form-validate-shake {
  0%   { transform: translateX(0); }
  12%  { transform: translateX(-9px); }
  28%  { transform: translateX(8px); }
  44%  { transform: translateX(-6px); }
  60%  { transform: translateX(4px); }
  76%  { transform: translateX(-2px); }
  100% { transform: translateX(0); }
}

/* message : slot réservé (pas de saut de layout), entre en slide + fade */
.form-validate__error {
  min-height: 1.25em;
  margin: 0;
  color: var(--fv-error);
  font-size: 0.8rem;
  line-height: 1.25;
  opacity: 0;
  transform: translateY(-6px);
  transition:
    opacity 0.28s var(--fv-ease),
    transform 0.28s var(--fv-ease);
}

.form-validate.is-error .form-validate__error {
  opacity: 1;
  transform: translateY(0);
}

/* --- Bouton ------------------------------------------------------------------- */

.form-validate__btn {
  position: relative;
  align-self: center;
  width: 100%;
  height: 46px;
  margin-top: 4px;
  border: 0;
  border-radius: 12px;
  background-image: linear-gradient(
    135deg,
    var(--fv-accent),
    color-mix(in srgb, var(--fv-accent) 55%, var(--fv-accent-2))
  );
  color: var(--ml-bg, #0d1017);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  overflow: hidden;
  transition:
    width 0.45s var(--fv-ease),
    border-radius 0.45s var(--fv-ease),
    transform 0.2s var(--fv-ease);
}

.form-validate__btn:hover:not(:disabled) {
  transform: translateY(-1px);
}

.form-validate__btn:active:not(:disabled) {
  transform: translateY(0) scale(0.98);
}

.form-validate__btn:focus-visible {
  outline: 2px solid var(--fv-accent);
  outline-offset: 3px;
}

.form-validate__btn:disabled {
  cursor: default;
}

.form-validate__btn-label {
  display: inline-block;
  opacity: 1;
  transform: scale(1);
  transition:
    opacity 0.2s var(--fv-ease),
    transform 0.2s var(--fv-ease);
}

/* check centré, dessiné au stroke une fois le bouton contracté */
.form-validate__btn-check {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}

.form-validate__btn-check .form-validate__svg {
  width: 22px;
  height: 22px;
}

.form-validate__check-path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1; /* calé sur pathLength="1" */
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 0.15s ease; /* retour rapide au reset */
}

/* ring d'onde qui s'échappe du bouton-cercle */
.form-validate__btn-ring {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  border: 2px solid var(--fv-accent-2);
  opacity: 0;
  transform: scale(1);
  pointer-events: none;
}

/* --- Chorégraphie succès -------------------------------------------------------
   1. le texte fond (0 → 0.2s)  2. contraction en cercle (0 → 0.45s)
   3. check dessiné (0.35 → 0.75s)  4. ring d'onde (0.6 → 1.2s) */

.form-validate.is-success .form-validate__btn {
  width: 46px;
  border-radius: 999px;
  background-image: linear-gradient(
    135deg,
    color-mix(in srgb, var(--fv-accent-2) 70%, var(--fv-accent)),
    var(--fv-accent-2)
  );
}

.form-validate.is-success .form-validate__btn-label {
  opacity: 0;
  transform: scale(0.75);
}

.form-validate.is-success .form-validate__check-path {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 0.4s var(--fv-ease) 0.35s;
}

.form-validate.is-success .form-validate__btn-ring {
  animation: form-validate-ring 0.6s ease-out 0.6s both;
}

@keyframes form-validate-ring {
  0%   { opacity: 0.7; transform: scale(1); }
  100% { opacity: 0;   transform: scale(1.8); }
}

/* --- Reduced motion -------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .form-validate.is-error .form-validate__field {
    animation: none; /* pas de shake — la couleur suffit */
  }

  .form-validate.is-success .form-validate__btn-ring {
    animation: none;
  }

  .form-validate__field,
  .form-validate__icon,
  .form-validate__error,
  .form-validate__btn,
  .form-validate__btn-label,
  .form-validate__check-path,
  .form-validate.is-success .form-validate__check-path {
    transition-duration: 0.01s;
    transition-delay: 0s;
  }
}
