/* ==========================================================================
   Vértice Commerce 2 — core/motion.css
   Capa de movimiento del MOTOR (siempre encolada, al final del core): reveal
   por scroll, transiciones del chrome (drawers, dropdown), micro-feedback de
   press, contador del carrito, barra de envío, marquee de logos y FAB de
   WhatsApp. Porta la mecánica de motion-premium.css de v1 con SOLO
   tokens semánticos (nada de curvas/colores de marca: --tr, --tr-slow,
   --ease-out; --ease-spring es RESERVADO del contrato para la capa de
   diseño, el core no lo consume).

   REGLA DEL CONTRATO (fix woocommerce.css:140): TODO el movimiento vive
   dentro de @media (prefers-reduced-motion: no-preference) Y ADEMÁS el
   archivo cierra con el bloque global de reduced-motion. Doble cinturón: lo
   que un módulo declare fuera del media query correcto igual queda frenado.

   !important permitidos y documentados en este archivo:
   - Bloque global @media (prefers-reduced-motion: reduce) del final
     (animation-duration/iteration-count, transition-duration,
     scroll-behavior): es EL fix de auditoría y debe ganarle a cualquier
     declaración del core, de la capa de diseño o de plugins.
     animation-iteration-count:1 acompaña a la duración de 0.01ms: sin él,
     las animaciones infinitas (marquee, pulso del FAB) quedarían loopeando
     a 0.01ms y quemarían CPU.

   z-index literal permitido y documentado en este archivo (excepción al
   contrato "z-index solo vía --z-*" de Task 12):
   - z-index: -1 en .vc-whatsapp-fab::before — truco de apilamiento LOCAL al
     stacking context que crea el propio FAB (z-index: var(--z-nav)): el
     anillo del pulso queda detrás del contenido del FAB sin participar de
     la escala --z-* (no compite con ningún otro plano del sitio).

   Contratos con el JS del motor (Task 11) DEFINIDOS ACÁ:
   - Reveal: elementos [data-vc-reveal] (template-parts/home/*); el observer
     agrega .is-visible al entrar al viewport. Red de seguridad solo-CSS: si
     main.js no corre, el keyframe vc-reveal-safety muestra todo a los ~1.8s
     (el reveal es mejora progresiva: JAMÁS puede dejar contenido oculto).
   - Marquee (inc/trust.php): el JS agrega .is-enhanced a .vc-marquee para
     activar el loop (sin JS queda la grilla estática y el botón de pausa
     sigue hidden) y alterna .is-paused + aria-pressed en el toggle.
   ========================================================================== */

/* ---------------------------- Keyframes -------------------------------- */
@keyframes vc-reveal-safety { to { opacity: 1; transform: none; } }
@keyframes vc-count-pop {
	0% { transform: scale(0.6); }
	55% { transform: scale(1.25); }
	100% { transform: scale(1); }
}
@keyframes vc-fab-pulse {
	0% { transform: scale(1); opacity: 0.45; }
	70%, 100% { transform: scale(1.65); opacity: 0; }
}
/* -100% = el ancho de la propia pista; con la pista duplicada (aria-hidden)
   y el gap del viewport, el loop es continuo. */
@keyframes vc-marquee-scroll { to { transform: translateX(calc(-100% - var(--sp-6))); } }

/* ============================ 1. TRANSICIONES BASE ====================== */
/* Los estados hover/focus/abierto se DECLARAN en reset/layout/components/
   nav/shop (sin transición: funcionales solos); acá se les da el easing.
   Solo propiedades de pintura/transform (GPU-friendly, sin layout). */
@media (prefers-reduced-motion: no-preference) {
	a { transition: color var(--tr); }

	.vc-btn,
	.vc-icon-btn,
	.vc-chip,
	.vc-qty__btn,
	.vc-drawer__link,
	.vc-pagination .page-numbers,
	.vc-pagelinks > a,
	.vc-livesearch__item,
	.vc-livesearch__all,
	.vc-nav .sub-menu a,
	.vc-drawer .woocommerce-mini-cart__buttons .button,
	.vc-drawer .woocommerce-mini-cart-item a.remove {
		transition:
			background-color var(--tr),
			color var(--tr),
			border-color var(--tr),
			box-shadow var(--tr),
			opacity var(--tr),
			transform var(--tr);
	}

	.vc-input,
	.vc-textarea { transition: border-color var(--tr), background-color var(--tr); }

	.vc-nav .menu-item-has-children > a::after { transition: transform var(--tr); }
}

