/* ════════════════════════════════════════════════════════════════════
   PALETTE DE MOUVEMENT — Intranet Groupe Huard
   Créé le 16/08/2026. Miroir web de `groupe-huard-app/lib/theme/huard_motion.dart`.
   Règles d'usage : groupe-huard-app/docs/MOTION.md

   ── CE FICHIER EST 100 % ADDITIF ────────────────────────────────────
   Tout est conditionné à une classe préfixée `hz-`, qui n'existe nulle
   part dans index.html à ce jour. Le simple fait de lier ce fichier ne
   change donc RIEN au rendu : aucun risque de conflit avec la tâche qui
   construit la console d'administration. Les effets ne s'activent qu'au
   moment où une classe `hz-` est posée sur un élément.

   ── CE QUI EXISTAIT DÉJÀ (vérifié, conservé, non dupliqué) ──────────
   index.html implémente déjà, correctement :
     • le coupe-circuit `@media (prefers-reduced-motion: reduce)`
       `*{animation:none!important;transition:none!important}` ;
     • `animateStatNums()`, compteurs animés une seule fois (`data-counted`)
       et déjà conditionnés à `prefers-reduced-motion` ;
     • les entrées `sectionIn` / `tuileIn` ;
     • l'indicateur de saisie du chat IA (`iaBlink`) — boucle infinie mais
       temporaire et conventionnelle, au même titre qu'un squelette.
   Ce fichier ne les remplace pas. Il apporte les jetons partagés et les
   effets manquants.
   ════════════════════════════════════════════════════════════════════ */

:root {
  /* Durées — identiques à HuardMotion (Flutter). */
  --hz-micro: 120ms;   /* retour tactile / survol            */
  --hz-short: 180ms;   /* changement d'état local            */
  --hz-medium: 240ms;  /* apparition, bascule de contenu     */
  --hz-page: 300ms;    /* changement de section              */
  --hz-stagger: 30ms;  /* décalage entre deux éléments       */
  --hz-ambient: 18s;   /* seul effet décoratif lent          */

  /* Courbes — équivalents CSS des courbes Flutter. */
  --hz-standard: cubic-bezier(0.22, 0.61, 0.36, 1); /* easeOutCubic   */
  --hz-exit: cubic-bezier(0.55, 0.06, 0.68, 0.19);  /* easeInCubic    */
  --hz-emphasized: cubic-bezier(0.2, 0, 0, 1);      /* emphasized     */
  --hz-press: cubic-bezier(0, 0, 0.2, 1);           /* easeOut        */

  /* INTERDIT : toute courbe à dépassement (rebond, élastique). */
}

/* ── 1. ENTRÉE D'ÉLÉMENT — fondu + montée, une seule fois ──────────── */

@keyframes hzEntrance {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.hz-entrance {
  animation: hzEntrance var(--hz-medium) var(--hz-standard) both;
}

/* Cascade PLAFONNÉE à 8 éléments — même règle que staggerMaxItems côté
   mobile. Au-delà, aucun délai n'est appliqué : les éléments d'une liste
   longue apparaissent d'un bloc plutôt que de faire ramer le défilement. */
.hz-stagger > *:nth-child(1) { animation-delay: 0ms; }
.hz-stagger > *:nth-child(2) { animation-delay: calc(var(--hz-stagger) * 1); }
.hz-stagger > *:nth-child(3) { animation-delay: calc(var(--hz-stagger) * 2); }
.hz-stagger > *:nth-child(4) { animation-delay: calc(var(--hz-stagger) * 3); }
.hz-stagger > *:nth-child(5) { animation-delay: calc(var(--hz-stagger) * 4); }
.hz-stagger > *:nth-child(6) { animation-delay: calc(var(--hz-stagger) * 5); }
.hz-stagger > *:nth-child(7) { animation-delay: calc(var(--hz-stagger) * 6); }
.hz-stagger > *:nth-child(8) { animation-delay: calc(var(--hz-stagger) * 7); }
.hz-stagger > * { animation: hzEntrance var(--hz-medium) var(--hz-standard) both; }
.hz-stagger > *:nth-child(n + 9) { animation: none; }

/* ── 2. PROFONDEUR AU SURVOL — desktop uniquement ──────────────────── */

/* `hover: hover` exclut les écrans tactiles, où un état de survol reste
   collé après le tap. Sur tactile, c'est `:active` qui répond. */
@media (hover: hover) and (pointer: fine) {
  .hz-lift {
    transition:
      transform var(--hz-short) var(--hz-standard),
      box-shadow var(--hz-short) var(--hz-standard);
  }
  .hz-lift:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(20, 40, 70, 0.10);
  }
}

