/**
 * DC PROBUILD — Animaciones.
 *
 * Sólo se carga si están activadas en el Customizer.
 *
 * Regla de oro de este archivo: nunca animar propiedades que provoquen
 * recálculo de diseño (width, height, top, left, margin). Se anima
 * exclusivamente `transform` y `opacity`, que el navegador resuelve en la
 * GPU sin repintar la página. Es la diferencia entre 60 fps y un scroll
 * que se atasca en un móvil de gama media.
 */

/* =====================================================================
   Revelado al hacer scroll
   ===================================================================== */

/*
 * El estado inicial se aplica sólo cuando JavaScript ha arrancado
 * (la clase `dcpro-js` la pone theme.js en el <html>). Sin esta condición,
 * si el JS falla o tarda, todo el contenido se queda invisible para siempre:
 * el fallo más común de las animaciones al hacer scroll.
 */
.dcpro-js .dcpro-reveal {
	opacity: 0;
	transform: translateY(2.5rem);
	transition:
		opacity 0.8s var(--ease-out),
		transform 0.8s var(--ease-out);
	will-change: opacity, transform;
}

.dcpro-js .dcpro-reveal--left {
	transform: translateX(-2.5rem);
}

.dcpro-js .dcpro-reveal--right {
	transform: translateX(2.5rem);
}

.dcpro-js .dcpro-reveal.is-visible {
	opacity: 1;
	transform: none;
	/* Se libera la capa de composición cuando termina: mantener `will-change`
	   en decenas de elementos consume memoria de vídeo sin motivo. */
	will-change: auto;
}

/* Retardo escalonado dentro de una misma rejilla. */
.dcpro-js .services-grid .dcpro-reveal:nth-child(2),
.dcpro-js .why-us__grid .dcpro-reveal:nth-child(2),
.dcpro-js .testimonials__grid .dcpro-reveal:nth-child(2),
.dcpro-js .about__mv .dcpro-reveal:nth-child(2) {
	transition-delay: 0.08s;
}

.dcpro-js .services-grid .dcpro-reveal:nth-child(3),
.dcpro-js .why-us__grid .dcpro-reveal:nth-child(3),
.dcpro-js .testimonials__grid .dcpro-reveal:nth-child(3),
.dcpro-js .about__mv .dcpro-reveal:nth-child(3) {
	transition-delay: 0.16s;
}

.dcpro-js .services-grid .dcpro-reveal:nth-child(4),
.dcpro-js .why-us__grid .dcpro-reveal:nth-child(4),
.dcpro-js .testimonials__grid .dcpro-reveal:nth-child(4) {
	transition-delay: 0.24s;
}

/* =====================================================================
   Hero
   ===================================================================== */

.hero__title-line {
	animation: dcpro-line-in 0.9s var(--ease-out) both;
	animation-delay: var(--line-delay, 0s);
}

