/* ==========================================================================
   JIA CRM · Sistema de motion global
   --------------------------------------------------------------------------
   Micro-interacciones aplicadas por selectores genéricos y data-attributes,
   sin tener que editar cada plantilla. Reglas del sistema:
     · Solo se animan transform (translate/scale/rotate) y opacity; colores y
       sombras usan transiciones cortas.
     · Nada dura más de 300 ms en interacciones.
     · Sin layout shift: los desplazamientos usan las propiedades individuales
       `translate` / `scale` / `rotate`, que se componen con el `transform` de
       Tailwind en vez de pisarlo.
     · El movimiento vive dentro de `prefers-reduced-motion: no-preference`;
       con `reduce` solo quedan cambios de color/opacidad instantáneos.
   Las animaciones por vista (dashboard, kanban, gráficos…) viven en
   motion-views.css y reutilizan los tokens de :root.
   ========================================================================== */

/* -------------------------------------------------------------------------- */
/* 1. Tokens compartidos                                                      */
/* -------------------------------------------------------------------------- */
:root {
  --motion-fast: 120ms;
  --motion-base: 180ms;
  --motion-slow: 260ms;
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  --ease-standard: cubic-bezier(.4, 0, .2, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);

  /* Derivados (opcionales para otras hojas) */
  --motion-distance: 4px;          /* desplazamiento de entrada de popovers */
  --motion-scale-in: .96;          /* escala inicial de popovers/modales */
  --motion-press-scale: .97;       /* escala al pulsar un botón */
  --motion-sheen: 300ms;           /* barrido de brillo del botón primario */

  --focus-ring: #E9590E;
  --mx-row-hover: color-mix(in srgb, var(--surface-2, #F7F8FA) 80%, transparent);
  --mx-card-shadow-hover: 0 1px 2px rgba(17, 30, 50, .05), 0 10px 24px -12px rgba(17, 30, 50, .22);
  --mx-danger: #DC2626;
  --mx-danger-ring: rgba(220, 38, 38, .16);
  --mx-info-fg: #1D4ED8;
  --mx-info-bg: rgba(59, 130, 246, .10);
  --mx-info-bar: #3B82F6;
}
.dark {
  --mx-card-shadow-hover: 0 12px 28px -14px rgba(0, 0, 0, .75);
  --mx-danger: #F87171;
  --mx-danger-ring: rgba(248, 113, 113, .22);
  --mx-info-fg: #93C5FD;
  --mx-info-bg: rgba(59, 130, 246, .18);
}

/* -------------------------------------------------------------------------- */
/* 2. Keyframes                                                               */
/* -------------------------------------------------------------------------- */
@keyframes mx-fade-in { from { opacity: 0; } }
@keyframes mx-dropdown-in {
  from { opacity: 0; scale: var(--motion-scale-in); translate: 0 calc(-1 * var(--motion-distance)); }
}
@keyframes mx-modal-in {
  from { opacity: 0; scale: var(--motion-scale-in); translate: 0 var(--motion-distance); }
}
@keyframes mx-sheet-in { from { translate: 0 100%; } }
@keyframes mx-toast-in { from { opacity: 0; translate: 16px 0; scale: .98; } }
@keyframes mx-toast-progress { from { scale: 1 1; } to { scale: 0 1; } }
@keyframes mx-error-in { from { opacity: 0; translate: 0 -2px; } }
@keyframes mx-shake {
  0%, 100% { translate: 0 0; }
  20% { translate: -4px 0; }
  40% { translate: 4px 0; }
  60% { translate: -3px 0; }
  80% { translate: 2px 0; }
}
@keyframes mx-shimmer { from { translate: -100% 0; } to { translate: 100% 0; } }
@keyframes mx-spin { to { rotate: 360deg; } }
@keyframes mx-focus-ring { from { outline-offset: 6px; outline-color: transparent; } }
@keyframes mx-indicator-in { from { opacity: 0; scale: 1 0; } }
@keyframes mx-icon-pop { from { opacity: 0; rotate: -90deg; scale: .6; } }

/* -------------------------------------------------------------------------- */
/* 3. Foco accesible: anillo de marca que "se asienta" al aparecer            */
/* -------------------------------------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: no-preference) {
  /* Solo controles: así no se reinician animaciones de entrada de otros elementos al perder el foco. */
  :where(a, button, summary, [role="button"], [role="tab"], [role="menuitem"], input[type="checkbox"], input[type="radio"]):focus-visible {
    animation: mx-focus-ring var(--motion-base) var(--ease-out);
  }
}

/* -------------------------------------------------------------------------- */
/* 4. Botones y enlaces con forma de botón                                    */
/*    Grupo "pulsable": <button>, inputs de envío, [role=button] y <a> con     */
/*    esquinas redondeadas + padding (los enlaces-botón de Tailwind).          */
/*    Opt-out: data-no-press o .mx-no-motion.                                  */
/* -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  :is(button, input[type="submit"], input[type="button"], input[type="reset"], [role="button"],
      a[class*="rounded"]:is([class*="px-"], [class~="p-1"], [class~="p-1.5"], [class~="p-2"], [class~="p-2.5"],
                             [class~="h-8"], [class~="h-9"], [class~="h-10"], [class~="h-11"])):not([data-no-press], .mx-no-motion, .app-sidebar-nav *) {
    transition:
      color var(--motion-fast) var(--ease-standard),
      background-color var(--motion-fast) var(--ease-standard),
      border-color var(--motion-fast) var(--ease-standard),
      box-shadow var(--motion-base) var(--ease-out),
      opacity var(--motion-fast) var(--ease-standard),
      transform var(--motion-base) var(--ease-out),
      scale var(--motion-slow) var(--ease-spring),
      translate var(--motion-base) var(--ease-out);
  }

  /* Press: hunde rápido, vuelve con muelle (la transición de salida usa --ease-spring). */
  :is(button, input[type="submit"], input[type="button"], input[type="reset"], [role="button"],
      a[class*="rounded"]:is([class*="px-"], [class~="p-1"], [class~="p-1.5"], [class~="p-2"], [class~="p-2.5"],
                             [class~="h-8"], [class~="h-9"], [class~="h-10"], [class~="h-11"])):not([data-no-press], .mx-no-motion, .app-sidebar-nav *, .hs-menu *, [role="menu"] *, :disabled, [aria-disabled="true"]):active {
    scale: var(--mx-press, var(--motion-press-scale));
    transition-duration: var(--motion-fast);
    transition-timing-function: var(--ease-standard);
  }
  /* Elementos anchos (filas de menú, botones w-full): presión casi imperceptible. */
  :is(button, [role="button"], a)[class*="w-full"] { --mx-press: .99; }
  :is(.hs-menu, [role="menu"]) :is(a, button):active { scale: .99; }

  /* Íconos Lucide dentro de botones/enlaces: micro-desplazamiento según su semántica. */
  :is(button, a, [role="button"]) :is(svg.lucide, [data-lucide]) {
    transition:
      translate var(--motion-base) var(--ease-spring),
      rotate var(--motion-slow) var(--ease-spring),
      scale var(--motion-base) var(--ease-spring);
  }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  :is(button, a, [role="button"]):hover :is(.lucide-arrow-right, .lucide-chevron-right, .lucide-move-right, .lucide-chevrons-right,
    [data-lucide="arrow-right"], [data-lucide="chevron-right"], [data-lucide="move-right"], [data-lucide="chevrons-right"]) { translate: 2px 0; }
  :is(button, a, [role="button"]):hover :is(.lucide-arrow-left, .lucide-chevron-left, .lucide-chevrons-left,
    [data-lucide="arrow-left"], [data-lucide="chevron-left"], [data-lucide="chevrons-left"]) { translate: -2px 0; }
  :is(button, a, [role="button"]):hover :is(.lucide-arrow-up-right, .lucide-external-link, .lucide-send,
    [data-lucide="arrow-up-right"], [data-lucide="external-link"], [data-lucide="send"]) { translate: 1.5px -1.5px; }
  :is(button, a, [role="button"]):hover :is(.lucide-download, [data-lucide="download"]) { translate: 0 1.5px; }
  :is(button, a, [role="button"]):hover :is(.lucide-upload, [data-lucide="upload"]) { translate: 0 -1.5px; }
  :is(button, a, [role="button"]):hover :is(.lucide-plus, [data-lucide="plus"]) { rotate: 90deg; }
  :is(button, a, [role="button"]):hover :is(.lucide-refresh-cw, .lucide-rotate-cw, [data-lucide="refresh-cw"], [data-lucide="rotate-cw"]) { rotate: 60deg; }
  :is(button, a, [role="button"]):hover :is(.lucide-pencil, .lucide-trash-2, .lucide-trash, [data-lucide="pencil"], [data-lucide="trash-2"], [data-lucide="trash"]) { rotate: -8deg; }
  :is(button, a, [role="button"]):hover :is(.lucide-search, [data-lucide="search"]) { scale: 1.1; }

  /* Elevación leve en botones sólidos (primario, navy, peligro). */
  :is(button, a, input[type="submit"]):is(.bg-accent, .bg-navy, .bg-red-600):not(:disabled, .mx-btn-loading, [data-no-press], .mx-no-motion, .app-sidebar-nav *):hover {
    translate: 0 -1px;
  }
  :is(button, a, input[type="submit"]):is(.bg-accent, .bg-navy, .bg-red-600):not(:disabled, .mx-btn-loading, [data-no-press], .mx-no-motion, .app-sidebar-nav *):hover:active {
    translate: 0 0;
  }
}