.hz-lift:active {
  transform: translateY(0) scale(0.985);
  transition: transform var(--hz-micro) var(--hz-press);
}

/* ── 3. SQUELETTE DE CHARGEMENT ────────────────────────────────────── */

@keyframes hzSweep {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.hz-skel {
  border-radius: 8px;
  background: linear-gradient(
    90deg,
    rgba(20, 40, 70, 0.06) 35%,
    rgba(20, 40, 70, 0.11) 50%,
    rgba(20, 40, 70, 0.06) 65%
  );
  background-size: 200% 100%;
  animation: hzSweep 1.1s linear infinite;
}

.hz-skel-line { height: 12px; margin-bottom: 8px; }
.hz-skel-line.w70 { width: 70%; }
.hz-skel-line.w45 { width: 45%; }

.hz-skel-card {
  padding: 14px;
  border: 1px solid #eef2f7;
  border-radius: 14px;
  background: #fff;
  margin-bottom: 10px;
}

/* ── 4. SOULIGNEMENT D'ONGLET ACTIF ────────────────────────────────── */

.hz-tabs { position: relative; }

.hz-tabs .hz-underline {
  position: absolute;
  bottom: 0;
  height: 2.5px;
  border-radius: 2.5px;
  background: var(--bleu, #1E6FA8);
  /* `left` et `width` sont posés en JS sur l'onglet actif ; la transition
     fait glisser le trait au lieu de le faire sauter. */
  transition:
    left var(--hz-medium) var(--hz-emphasized),
    width var(--hz-medium) var(--hz-emphasized);
}

/* ── 5. EN-TÊTE À DÉGRADÉ LENT — le seul effet purement décoratif ──── */

@keyframes hzAmbient {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* Réservé aux GRANDES surfaces d'en-tête. Ne jamais poser sur une carte
   de liste : ce serait « quelque chose qui bouge en boucle dans le champ
   de vision », précisément ce qu'on s'interdit. Le cycle de 18 s reste
   sous le seuil de détection consciente : on perçoit une surface vivante,
   jamais un élément qui bouge. */
.hz-header-ambient {
  background-size: 300% 300%;
  animation: hzAmbient var(--hz-ambient) linear infinite;
}

/* ── 6. MICRO-RETOUR D'ACTION — succès / échec ─────────────────────── */

@keyframes hzFadeUp {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* Apparition d'un bandeau de confirmation ou d'erreur. Pas de rebond :
   le message monte et se pose. */
.hz-feedback {
  animation: hzFadeUp var(--hz-short) var(--hz-standard) both;
}

/* ════════════════════════════════════════════════════════════════════
   ACCESSIBILITÉ — réduction d'animations
   index.html porte déjà un coupe-circuit global. On le redéclare ici pour
   que `motion.css` reste correct s'il est réutilisé seul (pilotage-ia.html,
   ia.html, agents/*.html), sans dépendre de l'ordre de chargement.
   Le contenu reste ENTIÈREMENT visible : on retire le mouvement, jamais
   l'information.
   ════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .hz-entrance,
  .hz-stagger > *,
  .hz-feedback {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  .hz-skel,
  .hz-header-ambient {
    animation: none !important;
  }

  .hz-lift,
  .hz-lift:hover,
  .hz-lift:active,
  .hz-tabs .hz-underline {
    transition: none !important;
    transform: none !important;
  }
}
