/*
 * Transiciones de pase compartidas por el reproductor y por la vista previa
 * del panel. No duplicar: el panel carga este mismo fichero desde /player/css.
 *
 * Contrato de uso
 *   - El elemento entrante se crea con  class="qs-pase ef-<id>"
 *     y se le añade la clase "visible" en el siguiente fotograma.
 *   - El elemento saliente pasa a  class="qs-pase ef-<id> saliendo".
 *   - La duración se fija por JavaScript en style.transitionDuration
 *     (600 ms por defecto), nunca con variables CSS: hay aparatos antiguos
 *     que no las admiten.
 *
 * Rendimiento
 *   - Solo se animan transform y opacity, salvo las marcadas como pesadas,
 *     que además usan clip-path, mask o filter. Ninguna propiedad provoca
 *     recálculo de maquetación.
 *   - En aparatos con la clase low-end-device el reproductor sustituye las
 *     transiciones pesadas por un fundido simple antes de aplicar la clase.
 */

.qs-pase {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transform: translateZ(0);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.qs-pase.visible {
  opacity: 1;
}

body:not(.low-end-device) .qs-pase {
  transition-property: transform, opacity, clip-path, -webkit-clip-path, filter,
    -webkit-mask-size, mask-size;
  transition-duration: 600ms;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

.low-end-device .qs-pase,
.ef-none {
  transition: none !important;
  animation: none !important;
}

/* ------------------------------------------------------------------ */
/* Básicas                                                             */
/* ------------------------------------------------------------------ */
.ef-none {
  opacity: 1;
}

.ef-fade {
  opacity: 0;
}
.ef-fade.visible {
  opacity: 1;
}
.ef-fade.saliendo {
  opacity: 0;
}

/* ------------------------------------------------------------------ */
/* Deslizamientos: la entrante llega desde un borde                    */
/* ------------------------------------------------------------------ */
.ef-slide_left {
  transform: translateX(100%);
}
.ef-slide_right {
  transform: translateX(-100%);
}
.ef-slide_up {
  transform: translateY(100%);
}
.ef-slide_down {
  transform: translateY(-100%);
}
.ef-slide_up_left {
  transform: translate(100%, 100%);
}
.ef-slide_up_right {
  transform: translate(-100%, 100%);
}
.ef-slide_down_left {
  transform: translate(100%, -100%);
}
.ef-slide_down_right {
  transform: translate(-100%, -100%);
}

.ef-slide_left.visible,
.ef-slide_right.visible,
.ef-slide_up.visible,
.ef-slide_down.visible,
.ef-slide_up_left.visible,
.ef-slide_up_right.visible,
.ef-slide_down_left.visible,
.ef-slide_down_right.visible {
  transform: translate(0, 0);
  opacity: 1;
}

/* ------------------------------------------------------------------ */
/* Empujes: la entrante desplaza a la saliente                         */
/* ------------------------------------------------------------------ */
.ef-push_left {
  transform: translateX(100%);
}
.ef-push_right {
  transform: translateX(-100%);
}
.ef-push_up {
  transform: translateY(100%);
}
.ef-push_down {
  transform: translateY(-100%);
}

.ef-push_left.visible,
.ef-push_right.visible,
.ef-push_up.visible,
.ef-push_down.visible {
  transform: translate(0, 0);
  opacity: 1;
}

.ef-push_left.saliendo {
  opacity: 1;
  transform: translateX(-100%);
}
.ef-push_right.saliendo {
  opacity: 1;
  transform: translateX(100%);
}
.ef-push_up.saliendo {
  opacity: 1;
  transform: translateY(-100%);
}
.ef-push_down.saliendo {
  opacity: 1;
  transform: translateY(100%);
}

/* ------------------------------------------------------------------ */
/* Cubrir: la entrante pasa por encima y la saliente no se mueve       */
/* ------------------------------------------------------------------ */
.ef-cover_left {
  transform: translateX(100%);
  z-index: 2;
}
.ef-cover_right {
  transform: translateX(-100%);
  z-index: 2;
}
.ef-cover_up {
  transform: translateY(100%);
  z-index: 2;
}
.ef-cover_down {
  transform: translateY(-100%);
  z-index: 2;
}

.ef-cover_left.visible,
.ef-cover_right.visible,
.ef-cover_up.visible,
.ef-cover_down.visible {
  transform: translate(0, 0);
  opacity: 1;
}

.ef-cover_left.saliendo,
.ef-cover_right.saliendo,
.ef-cover_up.saliendo,
.ef-cover_down.saliendo {
  opacity: 1;
  z-index: 1;
  transform: translate(0, 0);
}

/* ------------------------------------------------------------------ */
/* Descubrir: la saliente se retira y deja ver a la entrante           */
/* ------------------------------------------------------------------ */
.ef-uncover_left,
.ef-uncover_right,
.ef-uncover_up,
.ef-uncover_down {
  transform: translate(0, 0);
  z-index: 1;
}

.ef-uncover_left.visible,
.ef-uncover_right.visible,
.ef-uncover_up.visible,
.ef-uncover_down.visible {
  opacity: 1;
}

.ef-uncover_left.saliendo,
.ef-uncover_right.saliendo,
.ef-uncover_up.saliendo,
.ef-uncover_down.saliendo {
  opacity: 1;
  z-index: 3;
}

.ef-uncover_left.saliendo {
  transform: translateX(-100%);
}
.ef-uncover_right.saliendo {
  transform: translateX(100%);
}
.ef-uncover_up.saliendo {
  transform: translateY(-100%);
}
.ef-uncover_down.saliendo {
  transform: translateY(100%);
}

/* ------------------------------------------------------------------ */
/* Zoom                                                                */
/* ------------------------------------------------------------------ */
.ef-zoom_in {
  transform: scale(0.85);
}
.ef-zoom_out {
  transform: scale(1.15);
}
.ef-zoom_in_soft {
  transform: scale(0.96);
}
.ef-zoom_out_soft {
  transform: scale(1.04);
}
.ef-zoom_bounce {
  transform: scale(0.6);
}
.ef-zoom_rotate {
  transform: scale(0.7) rotate(-12deg);
}

.ef-zoom_in.visible,
.ef-zoom_out.visible,
.ef-zoom_in_soft.visible,
.ef-zoom_out_soft.visible,
.ef-zoom_bounce.visible,
.ef-zoom_rotate.visible {
  transform: scale(1) rotate(0deg);
  opacity: 1;
}

.ef-zoom_bounce.visible {
  transition-timing-function: cubic-bezier(0.18, 1.5, 0.42, 1);
}
.ef-zoom_in_soft.visible,
.ef-zoom_out_soft.visible {
  transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
}

.ef-zoom_in.saliendo,
.ef-zoom_in_soft.saliendo,
.ef-zoom_bounce.saliendo {
  opacity: 0;
  transform: scale(1.08);
}
.ef-zoom_out.saliendo,
.ef-zoom_out_soft.saliendo {
  opacity: 0;
  transform: scale(0.92);
}
.ef-zoom_rotate.saliendo {
  opacity: 0;
  transform: scale(1.2) rotate(10deg);
}

/* ------------------------------------------------------------------ */
/* Giros (pesadas: perspectiva en 3D)                                  */
/* ------------------------------------------------------------------ */
.ef-flip_horizontal,
.ef-flip_vertical,
.ef-card_flip,
.ef-cube_left,
.ef-cube_right {
  perspective: 1600px;
  -webkit-perspective: 1600px;
  transform-origin: 50% 50%;
}

.ef-flip_horizontal {
  transform: perspective(1600px) rotateY(90deg);
}
.ef-flip_vertical {
  transform: perspective(1600px) rotateX(90deg);
}
.ef-card_flip {
  transform: perspective(1600px) rotateY(180deg) scale(0.9);
}
.ef-cube_left {
  transform-origin: left center;
  transform: perspective(1600px) translateX(100%) rotateY(75deg);
}
.ef-cube_right {
  transform-origin: right center;
  transform: perspective(1600px) translateX(-100%) rotateY(-75deg);
}

.ef-flip_horizontal.visible,
.ef-flip_vertical.visible,
.ef-card_flip.visible,
.ef-cube_left.visible,
.ef-cube_right.visible {
  transform: perspective(1600px) rotate(0deg) translate(0, 0) scale(1);
  opacity: 1;
}

.ef-flip_horizontal.saliendo {
  opacity: 0;
  transform: perspective(1600px) rotateY(-90deg);
}
.ef-flip_vertical.saliendo {
  opacity: 0;
  transform: perspective(1600px) rotateX(-90deg);
}
.ef-card_flip.saliendo {
  opacity: 0;
  transform: perspective(1600px) rotateY(-180deg) scale(0.9);
}
.ef-cube_left.saliendo {
  opacity: 1;
  transform-origin: right center;
  transform: perspective(1600px) translateX(-100%) rotateY(-75deg);
}
.ef-cube_right.saliendo {
  opacity: 1;
  transform-origin: left center;
  transform: perspective(1600px) translateX(100%) rotateY(75deg);
}

/* ------------------------------------------------------------------ */
/* Barridos y cortinas (pesadas: recorte, sin recálculo de maquetación) */
/* ------------------------------------------------------------------ */
.ef-wipe_horizontal {
  opacity: 1;
  -webkit-clip-path: inset(0 100% 0 0);
  clip-path: inset(0 100% 0 0);
}
.ef-wipe_vertical {
  opacity: 1;
  -webkit-clip-path: inset(100% 0 0 0);
  clip-path: inset(100% 0 0 0);
}
.ef-curtain_open {
  opacity: 1;
  -webkit-clip-path: inset(0 50% 0 50%);
  clip-path: inset(0 50% 0 50%);
}
.ef-curtain_close {
  opacity: 1;
  -webkit-clip-path: inset(0 0 0 0);
  clip-path: inset(0 0 0 0);
}
.ef-diagonal_wipe {
  opacity: 1;
  -webkit-clip-path: polygon(0 0, 0 0, 0 0, 0 0);
  clip-path: polygon(0 0, 0 0, 0 0, 0 0);
}

.ef-wipe_horizontal.visible,
.ef-wipe_vertical.visible,
.ef-curtain_open.visible {
  -webkit-clip-path: inset(0 0 0 0);
  clip-path: inset(0 0 0 0);
  opacity: 1;
}
.ef-diagonal_wipe.visible {
  -webkit-clip-path: polygon(0 0, 200% 0, 0 200%, 0 0);
  clip-path: polygon(0 0, 200% 0, 0 200%, 0 0);
  opacity: 1;
}

.ef-curtain_close.saliendo {
  opacity: 1;
  z-index: 3;
  -webkit-clip-path: inset(0 50% 0 50%);
  clip-path: inset(0 50% 0 50%);
}
.ef-wipe_horizontal.saliendo,
.ef-wipe_vertical.saliendo,
.ef-curtain_open.saliendo,
.ef-diagonal_wipe.saliendo {
  opacity: 0;
}

/* Persianas: máscara de bandas que se estrechan hasta abrirse. */
.ef-blind_horizontal,
.ef-blind_vertical {
  opacity: 1;
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
  -webkit-mask-position: 0 0;
  mask-position: 0 0;
}
.ef-blind_horizontal {
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 4%, rgba(0, 0, 0, 0) 4%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 4%, rgba(0, 0, 0, 0) 4%);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}
.ef-blind_vertical {
  -webkit-mask-image: linear-gradient(to right, #000 0%, #000 4%, rgba(0, 0, 0, 0) 4%);
  mask-image: linear-gradient(to right, #000 0%, #000 4%, rgba(0, 0, 0, 0) 4%);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}
.ef-blind_horizontal.visible {
  -webkit-mask-size: 100% 4%;
  mask-size: 100% 4%;
}
.ef-blind_vertical.visible {
  -webkit-mask-size: 4% 100%;
  mask-size: 4% 100%;
}
.ef-blind_horizontal.saliendo,
.ef-blind_vertical.saliendo {
  opacity: 0;
}

/* ------------------------------------------------------------------ */
/* Máscaras (pesadas)                                                  */
/* ------------------------------------------------------------------ */
.ef-circle_open {
  opacity: 1;
  -webkit-clip-path: circle(0% at 50% 50%);
  clip-path: circle(0% at 50% 50%);
}
.ef-circle_open.visible {
  -webkit-clip-path: circle(75% at 50% 50%);
  clip-path: circle(75% at 50% 50%);
}
.ef-circle_close {
  opacity: 1;
  -webkit-clip-path: circle(75% at 50% 50%);
  clip-path: circle(75% at 50% 50%);
}
.ef-circle_close.visible {
  -webkit-clip-path: circle(75% at 50% 50%);
  clip-path: circle(75% at 50% 50%);
}
.ef-circle_close.saliendo {
  opacity: 1;
  z-index: 3;
  -webkit-clip-path: circle(0% at 50% 50%);
  clip-path: circle(0% at 50% 50%);
}
.ef-circle_open.saliendo {
  opacity: 0;
}

.ef-diamond {
  opacity: 1;
  -webkit-clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%);
  clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%);
}
.ef-diamond.visible {
  -webkit-clip-path: polygon(50% -60%, 160% 50%, 50% 160%, -60% 50%);
  clip-path: polygon(50% -60%, 160% 50%, 50% 160%, -60% 50%);
}
.ef-diamond.saliendo {
  opacity: 0;
}

/* ------------------------------------------------------------------ */
/* Desplazamientos con desenfoque (pesadas: filtro)                    */
/* ------------------------------------------------------------------ */
.ef-blur_fade {
  opacity: 0;
  -webkit-filter: blur(24px);
  filter: blur(24px);
}
.ef-blur_zoom {
  opacity: 0;
  transform: scale(1.12);
  -webkit-filter: blur(18px);
  filter: blur(18px);
}
.ef-blur_fade.visible,
.ef-blur_zoom.visible {
  opacity: 1;
  transform: scale(1);
  -webkit-filter: blur(0);
  filter: blur(0);
}
.ef-blur_fade.saliendo,
.ef-blur_zoom.saliendo {
  opacity: 0;
  -webkit-filter: blur(24px);
  filter: blur(24px);
}

/* ------------------------------------------------------------------ */
/* Difuminados                                                         */
/* ------------------------------------------------------------------ */
/* Fundido a negro: la saliente se apaga antes de que entre la nueva.  */
.ef-fade_black {
  opacity: 0;
  background: #000;
}
.ef-fade_black.visible {
  opacity: 1;
  transition-delay: 220ms;
}
.ef-fade_black.saliendo {
  opacity: 0;
}

/* Fundido a blanco: velo blanco a media transición. */
.ef-fade_white {
  opacity: 0;
  background: #fff;
}
.ef-fade_white.visible {
  opacity: 1;
  transition-delay: 220ms;
}
.ef-fade_white.saliendo {
  opacity: 0;
}

.ef-dissolve {
  opacity: 0;
  transform: scale(1.02);
}
.ef-dissolve.visible {
  opacity: 1;
  transform: scale(1);
  transition-timing-function: linear;
}
.ef-dissolve.saliendo {
  opacity: 0;
  transition-timing-function: linear;
}

/* ------------------------------------------------------------------ */
/* Efectos con carácter                                                */
/* ------------------------------------------------------------------ */
.ef-bounce_top {
  transform: translateY(-110%);
}
.ef-bounce_bottom {
  transform: translateY(110%);
}
.ef-bounce_top.visible,
.ef-bounce_bottom.visible {
  transform: translateY(0);
  opacity: 1;
  transition-timing-function: cubic-bezier(0.17, 1.6, 0.4, 1);
}
.ef-bounce_top.saliendo {
  opacity: 0;
  transform: translateY(110%);
}
.ef-bounce_bottom.saliendo {
  opacity: 0;
  transform: translateY(-110%);
}

.ef-elastic {
  transform: scale(0.4) translateY(20%);
}
.ef-elastic.visible {
  transform: scale(1) translateY(0);
  opacity: 1;
  transition-timing-function: cubic-bezier(0.16, 2.2, 0.35, 1);
}
.ef-elastic.saliendo {
  opacity: 0;
  transform: scale(1.15);
}

.ef-inertia_slide {
  transform: translateX(115%);
}
.ef-inertia_slide.visible {
  transform: translateX(0);
  opacity: 1;
  transition-timing-function: cubic-bezier(0.12, 1.25, 0.3, 1);
}
.ef-inertia_slide.saliendo {
  opacity: 1;
  transform: translateX(-115%);
  transition-timing-function: cubic-bezier(0.6, 0, 0.9, 0.4);
}

.ef-spin_fade {
  transform: rotate(-25deg) scale(0.8);
}
.ef-spin_fade.visible {
  transform: rotate(0deg) scale(1);
  opacity: 1;
}
.ef-spin_fade.saliendo {
  opacity: 0;
  transform: rotate(25deg) scale(0.8);
}

.ef-gravity_drop {
  transform: translateY(-120%) rotate(-4deg);
}
.ef-gravity_drop.visible {
  transform: translateY(0) rotate(0deg);
  opacity: 1;
  transition-timing-function: cubic-bezier(0.6, 0.02, 0.6, 1.35);
}
.ef-gravity_drop.saliendo {
  opacity: 0;
  transform: translateY(120%) rotate(4deg);
  transition-timing-function: cubic-bezier(0.5, 0, 0.9, 0.6);
}

.ef-page_fold {
  transform-origin: left center;
  transform: perspective(1400px) rotateY(-95deg);
}
.ef-page_fold.visible {
  transform: perspective(1400px) rotateY(0deg);
  opacity: 1;
}
.ef-page_fold.saliendo {
  opacity: 1;
  z-index: 3;
  transform-origin: left center;
  transform: perspective(1400px) rotateY(95deg);
}

.ef-swing {
  transform-origin: top center;
  transform: rotate(12deg) translateY(-30%);
}
.ef-swing.visible {
  transform: rotate(0deg) translateY(0);
  opacity: 1;
  transition-timing-function: cubic-bezier(0.2, 1.8, 0.4, 1);
}
.ef-swing.saliendo {
  opacity: 0;
  transform: rotate(-12deg) translateY(30%);
}
