/* CREA · movimiento
   Animaciones de toda la app: cambio de página, acceso, modales, hojas,
   avisos, listas, pestañas y segmentados. Va después de styles.css y solo
   anima transform y opacity. La API de JavaScript está en motion.js y la guía
   en docs/MOTION.md. */

:root {
  --motion-fast: 150ms;     /* pulsaciones, salidas, cambios de color */
  --motion-base: 220ms;     /* entradas de tarjetas, indicadores, modales */
  --motion-slow: 300ms;     /* hojas inferiores, login, entrada de la shell */
  --motion-stagger: 35ms;   /* paso entre elementos de una lista */
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-in: cubic-bezier(.4, 0, 1, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --motion-distance: 8px;   /* desplazamiento de las entradas */
  --motion-scale: .97;      /* escala inicial de diálogos y tarjetas */
  --motion-sheet: 100%;     /* recorrido de las hojas inferiores */
}

@media (prefers-reduced-motion: reduce) {
  /* Sin desplazamientos ni escalas: como mucho fundidos breves. */
  :root {
    --motion-fast: 90ms;
    --motion-base: 120ms;
    --motion-slow: 140ms;
    --motion-stagger: 0ms;
    --motion-distance: 0px;
    --motion-scale: 1;
    --motion-sheet: 0px;
  }
}

@keyframes motion-in { from { opacity: 0; transform: translateY(var(--motion-distance)); } }
@keyframes motion-out { to { opacity: 0; transform: translateY(calc(var(--motion-distance) * -.75)); } }
@keyframes motion-fade-in { from { opacity: 0; } }
@keyframes motion-fade-out { to { opacity: 0; } }
@keyframes motion-pop-in { from { opacity: 0; transform: translateY(var(--motion-distance)) scale(var(--motion-scale)); } }
@keyframes motion-pop-out { to { opacity: 0; transform: translateY(calc(var(--motion-distance) / 2)) scale(var(--motion-scale)); } }
@keyframes motion-sheet-in { from { opacity: .4; transform: translateY(var(--motion-sheet)); } }
@keyframes motion-sheet-out { to { opacity: .4; transform: translateY(var(--motion-sheet)); } }
@keyframes motion-from-left { from { opacity: 0; transform: translateX(calc(var(--motion-distance) * -2)); } }
@keyframes motion-from-top { from { opacity: 0; transform: translateY(calc(var(--motion-distance) * -1)); } }
@keyframes motion-from-bottom { from { opacity: 0; transform: translateY(calc(var(--motion-distance) * 2)); } }
@keyframes motion-drop { from { opacity: 0; transform: translateY(calc(var(--motion-distance) * -.5)); } }
@keyframes motion-spin { to { transform: rotate(360deg); } }

/* Salida genérica de Motion.leave(); los componentes la afinan abajo. */
.motion-leaving { animation: motion-fade-out var(--motion-fast) var(--ease-in) both; pointer-events: none; }

/* Entrada escalonada (Motion.enter y las tarjetas de cada vista). El retraso
   lo pone motion.js en --motion-delay. */
.motion-in { animation: motion-in var(--motion-base) var(--ease-out) var(--motion-delay, 0ms) both; }

/* ---------- Cambio de página: View Transitions ---------- */
/* motion.js pone html.motion-vt mientras dura la transición: solo el contenido
   se mueve; barra lateral, cabecera, barra inferior y avisos quedan quietos. */
html.motion-vt #view { view-transition-name: crea-view; }
html.motion-vt .side { view-transition-name: crea-side; }
html.motion-vt .top { view-transition-name: crea-top; }
html.motion-vt #top-title { view-transition-name: crea-title; }
html.motion-vt #top-sub { view-transition-name: crea-sub; }
html.motion-vt .tabbar { view-transition-name: crea-tabbar; }
html.motion-vt .toasts { view-transition-name: crea-toasts; }

/* Durante la transición se puede seguir pulsando la página real. */
::view-transition { pointer-events: none; }
::view-transition-group(*) { animation-duration: var(--motion-base); animation-timing-function: var(--ease-out); }
::view-transition-old(root), ::view-transition-new(root),
::view-transition-group(root),
::view-transition-group(crea-side), ::view-transition-old(crea-side), ::view-transition-new(crea-side),
::view-transition-group(crea-top), ::view-transition-old(crea-top), ::view-transition-new(crea-top),
::view-transition-group(crea-tabbar), ::view-transition-old(crea-tabbar), ::view-transition-new(crea-tabbar),
::view-transition-group(crea-toasts), ::view-transition-old(crea-toasts), ::view-transition-new(crea-toasts),
::view-transition-group(crea-view), ::view-transition-group(crea-title), ::view-transition-group(crea-sub) { animation: none; }

/* El contenido sale fundiéndose hacia arriba y el nuevo entra desde abajo. La
   imagen vieja se queda donde estaba aunque la página nueva empiece arriba. */
::view-transition-old(crea-view) {
  animation: motion-vt-out var(--motion-fast) var(--ease-in) both;
}
::view-transition-new(crea-view) {
  animation: motion-in var(--motion-slow) var(--ease-out) 80ms both;
}
@keyframes motion-vt-out {
  from { transform: translateY(var(--motion-vt-dy, 0px)); }
  to { opacity: 0; transform: translateY(calc(var(--motion-vt-dy, 0px) - var(--motion-distance) * .75)); }
}
::view-transition-image-pair(crea-view) { isolation: auto; }
::view-transition-old(crea-view), ::view-transition-new(crea-view) { mix-blend-mode: normal; height: auto; }

/* Pestañas de una misma ficha: fundido sin desplazamiento (la cabecera de la
   ficha no se mueve) y el contenido de la pestaña entra escalonado. */
html.motion-vt-tab::view-transition-old(crea-view) { animation: motion-fade-out var(--motion-fast) var(--ease-in) both; }
html.motion-vt-tab::view-transition-new(crea-view) { animation: motion-fade-in var(--motion-base) var(--ease-out) both; }

::view-transition-old(crea-title), ::view-transition-old(crea-sub) { animation: motion-fade-out var(--motion-fast) var(--ease-in) both; }
::view-transition-new(crea-title), ::view-transition-new(crea-sub) { animation: motion-fade-in var(--motion-base) var(--ease-out) both; }

/* Respaldo sin View Transitions (Firefox antiguo, Safari < 18): una copia
   fija del contenido anterior se desvanece mientras entra el nuevo. */
.motion-ghost {
  position: fixed; z-index: 15; margin: 0; pointer-events: none; overflow: hidden;
  animation: motion-out var(--motion-fast) var(--ease-in) both;
}

/* Carga: si una vista tarda, una silueta suave en lugar de un hueco. */
#view.motion-loading::after {
  content: ""; display: block; height: 220px; border-radius: 14px;
  background:
    linear-gradient(90deg, transparent 0, rgba(255,255,255,.65) 50%, transparent 100%) -100% 0 / 60% 100% no-repeat,
    linear-gradient(#e9edeb, #e9edeb) 22px 26px / 34% 10px no-repeat,
    linear-gradient(#eff2f0, #eff2f0) 22px 56px / 72% 10px no-repeat,
    linear-gradient(#eff2f0, #eff2f0) 22px 84px / 58% 10px no-repeat,
    linear-gradient(#eff2f0, #eff2f0) 22px 112px / 66% 10px no-repeat,
    #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.03), 0 8px 20px -12px rgba(69,94,77,.18);
  animation: motion-fade-in var(--motion-base) var(--ease-out) both, motion-shimmer 1.4s linear infinite;
}
@keyframes motion-shimmer { to { background-position: 200% 0, 22px 26px, 22px 56px, 22px 84px, 22px 112px, 0 0; } }

/* ---------- Acceso ---------- */
.login::before, .login::after { animation: motion-fade-in 700ms var(--ease-out) both; }
.login-card { animation: motion-pop-in var(--motion-slow) var(--ease-out) both; }
.login-card > *, .login-card form > * { animation: motion-in var(--motion-slow) var(--ease-out) both; }
.login-card > :nth-child(2) { animation-delay: 60ms; }
.login-card form > :nth-child(1) { animation-delay: 100ms; }
.login-card form > :nth-child(2) { animation-delay: 135ms; }
.login-card form > :nth-child(3), .login-card form > :nth-child(4) { animation-delay: 170ms; }
.login-card > .fine { animation-delay: 210ms; }
.login-card .form-error:not([hidden]) { animation: motion-drop var(--motion-base) var(--ease-out) both; }
.login-card.motion-leaving { animation: motion-pop-out var(--motion-base) var(--ease-in) both; }

/* Botón ocupado: el de «Entrar» mientras se envía y cualquiera con
   Motion.busy(boton). */
.login-card .btn:disabled, .btn[aria-busy="true"] { opacity: .9; }
.login-card .btn:disabled::before, .btn[aria-busy="true"]::before {
  content: ""; width: 13px; height: 13px; border-radius: 50%; flex: none;
  border: 2px solid rgba(255,255,255,.45); border-top-color: #fff; animation: motion-spin .7s linear infinite;
}
.btn-ghost[aria-busy="true"]::before, .btn-danger[aria-busy="true"]::before { border-color: var(--sage-2); border-top-color: var(--sage-medium); }

/* Shell al entrar (motion.js pone .motion-entering un instante). */
.app.motion-entering .side { animation: motion-from-left var(--motion-slow) var(--ease-out) both; }
.app.motion-entering .nav a { animation: motion-in var(--motion-base) var(--ease-out) both; }
.app.motion-entering .nav a:nth-child(2) { animation-delay: 30ms; }
.app.motion-entering .nav a:nth-child(3) { animation-delay: 60ms; }
.app.motion-entering .nav a:nth-child(4) { animation-delay: 90ms; }
.app.motion-entering .nav a:nth-child(5) { animation-delay: 120ms; }
.app.motion-entering .nav a:nth-child(6) { animation-delay: 150ms; }
.app.motion-entering .nav a:nth-child(n+7) { animation-delay: 180ms; }
.app.motion-entering .me { animation: motion-in var(--motion-base) var(--ease-out) 200ms both; }
.app.motion-entering .top { animation: motion-from-top var(--motion-slow) var(--ease-out) 60ms both; }
.app.motion-entering .tabbar { animation: motion-from-bottom var(--motion-slow) var(--ease-out) 80ms both; }
.app.motion-leaving { animation: motion-fade-out var(--motion-base) var(--ease-in) both; }

/* ---------- Modales y hojas ---------- */
.overlay { animation: motion-fade-in var(--motion-base) var(--ease-out) both; backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
.overlay .modal { animation: motion-pop-in var(--motion-base) var(--ease-out) both; }
.overlay.motion-leaving { animation: motion-fade-out var(--motion-fast) var(--ease-in) 30ms both; }
.overlay.motion-leaving .modal { animation: motion-pop-out var(--motion-fast) var(--ease-in) both; }

.sheet-dim { animation: motion-fade-in var(--motion-base) var(--ease-out) both; }
.sheet { animation: motion-sheet-in var(--motion-slow) var(--ease-out) both; }
.sheet-dim.motion-leaving { animation: motion-fade-out var(--motion-base) var(--ease-in) both; }
.sheet.motion-leaving { animation: motion-sheet-out var(--motion-base) var(--ease-in) both; }
.sheet .sheet-list > * { animation: motion-in var(--motion-base) var(--ease-out) both; }
.sheet .sheet-list > :nth-child(2) { animation-delay: 20ms; }
.sheet .sheet-list > :nth-child(3) { animation-delay: 40ms; }
.sheet .sheet-list > :nth-child(4) { animation-delay: 60ms; }
.sheet .sheet-list > :nth-child(5) { animation-delay: 80ms; }
.sheet .sheet-list > :nth-child(6) { animation-delay: 100ms; }
.sheet .sheet-list > :nth-child(n+7) { animation-delay: 120ms; }
.sheet.motion-leaving .sheet-list > * { animation: none; }
.sheet.sheet-pop { transform-origin: bottom left; animation: motion-pop-in var(--motion-base) var(--ease-out) both; }
.sheet.sheet-pop.motion-leaving { animation: motion-pop-out var(--motion-fast) var(--ease-in) both; }

@media (max-width: 600px) {
  /* En móvil el modal es una hoja que sube desde abajo. */
  .overlay .modal { animation: motion-sheet-in var(--motion-slow) var(--ease-out) both; }
  .overlay.motion-leaving .modal { animation: motion-sheet-out var(--motion-base) var(--ease-in) both; }
}

/* Desplegables: resultados de búsqueda de familia y similares. */
.pick > * { animation: motion-drop var(--motion-base) var(--ease-out) both; }
.pick > :nth-child(2) { animation-delay: 25ms; }
.pick > :nth-child(3) { animation-delay: 50ms; }
.pick > :nth-child(n+4) { animation-delay: 75ms; }

/* Avisos */
.toast { animation: motion-pop-in var(--motion-base) var(--ease-out) both; }
.toast.motion-leaving { animation: motion-pop-out var(--motion-fast) var(--ease-in) both; }

/* Mensajes que aparecen en formularios y fichas */
/* (los banners se repintan al teclear: no se animan para que no parpadeen) */
.form-error:not([hidden]) { animation: motion-fade-in var(--motion-base) var(--ease-out) both; }

/* ---------- Indicadores que se deslizan ---------- */
/* motion.js añade un .motion-ind a .seg, .tabs y .nav y lo coloca bajo el
   elemento .on; el fondo del .on pasa al indicador. */
.motion-has-ind { position: relative; }
.motion-has-ind > :not(.motion-ind) { position: relative; z-index: 1; }
.motion-ind {
  position: absolute; left: 0; top: 0; z-index: 0; pointer-events: none;
  transition: transform var(--motion-base) var(--ease-out), width var(--motion-base) var(--ease-out),
    height var(--motion-base) var(--ease-out), opacity var(--motion-fast) linear;
}
.motion-ind.motion-ind-instant { transition: none; }
.seg > .motion-ind { background: #fff; border-radius: 10px; box-shadow: 0 1px 4px rgba(0,0,0,.08); }
.seg.motion-has-ind > button.on { background: transparent; box-shadow: none; }
.seg > button { transition: color var(--motion-base) var(--ease-out); }
.tabs > .motion-ind { background: var(--green); border-radius: 2px; }
.tabs.motion-has-ind > a.on { border-color: transparent; }
.tabs > a { transition: color var(--motion-base) var(--ease-out); }
.nav > .motion-ind { background: var(--sage-soft); border-radius: 10px; }
.nav.motion-has-ind > a.on { background: transparent; }
.nav > a { transition: background-color var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out); }

/* ---------- Microinteracciones ---------- */
.btn { transition: transform var(--motion-fast) var(--ease-out), box-shadow var(--motion-fast) var(--ease-out), filter var(--motion-fast), background-color var(--motion-fast); }
.btn:not(:disabled):active { transform: scale(.97); transition-duration: 80ms; }
.iconbtn, .appbar-avatar, .me, .swatches button, .check input, .pick button, .sheet-list a, .sheet-list button, .arow, .svcrow, .chev, .inp, .search {
  transition: transform var(--motion-fast) var(--ease-out), background-color var(--motion-fast) var(--ease-out),
    box-shadow var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out);
}
.iconbtn:active, .appbar-avatar:active { transform: scale(.92); }
.me:active, .sheet-list a:active, .sheet-list button:active, .pick button:active { transform: scale(.985); }
.sheet-list a:active, .sheet-list button:active { background: var(--bg-alt); }
.arow:active, .svcrow.clickable:active { transform: scale(.993); }
.check input:checked { animation: motion-check var(--motion-base) var(--ease-out); }
@keyframes motion-check { from { transform: scale(.8); } }
.tabbar a .ic, .tabbar button .ic { transition: transform var(--motion-fast) var(--ease-out); }
.tabbar a:active .ic, .tabbar button:active .ic { transform: scale(.88); }
.tabbar a, .tabbar button { transition: color var(--motion-fast) var(--ease-out); }

@media (hover: hover) {
  .btn:not(:disabled):hover { transform: translateY(-1px); }
  .btn-pink:not(:disabled):hover { box-shadow: 0 8px 18px -10px rgba(201,134,128,.9); }
  .btn-sage:not(:disabled):hover { box-shadow: 0 8px 18px -10px rgba(69,94,77,.6); }
  .btn-ghost:not(:disabled):hover { box-shadow: inset 0 0 0 1px var(--sage-medium), 0 8px 18px -12px rgba(69,94,77,.45); }
  .btn-danger:not(:disabled):hover { box-shadow: inset 0 0 0 1px #e0aaa5, 0 8px 18px -12px rgba(162,70,63,.45); }
  .btn:not(:disabled):active { transform: scale(.97); }
  .arow:hover .chev { transform: translateX(3px); color: var(--sage-medium); }
  .swatches button:hover { transform: scale(1.08); }
  a.card, .card.clickable { transition: transform var(--motion-base) var(--ease-out), box-shadow var(--motion-base) var(--ease-out); }
  a.card:hover, .card.clickable:hover { transform: translateY(-2px); box-shadow: 0 1px 2px rgba(0,0,0,.03), 0 14px 28px -14px rgba(69,94,77,.3); }
}

@media (prefers-reduced-motion: reduce) {
  .btn:not(:disabled):hover, .btn:not(:disabled):active, .iconbtn:active, .appbar-avatar:active, .me:active,
  .sheet-list a:active, .sheet-list button:active, .pick button:active, .arow:active, .svcrow.clickable:active,
  .arow:hover .chev, .swatches button:hover, a.card:hover, .card.clickable:hover,
  .tabbar a:active .ic, .tabbar button:active .ic { transform: none; }
  .check input:checked { animation: none; }
  .motion-ind { transition: opacity var(--motion-fast) linear; }
  #view.motion-loading::after { animation: motion-fade-in var(--motion-base) linear both; }
}

/* ---------- Cobros ---------- */
/* La barra de cuotas crece al entrar su tarjeta (no en un repintado tras guardar). */
@keyframes motion-grow-x { from { transform: scaleX(0); } }
.motion-in .qbar { transform-origin: left; animation: motion-grow-x var(--motion-slow) var(--ease-out) calc(var(--motion-delay, 0ms) + 80ms) both; }
.tray .item.motion-leaving { animation: motion-out var(--motion-fast) var(--ease-in) both; }
.rep td { transition: background-color var(--motion-fast) var(--ease-out); }
.rep tr.on td { background: rgba(239, 244, 242, .55); }


/* Fase 4 · botones de fichaje: misma pulsación que los botones píldora y un
   indicador de carga mientras el servidor guarda la hora. */
.fbtn { transition: transform var(--motion-fast) var(--ease-out), box-shadow var(--motion-fast) var(--ease-out), opacity var(--motion-base) var(--ease-out); }
.fbtn:not(:disabled):active { transform: scale(.98); transition-duration: 80ms; }
@media (hover: hover) {
  .fbtn:not(:disabled):hover { transform: translateY(-1px); }
}
.fbtn[aria-busy="true"] { opacity: .9; }
.fbtn[aria-busy="true"]::after {
  content: ""; margin-left: auto; width: 18px; height: 18px; border-radius: 50%; flex: none;
  border: 2px solid rgba(255,255,255,.45); border-top-color: #fff; animation: motion-spin .7s linear infinite;
}
.fbtn[aria-busy="true"] .ok { display: none; }
.uso { transition: background-color var(--motion-fast) var(--ease-out); }