/* ============================ 2. FEEDBACK DE PRESS ====================== */
/* Todo pressable responde al click con un scale sutil (0.92–0.97, nunca
   bouncy). Vive completo en no-preference: bajo reduce no escala. */
@media (prefers-reduced-motion: no-preference) {
	.vc-icon-btn:active { transform: scale(0.94); }
	.vc-qty__btn:active:not(:disabled) { transform: scale(0.92); }
	.vc-btn:active:not(:disabled):not([aria-disabled="true"]) { transform: scale(0.97); }
	.vc-pagination a.page-numbers:active { transform: scale(0.95); }
	.vc-drawer .woocommerce-mini-cart__buttons .button:active { transform: scale(0.97); }
}

/* ============================ 3. REVEAL POR SCROLL ====================== */
/* [data-vc-reveal] en las secciones de la home (nunca en el hero: es el LCP).
   Solo opacity/transform. El estado base oculto vive DENTRO de no-preference:
   con reduce el contenido es visible desde el primer frame, sin trucos. */
@media (prefers-reduced-motion: no-preference) {
	[data-vc-reveal] {
		opacity: 0;
		transform: translateY(1.25rem);
		transition: opacity var(--tr-slow), transform var(--tr-slow);
		/* Red de seguridad sin JS (documentada en cabecera). */
		animation: vc-reveal-safety 0.01s linear 1.8s forwards;
	}
	[data-vc-reveal].is-visible {
		opacity: 1;
		transform: none;
	}
}

/* ============================ 4. DRAWERS + DROPDOWN ===================== */
/* Estados finales en core/nav.css; acá SOLO la transición. visibility entra
   en la transición para que el panel siga visible durante el cierre (la
   propiedad es discreta: no-hidden durante todo el tramo animado). */
@media (prefers-reduced-motion: no-preference) {
	.vc-drawer__overlay { transition: opacity var(--tr), visibility var(--tr); }
	.vc-drawer__panel { transition: transform var(--tr-slow), visibility var(--tr-slow); }

	.vc-nav .sub-menu {
		transform-origin: top left;
		transition: opacity var(--tr), transform var(--tr), visibility var(--tr);
	}
}

/* ============================ 5. CONTADOR DEL CARRITO =================== */
/* El fragment AJAX (inc/woocommerce.php) reemplaza span.vc-cart-count al
   agregar al carrito: la animación corre sola al re-insertarse el nodo, sin
   JS extra. Mismo pop para el contador de wishlist (lo re-crea el JS). */
@media (prefers-reduced-motion: no-preference) {
	.vc-cart-count:not([hidden]),
	.vc-wishlist-count:not([hidden]) { animation: vc-count-pop 260ms var(--ease-out); }
}

/* ============================ 6. BARRA DE ENVÍO GRATIS ================== */
/* components.css documenta que el fill (.vc-shipbar__fill, inline
   transform:scaleX) se anima acá: al reemplazarse los totales por AJAX el
   progreso desliza en vez de saltar. */
@media (prefers-reduced-motion: no-preference) {
	.vc-shipbar__fill { transition: transform var(--tr-slow), background-color var(--tr); }
}

/* ============================ 7. MARQUEE DE LOGOS ======================= */
/* inc/trust.php: .vc-marquee[data-vc-marquee] > button.vc-marquee__toggle
   [hidden] + .vc-marquee__viewport > ul.vc-marquee__track ×2 (la segunda con
   aria-hidden="true").

   Degradación en cascada (contrato del módulo):
   - Sin JS: grilla estática centrada, pista duplicada oculta, toggle hidden.
   - Con JS pero reduced-motion: el bloque global del final congela el loop
     (0.01ms × 1 iteración) ⇒ en la práctica, la misma grilla estática.
   - Con JS y motion OK (.is-enhanced): loop infinito pausable por el toggle
     (.is-paused), por hover y por foco dentro de la pista. */
.vc-marquee { position: relative; }
.vc-marquee__viewport {
	display: flex;
	gap: var(--sp-6);
	overflow: hidden;
}
.vc-marquee__track {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--sp-5) var(--sp-6);
	flex: none;
	min-width: 100%;
}
/* Estático (sin JS / sin animación): la pista duplicada no aporta nada. */
.vc-marquee__track[aria-hidden="true"] { display: none; }
.vc-marquee__item { display: flex; align-items: center; }
.vc-marquee__logo {
	width: auto;
	height: auto;
	max-height: 48px;
	max-width: 160px;
	object-fit: contain;
}

/* Toggle de pausa (nace hidden; lo revela el JS junto con .is-enhanced).
   Target 36px + estados con tokens; el foco lo da el anillo global. */