@keyframes dcpro-line-in {
	from {
		opacity: 0;
		transform: translateY(3rem);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

.hero__badge,
.hero__description,
.hero__actions,
.hero__stats {
	animation: dcpro-fade-up 0.9s var(--ease-out) both;
}

.hero__badge {
	animation-delay: 0.05s;
}

.hero__description {
	animation-delay: 0.65s;
}

.hero__actions {
	animation-delay: 0.8s;
}

.hero__stats {
	animation-delay: 0.95s;
}

@keyframes dcpro-fade-up {
	from {
		opacity: 0;
		transform: translateY(1.5rem);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

/* Punto pulsante del distintivo. */
.hero__badge-dot {
	animation: dcpro-pulse 2s ease-in-out infinite;
}

@keyframes dcpro-pulse {
	0%,
	100% {
		transform: scale(1);
		box-shadow: 0 0 0 0 rgba(var(--color-accent-rgb), 0.7);
	}
	50% {
		transform: scale(1.15);
		box-shadow: 0 0 0 10px rgba(var(--color-accent-rgb), 0);
	}
}

/* Flecha de bajada. */
.hero__scroll {
	animation: dcpro-bob 2.4s ease-in-out infinite;
}

@keyframes dcpro-bob {
	0%,
	100% {
		transform: translate(-50%, 0);
	}
	50% {
		transform: translate(-50%, 8px);
	}
}

/* =====================================================================
   Marquesina de especialidades
   ===================================================================== */

/*
 * Se desplaza exactamente el 50% porque la lista está duplicada en el HTML:
 * al llegar a la mitad, el fotograma coincide píxel a píxel con el inicio y
 * el reinicio es invisible.
 */
.brands__track {
	animation: dcpro-marquee var(--marquee-duration, 40s) linear infinite;
}

.brands__viewport:hover .brands__track {
	animation-play-state: paused;
}

@keyframes dcpro-marquee {
	from {
		transform: translateX(0);
	}
	to {
		transform: translateX(-50%);
	}
}

/* =====================================================================
   Detalles de interfaz
   ===================================================================== */

/* Despliegue del acordeón de preguntas frecuentes.
   `interpolate-size` permite animar hasta `auto` en navegadores que ya lo
   soportan; donde no, el contenido simplemente aparece sin transición. */
@supports (interpolate-size: allow-keywords) {
	html {
		interpolate-size: allow-keywords;
	}

	.faq__item::details-content {
		block-size: 0;
		overflow: hidden;
		transition: block-size 0.35s var(--ease-out), content-visibility 0.35s allow-discrete;
	}

	.faq__item[open]::details-content {
		block-size: auto;
	}
}

/*
 * Entrada escalonada del menú móvil.
 *
 * El retardo se calcula con una variable que escribe theme.js en cada <li>,
 * en lugar de una lista de `:nth-child`: así funciona con cualquier número de
 * entradas, y no sólo con las seis primeras.
 */
.dcpro-mobile-nav.is-open .dcpro-mobile-nav__list > li,
.dcpro-mobile-nav.is-open .dcpro-mobile-nav__foot > * {
	animation: dcpro-slide-in 0.45s var(--ease-out) both;
	animation-delay: calc(0.12s + var(--stagger, 0) * 0.05s);
}

@keyframes dcpro-slide-in {
	from {
		opacity: 0;
		transform: translateX(1.75rem);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

/* El botón de cierre entra girando un poco. */
.dcpro-mobile-nav.is-open .dcpro-mobile-nav__close {
	animation: dcpro-pop-in 0.4s var(--ease-out) both;
	animation-delay: 0.1s;
}

@keyframes dcpro-pop-in {
	from {
		opacity: 0;
		transform: scale(0.8) rotate(-45deg);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

/* Los submenús de escritorio entran con un desplazamiento mínimo. */
.dcpro-nav__list .sub-menu {
	transform-origin: top center;
}

/* Parallax suave del hero. El desplazamiento lo calcula animations.js y
   lo escribe en esta variable. */
.hero__media {
	transform: translate3d(0, var(--parallax-y, 0), 0);
	will-change: transform;
}

/* =====================================================================
   Hero: zoom lento, vídeo y resplandor
   ===================================================================== */

/*
 * Ken Burns: acercamiento de 20 segundos con vuelta, sobre la imagen de
 * fondo. Da sensación de vida cuando no hay vídeo, y cuesta cero: es una
 * transformación que resuelve la GPU.
 */
.hero__media--zoom .hero__image {
	animation: dcpro-ken-burns 24s ease-in-out infinite alternate;
	transform-origin: center 40%;
}

@keyframes dcpro-ken-burns {
	from {
		transform: scale(1);
	}
	to {
		transform: scale(1.12);
	}
}

/* El vídeo entra con un fundido cuando ya puede reproducirse, para que no
   dé un salto brusco sobre la imagen. */
.hero__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0;
	transition: opacity 1.2s ease;
}

.hero__video.is-ready {
	opacity: 1;
}

/* Resplandor que sigue al cursor. */
.hero__glow {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	opacity: 0;
	transition: opacity 0.6s ease;
	background: radial-gradient(
		420px circle at var(--glow-x, 50%) var(--glow-y, 50%),
		rgba(var(--color-accent-rgb), 0.16),
		transparent 65%
	);
}

.hero__glow.is-active {
	opacity: 1;
}

/* --- Estilos de la capa oscura --- */

.hero[data-overlay-style="bottom"] .hero__overlay {
	background: linear-gradient(
		to top,
		rgba(10, 10, 10, var(--hero-overlay, 0.9)) 0%,
		rgba(10, 10, 10, calc(var(--hero-overlay, 0.9) * 0.75)) 45%,
		rgba(10, 10, 10, calc(var(--hero-overlay, 0.9) * 0.35)) 100%
	);
}

.hero[data-overlay-style="flat"] .hero__overlay {
	background: rgba(10, 10, 10, var(--hero-overlay, 0.9));
}

.hero[data-overlay-style="spotlight"] .hero__overlay {
	background:
		radial-gradient(
			ellipse 70% 60% at 50% 45%,
			rgba(10, 10, 10, calc(var(--hero-overlay, 0.9) * 0.6)) 0%,
			rgba(10, 10, 10, var(--hero-overlay, 0.9)) 100%
		);
}

/* =====================================================================
   Titular por palabras
   ===================================================================== */

/*
 * Cuando JavaScript parte el titular, la animación pasa de la línea a cada
 * palabra. `overflow: hidden` en la línea hace que las palabras suban desde
 * debajo, como si asomaran por detrás de una rendija.
 */
.hero__title.is-split .hero__title-line {
	animation: none;
	opacity: 1;
	overflow: hidden;
	padding-bottom: 0.08em;
}

.hero__word {
	display: inline-block;
	animation: dcpro-word-up 0.85s var(--ease-out) both;
	animation-delay: var(--word-delay, 0s);
}

@keyframes dcpro-word-up {
	from {
		opacity: 0;
		transform: translateY(100%) rotate(3deg);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

/* =====================================================================
   Botones magnéticos e inclinación de tarjetas
   ===================================================================== */

.dcpro-magnetic {
	/* La transición sólo actúa al soltar: durante el movimiento manda el
	   JavaScript, que ya va sincronizado con el refresco de pantalla. */
	transition: transform 0.4s var(--ease-out), box-shadow var(--transition),
		background-color var(--transition), color var(--transition);
}

.service-card,
.why-card,
.mv-card,
.team-card {
	transform-style: preserve-3d;
}

.service-card.is-tilting,
.why-card.is-tilting,
.mv-card.is-tilting,
.team-card.is-tilting {
	transform: perspective(900px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)) translateY(-8px);
	transition: transform 0.12s linear;
}

/* Brillo que recorre la tarjeta siguiendo al cursor. */
.service-card.is-tilting::after,
.why-card.is-tilting::after,
.team-card.is-tilting::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	pointer-events: none;
	background: radial-gradient(
		300px circle at var(--shine-x, 50%) var(--shine-y, 50%),
		rgba(255, 255, 255, 0.07),
		transparent 60%
	);
}

/* =====================================================================
   Barra de progreso de lectura
   ===================================================================== */

.dcpro-scroll-progress {
	position: fixed;
	inset: 0 0 auto;
	z-index: 150;
	height: 3px;
	background: linear-gradient(90deg, var(--color-accent), var(--color-accent-light));
	transform: scaleX(0);
	transform-origin: left;
	pointer-events: none;
}

/* =====================================================================
   Respeto por las preferencias del sistema
   ===================================================================== */

/*
 * Si el visitante ha pedido reducir el movimiento, se desactiva todo.
 * No es un detalle estético: para personas con trastornos vestibulares,
 * el parallax y los desplazamientos automáticos provocan mareo real.
 *
 * Se anula también la clase que oculta los elementos revelados, para que el
 * contenido sea visible sin depender de ninguna animación.
 */
@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;
	}

	.dcpro-js .dcpro-reveal {
		opacity: 1;
		transform: none;
	}

	.brands__track {
		animation: none;
	}

	.hero__media,
	.hero__media--zoom .hero__image {
		transform: none;
		animation: none;
	}

	/* Las palabras del titular se muestran de golpe, sin desplazamiento. */
	.hero__word {
		animation: none;
		opacity: 1;
		transform: none;
	}

	.hero__glow,
	.dcpro-scroll-progress {
		display: none;
	}

	.service-card.is-tilting,
	.why-card.is-tilting,
	.mv-card.is-tilting,
	.team-card.is-tilting {
		transform: none;
	}
}

/* Igual que arriba, pero para el interruptor del Customizer. */
.dcpro-no-animations .dcpro-reveal {
	opacity: 1 !important;
	transform: none !important;
}

.dcpro-no-animations .brands__track,
.dcpro-no-animations .hero__scroll,
.dcpro-no-animations .hero__badge-dot {
	animation: none !important;
}
