/* =========================================
   COMPONENTE: FADE IN LAB
   Cada variante está aislada para poder compararla.
   Ninguna variante usa `infinite`.
   ========================================= */

:root {
  --fade-duration: 4s;
}

/* =========================================
   fade1 — CSS animation clásica
   ========================================= */
.sample-1 { opacity: 0; }
.sample-1.is-playing { animation: fade1-in var(--fade-duration) ease-in-out 1 both; }
@keyframes fade1-in { from { opacity: 0; } to { opacity: 1; } }

/* =========================================
   fade2 — CSS animation con variable de duración
   ========================================= */
.sample-2 { opacity: 0; }
.sample-2.is-playing { animation: fade2-in var(--fade-duration) ease-in-out 1 forwards; }
@keyframes fade2-in { 0% { opacity: 0; } 100% { opacity: 1; } }

/* =========================================
   fade3 — CSS transition + clase de estado
   ========================================= */
.sample-3 { opacity: 0; transition: opacity var(--fade-duration) ease-in-out; }
.sample-3.is-visible { opacity: 1; }

/* =========================================
   fade4 — Pure CSS checkbox + transition
   No requiere JavaScript para producir el cambio visual.
   ========================================= */
.sample-4 { opacity: 0; transition: opacity var(--fade-duration) ease-in-out; }
.experiment-card:has([data-native-toggle]:checked) .sample-4 { opacity: 1; }

/* =========================================
   fade5 — opacity + visibility
   La opacidad hace el fade; visibility controla la interacción.
   ========================================= */
.sample-5 {
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--fade-duration) ease-in-out, visibility 0s linear var(--fade-duration);
}
.sample-5.is-visible {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--fade-duration) ease-in-out, visibility 0s linear 0s;
}

/* =========================================
   fade6 — animation-play-state
   La animación queda pausada hasta recibir .is-running.
   ========================================= */
.sample-6 { opacity: 0; animation: fade6-in var(--fade-duration) ease-in-out 1 both paused; }
.sample-6.is-running { animation-play-state: running; }
@keyframes fade6-in { from { opacity: 0; } to { opacity: 1; } }

/* =========================================
   fade7 — JS asigna animation al elemento
   ========================================= */
.sample-7 { opacity: 0; }
@keyframes fade7-in { from { opacity: 0; } to { opacity: 1; } }

/* =========================================
   fade8 — forced reflow
   La clase se quita, se fuerza un reflow y vuelve a agregarse.
   ========================================= */
.sample-8 { opacity: 0; }
.sample-8.is-playing { animation: fade8-in var(--fade-duration) ease-in-out 1 both; }
@keyframes fade8-in { from { opacity: 0; } to { opacity: 1; } }

/* =========================================
   fade9 — clone node
   El JS reemplaza el nodo para garantizar un ciclo limpio.
   ========================================= */
.sample-9 { opacity: 0; }
.sample-9.is-playing { animation: fade9-in var(--fade-duration) ease-in-out 1 both; }
@keyframes fade9-in { from { opacity: 0; } to { opacity: 1; } }

/* =========================================
   fade10 — atributo data-state
   El estado visual está representado por un atributo HTML.
   ========================================= */
.sample-10 { opacity: 0; transition: opacity var(--fade-duration) ease-in-out; }
.sample-10[data-state="visible"] { opacity: 1; }

/* =========================================
   fade11 — Web Animations API
   Este bloque solo define la apariencia base.
   ========================================= */
.sample-11 { opacity: 0; }

/* =========================================
   fade12 — Web Animations API + easing configurable
   ========================================= */
.sample-12 { opacity: 0; }

/* =========================================
   fade13 — KeyframeEffect + Animation
   ========================================= */
.sample-13 { opacity: 0; }

/* =========================================
   fade14 — requestAnimationFrame
   JS controla directamente opacity.
   ========================================= */
.sample-14 { opacity: 0; }

/* =========================================
   fade15 — setInterval
   Experimental. Se incluye solamente para comparación.
   ========================================= */
.sample-15 { opacity: 0; }

/* =========================================
   fade16 — transition + inline style
   CSS solo aporta transition; JS escribe el valor final.
   ========================================= */
.sample-16 { opacity: 0; transition: opacity var(--fade-duration) ease-in-out; }

/* =========================================
   fade17 — IntersectionObserver + transition
   ========================================= */
.sample-17 { opacity: 0; transition: opacity var(--fade-duration) ease-in-out; }
.sample-17.is-visible { opacity: 1; }

/* =========================================
   fade18 — IntersectionObserver + animation
   ========================================= */
.sample-18 { opacity: 0; }
.sample-18.is-visible { animation: fade18-in var(--fade-duration) ease-in-out 1 both; }
@keyframes fade18-in { from { opacity: 0; } to { opacity: 1; } }

/* =========================================
   fade19 — @starting-style
   La transición se activa al insertar el elemento.
   ========================================= */
.sample-19 {
  opacity: 1;
  transition: opacity var(--fade-duration) ease-in-out;
}
@starting-style {
  .sample-19 { opacity: 0; }
}

/* =========================================
   fade20 — View Transition API
   La transición de documento se configura aquí.
   ========================================= */
.sample-20 { view-transition-name: fade-lab-sample; opacity: 1; }
::view-transition-old(fade-lab-sample),
::view-transition-new(fade-lab-sample) { animation-duration: var(--fade-duration); }

@media (prefers-reduced-motion: reduce) {
  .sample-1.is-playing, .sample-2.is-playing, .sample-6, .sample-6.is-running,
  .sample-8.is-playing, .sample-9.is-playing, .sample-18.is-visible {
    animation-duration: .01ms;
  }
}