.vc-marquee__toggle {
	position: absolute;
	right: 0;
	bottom: calc(100% + var(--sp-2));
	display: inline-grid;
	place-items: center;
	width: 36px;
	height: 36px;
	border: var(--border-w) solid var(--line);
	border-radius: var(--radius-pill);
	background: var(--surface);
	color: var(--ink-2);
}
.vc-marquee__toggle:hover { color: var(--brand-strong); border-color: var(--brand); }
.vc-marquee__toggle[aria-pressed="true"] { background: var(--surface-2); color: var(--ink); }
.vc-marquee__toggle svg { width: 16px; height: 16px; }

@media (prefers-reduced-motion: no-preference) {
	.vc-marquee.is-enhanced .vc-marquee__track {
		flex-wrap: nowrap;
		justify-content: flex-start;
		animation: vc-marquee-scroll var(--vc-marquee-duration, 32s) linear infinite;
	}
	.vc-marquee.is-enhanced .vc-marquee__track[aria-hidden="true"] { display: flex; }

	/* Pausa: toggle, hover o foco de teclado dentro del marquee. */
	.vc-marquee.is-paused .vc-marquee__track,
	.vc-marquee.is-enhanced:hover .vc-marquee__track,
	.vc-marquee.is-enhanced:focus-within .vc-marquee__track {
		animation-play-state: paused;
	}
}

/* ============================ 8. ESTADO DE CARGA ======================== */
/* Estado de carga genérico en botones (el JS deshabilita + agrega la clase;
   requests en vuelo, contrato de Task 11). */
.vc-btn.is-loading { opacity: 0.7; cursor: progress; }

/* ============================ 9. FAB DE WHATSAPP ======================== */
/* footer.php: a.vc-whatsapp-fab (SOLO se renderiza con número cargado).
   Posición + pulso = mecánica del motor; el color va con el par --cta-*
   (contraste AA por contrato). La capa de diseño suele re-pintarlo con el
   verde reconocible de WhatsApp (#25D366 con tinta oscura) — decisión de
   piel, no del motor.
   z-index: --z-nav (bajo --z-overlay/--z-modal): con un drawer abierto el
   overlay lo cubre y captura el click — sin las clases de body que usaba v1
   para esconderlo a mano. */
.vc-whatsapp-fab {
	position: fixed;
	right: clamp(1rem, 3vw, 1.75rem);
	bottom: clamp(1rem, 3vw, 1.75rem);
	z-index: var(--z-nav);
	display: grid;
	place-items: center;
	width: 56px;
	height: 56px;
	border-radius: var(--radius-pill);
	background: var(--cta-bg);
	color: var(--cta-ink);
	box-shadow: var(--shadow-2);
}
.vc-whatsapp-fab:hover { background: var(--cta-bg-hover); color: var(--cta-ink); }
.vc-whatsapp-fab svg { width: 28px; height: 28px; }
.vc-whatsapp-fab:focus-visible { outline-offset: 3px; }

@media (prefers-reduced-motion: no-preference) {
	/* opacity en la lista: sin ella el opacity:0 del @starting-style de abajo
	   saltaría a 1 en el primer frame (solo animaría el scale). */
	.vc-whatsapp-fab {
		transition:
			background-color var(--tr),
			box-shadow var(--tr),
			transform var(--tr),
			opacity var(--tr);
	}
	@media (hover: hover) and (pointer: fine) {
		.vc-whatsapp-fab:hover { transform: translateY(-2px); box-shadow: var(--shadow-3); }
	}
	/* Entrada suave al cargar (solo realza un default ya visible). */
	@starting-style {
		.vc-whatsapp-fab { opacity: 0; transform: scale(0.85); }
	}
	/* Pulso de atención: anillo que emana y se desvanece (lento, sutil). */
	.vc-whatsapp-fab::before {
		content: "";
		position: absolute;
		inset: 0;
		z-index: -1;
		border-radius: inherit;
		background: var(--cta-bg);
		animation: vc-fab-pulse 2.6s var(--ease-out) infinite;
	}
}

/* ============================ 10. REDUCED MOTION (GLOBAL) =============== */
/* Fix woocommerce.css:140 — bloque global del contrato. Frena TODO el
   movimiento del sitio (core, capa de diseño y plugins): animaciones a un
   frame, transiciones instantáneas y scroll sin smooth (complementa el gate
   de scroll-behavior de reset.css). !important documentado en la cabecera;
   animation-iteration-count evita loops infinitos a 0.01ms (CPU). */
@media (prefers-reduced-motion: reduce) {
	*,
	::before,
	::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}