/* Halo de color al hover (sombra: transición corta, sin movimiento). */
@media (hover: hover) {
  :is(button, a).bg-accent:not(:disabled, .mx-btn-loading, .app-sidebar-nav *):hover {
    box-shadow: 0 1px 2px rgba(17, 30, 50, .08), 0 8px 18px -8px rgba(233, 89, 14, .6) !important;
  }
  :is(button, a).bg-navy:not(:disabled, .mx-btn-loading, .app-sidebar-nav *):hover {
    box-shadow: 0 1px 2px rgba(17, 30, 50, .08), 0 8px 18px -8px rgba(30, 51, 82, .55);
  }
  :is(button, a).bg-red-600:not(:disabled, .mx-btn-loading):hover {
    box-shadow: 0 1px 2px rgba(17, 30, 50, .08), 0 8px 18px -8px rgba(220, 38, 38, .55);
  }
}

/* "Sheen": barrido de luz sobre el botón primario naranja al hover.
   Solo en elementos que no son inline (un <a> inline no recorta su overflow). */
:where(button.bg-accent, a.bg-accent:is(.inline-flex, .flex, .block, .inline-block, .grid, .w-full)):not(.app-sidebar-nav *) {
  position: relative;
  overflow: hidden;
}
:is(button.bg-accent, a.bg-accent:is(.inline-flex, .flex, .block, .inline-block, .grid, .w-full)):not(.app-sidebar-nav *, .mx-no-motion)::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, .26) 50%, transparent 70%);
  translate: -110% 0;
  opacity: 0;
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  :is(button.bg-accent, a.bg-accent:is(.inline-flex, .flex, .block, .inline-block, .grid, .w-full)):not(.app-sidebar-nav *, .mx-no-motion, :disabled):hover::after {
    translate: 110% 0;
    opacity: 1;
    transition: translate var(--motion-sheen) var(--ease-out), opacity var(--motion-fast) linear;
  }
}

