/* =============================================================
   motion.css — animations & transitions légères
   Chargé après mobile.css dans base.html. Couche opt-in :
   si ce fichier saute, l'interface reste identique (aucune motion).

   Règles de casse :
   - main/.shell ne sont animés qu'en OPACITY : un transform d'ancêtre
     piègerait les descendants position:fixed (.fab, .preview-modal,
     .action-bar).
   - L'appui néo doit rester INSTANTANÉ (inset sec) : jamais de
     transition box-shadow au repos sur les plaques.
   ============================================================= */

/* Tokens de mouvement (propres à cette couche) */
:root {
  --dur-1: 100ms;
  --dur-2: 150ms;
  --dur-3: 280ms;
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-press: cubic-bezier(.3, 0, .6, .4);
}

/* Kill switch : préférence système « réduire le mouvement ».
   Couvre aussi Alpine (ses x-transition sont des transitions CSS). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0 !important;
  }
}

/* ---- Appui tactile : transform seule. Les insets néo (fond/box-shadow)
       restent instantanés — c'est l'appui néo. ---- */
.btn, .fab, .icon-btn, .chip, .seg, .avatar, .search-result {
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur-1) var(--ease-press);
}
.btn:not(:disabled):active, .chip:active, .seg:active, .search-result:active,
.icon-btn:active, .avatar:active { transform: scale(.97); }
.fab:active { transform: scale(.94); }
.card:active { transform: scale(.995); }

/* ---- Navigation : pression + couleur d'état FUSIONNÉES (une seule
       déclaration, sinon la suivante écrase la précédente). ---- */
.nav-item, .tabbar a {
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur-1) var(--ease-press),
              color var(--dur-2) var(--ease-out),
              background-color var(--dur-2) var(--ease-out);
}
.nav-item:active, .tabbar a:active { transform: scale(.97); }

/* ---- Cartes : pression + fond de thème fusionnés. PAS de box-shadow
       au repos (l'inset à l'appui doit rester instantané). ---- */
.card {
  transition: transform var(--dur-1) var(--ease-press),
              background-color var(--dur-3) var(--ease-out);
}

/* ---- Changement de thème : fonds (un fondu doux au toggle). ---- */
body, .topbar, .tabbar, .sidebar {
  transition: background-color var(--dur-3) var(--ease-out);
}

/* ---- Hover desktop (pointeur fin uniquement, jamais sur tactile).
       L'ombre néo duale est CONSERVÉE, le pop est ajouté par-dessus. ---- */
@media (hover: hover) and (pointer: fine) {
  .card:not(:active):hover {
    transform: translateY(-2px);
    box-shadow: -6px -6px 14px var(--neo-hi),
                6px 6px 16px var(--neo-lo),
                0 12px 28px -14px var(--neo-lo);
    transition: transform var(--dur-2) var(--ease-out),
                box-shadow var(--dur-2) var(--ease-out),
                background-color var(--dur-3) var(--ease-out);
  }
  .btn:not(:active):not(:disabled):hover { transform: translateY(-1px); }
}

/* ---- Apparition du contenu — OPACITY SEULE (jamais de transform sur
       main : .fab/.preview-modal/.action-bar sont fixed, descendants).
       `both` est sûr : pas de delay, gelé par BFCache, pas de rejeu
       aux swaps HTMX (ceux-ci ciblent #delivery-list, enfants de main). ---- */
.shell > main:last-of-type:not(.auth-wrap) { animation: fade-in var(--dur-3) var(--ease-out) both; }
/* Pages d'authentification : pas de fondu d'entrée. L'animation du main part de
   opacity:0 — si elle se bloque (navigateur occupé, chargement ultra-rapide
   depuis le cache), le header et le formulaire resteraient invisibles. */
.shell > .auth-wrap { animation: none; }
@keyframes fade-in { from { opacity: 0; } }

/* ---- Swaps HTMX : fondu du contenu fraîchement inséré
       (HTMX 2.0.4 pose `.htmx-added` pendant le swap/settle).
       C'est l'interaction principale de l'app : filtres chips, recherche. ---- */
#delivery-list .htmx-added,
#client-list .htmx-added,
#prospect-list .htmx-added {
  animation: fade-in var(--dur-2) var(--ease-out);
}

/* Lots de contacts (onglet Contacts) : le lot fraîchement chargé fonde — que
   ce soit le premier (modale/accordéon) ou la suite du bouton « Charger plus ». */
.cat-contacts .htmx-added {
  animation: fade-in var(--dur-2) var(--ease-out);
}

/* ---- Messages flash ---- */
.alert { animation: alert-in var(--dur-3) var(--ease-out); }
@keyframes alert-in { from { opacity: 0; transform: translateY(-6px); } }

/* ---- Menu avatar : origine selon le contexte (CSS, pas de modifieur
       Alpine inline — le partial a deux géométries opposées). ---- */
.avatar-menu { transform-origin: top right; }
@media (min-width: 768px) {
  .sidebar-foot .avatar-menu { transform-origin: bottom left; }
}