/* -------------------------------------------------------------------------- */
/* 5. Estados de carga (los aplica motion.js al enviar formularios)           */
/* -------------------------------------------------------------------------- */
.mx-spinner {
  display: inline-block;
  box-sizing: border-box;
  width: 1em;
  height: 1em;
  border-radius: 999px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  opacity: .95;
  pointer-events: none;
  animation: mx-spin .7s linear infinite;
}
:is(button, input).mx-btn-loading {
  cursor: progress;
  opacity: .92;
}
.mx-btn-loading > .mx-spinner {
  position: absolute;
  margin: 0;
  animation: mx-spin .7s linear infinite, mx-fade-in var(--motion-fast) var(--ease-out);
}
.mx-btn-loading .mx-icon-hidden { visibility: hidden; }
.mx-btn-label { display: inline; }
.mx-btn-loading > .mx-btn-label { translate: var(--mx-label-shift, 0px) 0; }
@media (prefers-reduced-motion: no-preference) {
  .mx-btn-label { transition: translate var(--motion-base) var(--ease-out); }
}
/* Formularios GET (filtros): feedback sutil, sin deshabilitar. */
.mx-btn-pending { opacity: .75; cursor: progress; }
form[aria-busy="true"] { cursor: progress; }

/* Barra de progreso superior (envíos de formulario). */
.mx-progress {
  position: fixed;
  z-index: 90;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  pointer-events: none;
  transform-origin: 0 50%;
  scale: 0 1;
  opacity: 0;
  background: linear-gradient(90deg, #E9590E, #FF8A4C);
  box-shadow: 0 0 8px rgba(233, 89, 14, .45);
}
.mx-progress.is-active {
  opacity: 1;
  scale: .85 1;
  /* Indicador de progreso (no es una interacción): avanza rápido y se frena. */
  transition: scale 8s cubic-bezier(.08, .8, .2, 1), opacity var(--motion-fast) linear;
}
.mx-progress.is-done {
  opacity: 0;
  scale: 1 1;
  transition: scale var(--motion-base) var(--ease-out), opacity var(--motion-base) var(--ease-out) var(--motion-fast);
}

/* -------------------------------------------------------------------------- */
/* 6. Inputs, selects y textarea                                              */
/* -------------------------------------------------------------------------- */
input:is([type="checkbox"], [type="radio"]) { accent-color: #E9590E; }

@media (prefers-reduced-motion: no-preference) {
  :is(input:not([type="checkbox"], [type="radio"], [type="range"], [type="hidden"], [type="submit"], [type="button"], [type="reset"]), select, textarea) {
    transition:
      border-color var(--motion-fast) var(--ease-standard),
      box-shadow var(--motion-base) var(--ease-out),
      background-color var(--motion-fast) var(--ease-standard),
      color var(--motion-fast) var(--ease-standard);
  }
  input:is([type="checkbox"], [type="radio"]) { transition: scale var(--motion-base) var(--ease-spring); }
  input:is([type="checkbox"], [type="radio"]):not(:disabled):active { scale: .88; }
}
@media (hover: hover) {
  :is(input:not([type="checkbox"], [type="radio"], [type="range"], [type="hidden"], [type="submit"], [type="button"], [type="reset"], [type="file"]), select, textarea):not(:focus, :disabled, [aria-invalid="true"], [class*="border-transparent"], [class~="border-0"]):hover {
    border-color: color-mix(in srgb, var(--line, #E3E6EB) 55%, var(--muted, #949FAE));
  }
}
/* Estado inválido (Django añade aria-invalid="true" a los campos con error). */
:is(input, select, textarea)[aria-invalid="true"] { border-color: var(--mx-danger) !important; }
:is(input, select, textarea)[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px var(--mx-danger-ring) !important; }
@media (prefers-reduced-motion: no-preference) {
  :is(input, select, textarea)[aria-invalid="true"],
  .mx-shake { animation: mx-shake 280ms var(--ease-standard) 1; }
}

/* Botón nativo del input de archivo, a juego con el resto. */
input[type="file"]::file-selector-button {
  margin-right: .75rem;
  padding: .35rem .75rem;
  border: 1px solid var(--line, #E3E6EB);
  border-radius: .5rem;
  background: var(--surface-2, #F7F8FA);
  color: var(--ink, #111E32);
  font: inherit;
  font-size: .8125rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard);
}
input[type="file"]:hover::file-selector-button {
  background: var(--canvas, #F0F1F4);
  border-color: color-mix(in srgb, var(--line, #E3E6EB) 55%, var(--muted, #949FAE));
}

/* Campo con etiqueta (partials/_field.html): etiqueta y ayuda reaccionan al foco. */
.mx-field-label { color: var(--subtle); transition: color var(--motion-fast) var(--ease-standard); }
.mx-field-help { transition: color var(--motion-fast) var(--ease-standard); }
.mx-field:focus-within .mx-field-label { color: var(--ink); }
.mx-field:focus-within .mx-field-help { color: var(--subtle); }
.mx-field.has-error .mx-field-label { color: var(--mx-danger); }
.mx-field-error { color: var(--mx-danger); }
@media (prefers-reduced-motion: no-preference) {
  .mx-field-error,
  .mx-alert-in { animation: mx-error-in var(--motion-base) var(--ease-out) backwards; }
  /* Aviso de error del formulario: aparece y luego un único shake. */
  .mx-alert-in.mx-shake {
    animation:
      mx-error-in var(--motion-base) var(--ease-out) backwards,
      mx-shake 280ms var(--ease-standard) var(--motion-base) 1;
  }
}

/* -------------------------------------------------------------------------- */
/* 7. Dropdowns, menús, modales y hojas (Alpine x-show)                       */
/*    Entrada por CSS al pasar de display:none a visible; salida progresiva    */
/*    con transition-behavior: allow-discrete donde el navegador la soporta.   */
/* -------------------------------------------------------------------------- */
:is(.hs-menu, [x-show][\@click\.outside], [x-show][x-on\:click\.outside], [data-motion="dropdown"]) { transform-origin: top center; }
:is(.hs-menu, [x-show][\@click\.outside][class~="right-0"], [x-show][x-on\:click\.outside][class~="right-0"], [data-motion="dropdown"][class~="right-0"]) { transform-origin: top right; }
:is([x-show][\@click\.outside][class~="left-0"], [x-show][x-on\:click\.outside][class~="left-0"], [data-motion="dropdown"][class~="left-0"]) { transform-origin: top left; }

@media (prefers-reduced-motion: no-preference) {
  :is(.hs-menu, [x-show][\@click\.outside], [x-show][x-on\:click\.outside], [data-motion="dropdown"]) {
    animation: mx-dropdown-in var(--motion-base) var(--ease-out);
    transition:
      opacity var(--motion-fast) var(--ease-standard),
      scale var(--motion-fast) var(--ease-standard),
      translate var(--motion-fast) var(--ease-standard),
      display var(--motion-fast) allow-discrete;
  }
  :is(.hs-menu, [x-show][\@click\.outside], [x-show][x-on\:click\.outside], [data-motion="dropdown"])[style*="display: none"] {
    opacity: 0;
    scale: .98;
    translate: 0 -2px;
  }

  /* Modales: el overlay lo funde Alpine/CSS; el panel entra con fade + scale + 4px. */
  [aria-modal="true"] > :first-child,
  dialog[open],
  [data-motion="modal"] { animation: mx-modal-in var(--motion-slow) var(--ease-out); }
  dialog[open]::backdrop { animation: mx-fade-in var(--motion-slow) var(--ease-out); }

  /* Overlays a pantalla completa (sidebar móvil, hoja de acciones) y hojas inferiores. */
  .fixed.inset-0[x-show],
  .fixed.inset-0[x-show] > .absolute.inset-0 { animation: mx-fade-in var(--motion-base) var(--ease-out); }
  .fixed.inset-0[x-show] > .absolute.bottom-0 { animation: mx-sheet-in var(--motion-slow) var(--ease-out); }
}

/* Clases reutilizables para x-transition explícito:
   x-transition:enter="mx-t-enter" x-transition:enter-start="mx-t-from" x-transition:enter-end="mx-t-to"
   x-transition:leave="mx-t-leave" x-transition:leave-start="mx-t-to"   x-transition:leave-end="mx-t-from" */
.mx-t-enter {
  transition:
    opacity var(--motion-base) var(--ease-out),
    scale var(--motion-base) var(--ease-out),
    translate var(--motion-base) var(--ease-out);
}
.mx-t-leave {
  transition:
    opacity var(--motion-fast) var(--ease-standard),
    scale var(--motion-fast) var(--ease-standard),
    translate var(--motion-fast) var(--ease-standard);
}
.mx-t-from { opacity: 0; scale: var(--motion-scale-in); translate: 0 calc(-1 * var(--motion-distance)); }
.mx-t-to { opacity: 1; scale: 1; translate: 0 0; }

/* Entrada genérica de un bloque al renderizar (tarjetas de confirmación, paneles). */
@media (prefers-reduced-motion: no-preference) {
  .mx-enter { animation: mx-modal-in var(--motion-slow) var(--ease-out) backwards; }
}

/* -------------------------------------------------------------------------- */
/* 8. Toasts (mensajes de Django y eventos `jia:toast`)                       */
/* -------------------------------------------------------------------------- */
.toast-stack {
  position: fixed;
  z-index: 60;
  top: calc(4rem + .75rem);
  right: 1rem;
  width: min(24rem, calc(100vw - 2rem));
  display: flex;
  flex-direction: column;
  gap: .5rem;
  pointer-events: none;
}
@media (max-width: 639px) {
  .toast-stack { left: .75rem; right: .75rem; width: auto; top: calc(4rem + .5rem); }
}
.toast {
  --toast-fg: var(--success-fg);
  --toast-soft: var(--success-bg);
  --toast-bar: #10B981;
  pointer-events: auto;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: flex-start;
  gap: .7rem;
  padding: .75rem .65rem .8rem .8rem;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: .9rem;
  box-shadow: var(--shadow-md), 0 1px 2px rgba(17, 30, 50, .06);
  font-size: .875rem;
  line-height: 1.35rem;
  transition:
    opacity var(--motion-base) var(--ease-standard),
    translate var(--motion-base) var(--ease-standard),
    scale var(--motion-base) var(--ease-standard);
}
.toast-error { --toast-fg: var(--danger-fg); --toast-soft: var(--danger-bg); --toast-bar: #EF4444; }
.toast-warning { --toast-fg: var(--warn-fg); --toast-soft: var(--warn-bg); --toast-bar: #F59E0B; }
.toast-info, .toast-debug { --toast-fg: var(--mx-info-fg); --toast-soft: var(--mx-info-bg); --toast-bar: var(--mx-info-bar); }
.toast-icon {
  flex-shrink: 0;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: .55rem;
  display: grid;
  place-items: center;
  background: var(--toast-soft);
  color: var(--toast-fg);
}
.toast-icon svg, .toast-close svg { width: 1rem; height: 1rem; }
.toast-body { flex: 1; min-width: 0; padding-top: .2rem; overflow-wrap: anywhere; }
.toast-close {
  flex-shrink: 0;
  width: 1.75rem;
  height: 1.75rem;
  margin: -.05rem -.05rem 0 0;
  border-radius: .5rem;
  display: grid;
  place-items: center;
  color: var(--muted);
  background: transparent;
}
.toast-close:hover { background: var(--surface-2); color: var(--ink); }
.toast-progress {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--toast-bar);
  opacity: .75;
  transform-origin: 0 50%;
}
.toast[data-toast-running] .toast-progress {
  display: block;
  animation: mx-toast-progress var(--toast-duration, 5s) linear forwards;
}
.toast.is-paused .toast-progress { animation-play-state: paused; }
.toast.is-leaving { opacity: 0; translate: 12px 0; scale: .98; pointer-events: none; }
@media (prefers-reduced-motion: no-preference) {
  .toast { animation: mx-toast-in var(--motion-slow) var(--ease-out) backwards; animation-delay: calc(var(--toast-index, 0) * 60ms); }
}
@media (prefers-reduced-motion: reduce) {
  .toast[data-toast-running] .toast-progress { display: none; }
  .toast.is-leaving { translate: none; scale: none; }
}

/* -------------------------------------------------------------------------- */
/* 9. Tarjetas y filas                                                        */
/*    Solo tarjetas clicables (<a>) se elevan; las <div> no prometen acción.  */
/* -------------------------------------------------------------------------- */
main :is(a.data-card, a.hs-card, a[class~="block"][class*="border"], a[class*="border"]:is([class~="p-3"], [class~="p-4"], [class~="p-5"], [class~="p-6"]), [data-hover-card]):not([draggable="true"], .mx-no-motion) {
  transition:
    translate var(--motion-base) var(--ease-out),
    box-shadow var(--motion-base) var(--ease-out),
    border-color var(--motion-fast) var(--ease-standard),
    background-color var(--motion-fast) var(--ease-standard);
}
@media (hover: hover) {
  main :is(a.data-card, a.hs-card, a[class~="block"][class*="border"], a[class*="border"]:is([class~="p-3"], [class~="p-4"], [class~="p-5"], [class~="p-6"]), [data-hover-card]):not([draggable="true"], .mx-no-motion):hover {
    box-shadow: var(--mx-card-shadow-hover);
  }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  main :is(a.data-card, a.hs-card, a[class~="block"][class*="border"], a[class*="border"]:is([class~="p-3"], [class~="p-4"], [class~="p-5"], [class~="p-6"]), [data-hover-card]):not([draggable="true"], .mx-no-motion):hover {
    translate: 0 -1px;
  }
}

/* Filas: fondo suave al hover. :where() deja ganar a las clases explícitas
   (hover:bg-*, bg-*) y a .hs-table/.data-table, que ya traen el suyo. */
:where(main table tbody tr) { transition: background-color var(--motion-fast) var(--ease-standard); }
:where(main table:not(.hs-table, .data-table) tbody tr):hover { background-color: var(--mx-row-hover); }

/* -------------------------------------------------------------------------- */
/* 10. Menú lateral (solo vía .app-sidebar-nav a y [aria-current="page"])     */
/* -------------------------------------------------------------------------- */
.app-sidebar-nav a { position: relative; }
.app-sidebar-nav a :is(svg, [data-lucide]) { transition: translate var(--motion-base) var(--ease-spring), scale var(--motion-base) var(--ease-spring); }
.app-sidebar-nav a:is([aria-current="page"], .active)::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 1rem;
  margin-top: -.5rem;
  border-radius: 0 3px 3px 0;
  background: currentColor;
  opacity: .9;
  transform-origin: 50% 50%;
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .app-sidebar-nav a:is([aria-current="page"], .active)::before { animation: mx-indicator-in var(--motion-slow) var(--ease-spring) backwards; animation-delay: 60ms; }
  .app-sidebar-nav a { transition: background-color var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard), scale var(--motion-slow) var(--ease-spring); }
  .app-sidebar-nav a:active { scale: .98; transition-duration: var(--motion-fast); }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .app-sidebar-nav a:hover :is(svg, [data-lucide]) { translate: 2px 0; }
  .app-sidebar-nav a[aria-current="page"]:hover :is(svg, [data-lucide]),
  .app-sidebar-nav a.active:hover :is(svg, [data-lucide]) { translate: 0 0; }
}

/* -------------------------------------------------------------------------- */
/* 11. Utilidades                                                             */
/* -------------------------------------------------------------------------- */
/* Skeleton con shimmer (el brillo se desplaza con translate, no con background-position). */
.skeleton {
  position: relative;
  overflow: hidden;
  display: block;
  min-height: .75rem;
  border-radius: .5rem;
  background: var(--surface-2, #F7F8FA);
  color: transparent !important;
  user-select: none;
}
.skeleton-text { height: .75rem; border-radius: .375rem; }
.skeleton-circle { border-radius: 999px; }
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  translate: -100% 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .6), transparent);
}
.dark .skeleton { background: var(--surface-2); }
.dark .skeleton::after { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .06), transparent); }
@media (prefers-reduced-motion: no-preference) {
  .skeleton::after { animation: mx-shimmer 1.4s var(--ease-standard) infinite; }
}

/* Tooltip ([data-tooltip]) y burbuja de "Copiado ✓" ([data-copy]). Un único nodo fijo. */
.mx-tooltip {
  position: fixed;
  z-index: 95;
  top: 0;
  left: 0;
  max-width: 16rem;
  padding: .3rem .55rem;
  border-radius: .45rem;
  background: #111E32;
  color: #fff;
  font-size: .75rem;
  line-height: 1.1rem;
  font-weight: 500;
  white-space: normal;
  pointer-events: none;
  box-shadow: 0 6px 20px rgba(17, 30, 50, .22);
  opacity: 0;
  translate: 0 2px;
  transition: opacity var(--motion-fast) var(--ease-out), translate var(--motion-fast) var(--ease-out);
}
.mx-tooltip[data-side="bottom"] { translate: 0 -2px; }
.mx-tooltip.is-visible { opacity: 1; translate: 0 0; }
.mx-tooltip.is-success { background: #047857; }
.dark .mx-tooltip { background: #F4F6FA; color: #111E32; box-shadow: 0 8px 24px rgba(0, 0, 0, .5); }
.dark .mx-tooltip.is-success { background: #86EFAC; color: #052E16; }
[data-copy] { cursor: copy; }
[data-copy][data-copied] { color: var(--success-fg); }

/* Solo lectores de pantalla (región aria-live de motion.js). */
.mx-sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* -------------------------------------------------------------------------- */
/* 12. Cambio de tema claro/oscuro                                            */
/*     motion.js envuelve toggleTheme(): con View Transitions hace un fundido  */
/*     cruzado de toda la página; sin ella, un fundido uniforme de colores.    */
/* -------------------------------------------------------------------------- */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--motion-slow);
  animation-timing-function: var(--ease-standard);
}
html.mx-theme-switching,
html.mx-theme-switching *,
html.mx-theme-switching *::before,
html.mx-theme-switching *::after { transition: none !important; }
html.mx-theme-fade,
html.mx-theme-fade *,
html.mx-theme-fade *::before,
html.mx-theme-fade *::after {
  transition:
    background-color var(--motion-slow) var(--ease-standard),
    border-color var(--motion-slow) var(--ease-standard),
    color var(--motion-slow) var(--ease-standard),
    fill var(--motion-slow) var(--ease-standard),
    stroke var(--motion-slow) var(--ease-standard) !important;
}
@media (prefers-reduced-motion: no-preference) {
  html.mx-theme-anim .theme-btn svg { animation: mx-icon-pop var(--motion-slow) var(--ease-spring); }
}

/* -------------------------------------------------------------------------- */
/* 13. Movimiento reducido: todo instantáneo (los spinners siguen girando     */
/*     despacio porque comunican estado, no decoran).                         */
/* -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *:not(.mx-spinner, .animate-spin),
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  .mx-spinner, .animate-spin { animation-duration: 1.6s !important; }
  .mx-btn-loading > .mx-spinner { animation: mx-spin 1.6s linear infinite !important; }
  .mx-progress.is-active { scale: 1 1; opacity: .9; }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
