/**
 * ENFOQUE MULTIFORMATO — MÓDULO AUDIO
 * /assets/css/enfoque-multiformato-audio.css
 *
 * VERSIÓN ACTUAL: 1.9.12 — debe coincidir con $version en
 * enfoque_audio_enqueue() (enfoque-audio.php). Si al abrir este
 * archivo en el navegador (la URL exacta que carga la página, con su
 * ?ver=) no aparece "1.9.12" acá arriba, el archivo en el servidor
 * NO es este — es una versión vieja y hay que resubirlo.
 *
 * v1.9.12 — SOLO el encabezado: este CSS no cambió. La versión se sube
 * para mantener el mismo $version que enfoque-audio.php v1.9.12, que
 * ahora encola los assets del reproductor cada vez que renderiza una
 * tarjeta (fix de la home, donde los bloques no estaban como shortcodes
 * dentro del contenido de la página). Ver el changelog de ese archivo.
 *
 * v1.9.11 — se quitan los anillos de foco de los controles de la
 * tarjeta de audio (outline), en TODOS los contextos donde aparece la
 * tarjeta (posts, popups del HUB — Facetas Business, El Hincha,
 * Marketplace — y popup del ePaper). Diagnosticado con la consola real
 * (getComputedStyle del elemento enfocado tras Tab/Espacio): el botón
 * play mostraba outline rgba(255,255,255,.6) 2px (regla propia de la
 * sección ACCESIBILIDAD, más abajo) y mute/velocidad un outline azul
 * rgb(40,114,250) 2px — el foco global de Blocksy. En los tres casos
 * es 'outline'; el resplandor rojo del play es un box-shadow aparte y
 * NO se toca. Fix: una regla nueva, ADITIVA, en la sección ACCESIBILIDAD,
 * acotada a los descendientes de .enfoque-audio (button, a, input,
 * [role="slider"], [tabindex]) en :focus y :focus-visible, con
 * especificidad (0,3,0) — mayor que la regla del play (0,2,0) y que
 * cualquier selector simple del tema, sin !important. No se modificó
 * ninguna regla existente (la del play queda, pero esta la supera). El
 * resaltado de fondo de los ítems del menú compartir (:focus-visible,
 * background) NO es un outline y no se toca. Nota de accesibilidad: sin
 * anillo, quien navega con teclado ya no ve qué control tiene el foco
 * (decisión del usuario).
 *
 * v1.9.10 — FIX real del parpadeo al iniciar reproducción, reportado
 * en los 4 contextos (post+popup, mobile+desktop) incluso después de
 * v1.9.8/v1.9.9 (que arreglaban saltos de LAYOUT, no parpadeos de
 * opacidad). Causa: .enfoque-audio__loader (overlay oscuro al 50%
 * que cubre toda la tarjeta durante is-loading) alternaba display:
 * none/flex de forma instantánea, e is-loading dura ~15-20ms para un
 * mp3 ya bufferizado (confirmado con la consola real del usuario) —
 * el overlay se encendía y apagaba de golpe en ese lapso. No depende
 * del póster (por eso afectaba post Y popup) ni del ancho (por eso
 * mobile Y desktop) — es un overlay genérico, no provider-específico.
 * Fix: opacity+visibility con transición retrasada 200ms SOLO al
 * entrar a is-loading (si la carga real dura menos, el overlay nunca
 * llega a mostrarse); la salida sigue siendo inmediata. Ver
 * .enfoque-audio__loader más abajo. No modifica is-loading del grid
 * (v1.9.8) ni del póster (v1.9.9), ambos siguen vigentes.
 *
 * v1.9.9 — FIX real, diagnosticado con evidencia de consola
 * (PerformanceObserver layout-shift + ResizeObserver, no solo lectura
 * de código): el fix de v1.9.8 (agregar is-loading a la visibilidad
 * de .podcast-grid) rompió la simetría con .enfoque-audio__poster
 * —elemento EN FLUJO NORMAL (position:relative, aspect-ratio:2/1,
 * ocupa espacio real propio, ~375px de alto en un contenedor de
 * 750px)—, que se oculta en is-playing/is-paused/is-ended pero NO
 * is-loading. Como el popup del HUB nunca tiene póster (enfoque_
 * render_audio_podcast_card_generico() no lo imprime), ahí nunca se
 * notó; en el sistema multiformato de POSTS, que sí usa póster, cada
 * click de play pasa brevemente por is-loading, el póster deja de
 * cumplir ninguna condición de ocultamiento y reaparece empujando
 * todo hacia abajo (~375px), y ~50ms después is-playing lo vuelve a
 * ocultar — ese reaparecer/desaparecer era el salto/flash reportado
 * en los posts (confirmado con 2 LAYOUT SHIFT consecutivos en la
 * consola real del usuario, exactos en timing y magnitud). Fix:
 * is-loading agregado también a la lista de ocultamiento del póster
 * — ver .enfoque-audio__poster más abajo, simétrico al fix del grid.
 * No toca nada de .podcast-top-right/badge/duración/velocidad
 * (v1.9.7) ni el fix de is-loading del grid (v1.9.8, sigue vigente).
 *
 * v1.9.8 — FIX: salto/flash del contenedor al iniciar la reproducción
 * dentro del popup. Causa real: play() (enfoque-multiformato-audio.js)
 * pasa siempre por engine.setState(STATES.LOADING) antes de que el
 * audio realmente arranque; is-loading no estaba en la lista de
 * estados donde .podcast-grid es visible (solo is-playing/is-paused/
 * is-ended), así que el grid completo colapsaba (display:none) y
 * volvía a expandirse (display:grid) en cada click de play — eso era
 * el salto. Agregado is-loading a esa lista (ver .podcast-grid más
 * abajo). El spinner de carga (.enfoque-audio__loader) es
 * position:absolute + inset:0, no participa del flujo/tamaño, así que
 * puede mostrarse encima del grid ya visible sin volver a tocar su
 * CSS. No modifica nada de .podcast-top-right/badge/duración/velocidad
 * (v1.9.7, intacto) ni la regla del póster del sistema multiformato de
 * posts (sin cambios, no aplica al popup).
 *
 * v1.9.7 — REVERT del cambio de v1.9.6 en .podcast-top-right (ese
 * cambio apuntaba a la regla de ESCRITORIO — justify-content:center→
 * flex-start — pero las capturas que motivaron el reporte eran de
 * MOBILE, donde esa regla ni siquiera aplica; quedó fuera de alcance,
 * revertido a como estaba). FIX real, acotado a mobile + popup del
 * HUB exclusivamente: bloque nuevo @media(max-width:640px) con
 * selector .enfoque-audio-wrap--hub (clase que SOLO existe en el
 * markup del popup) que achica badge/duración/velocidad, para que
 * vuelvan a entrar en el mismo renglón que en el post individual —
 * causa real: el popup (.enf-hub-embed-panel, width:92%+padding:16px)
 * le come más ancho al contenedor que un post individual en la misma
 * pantalla, así que en teléfonos angostos badge+top-right dejaban de
 * entrar juntos y top-right caía a su propio renglón. No toca la
 * regla mobile compartida con el post (intacta) ni ninguna regla de
 * escritorio.
 *
 * v1.9.6 (REVERTIDO en v1.9.7 — ver arriba) — FIX: en .podcast-top-right (duración + velocidad), 
 * justify-content pasa de center a flex-start. Causa real: .podcast-top
 * tiene align-items:stretch, así que este bloque siempre se estira a
 * la altura completa de .podcast-headline (badge+gap+título en
 * columna) — centrado, quedaba invisible cuando el headline es corto
 * (post individual, contenedor ancho) pero muy visible cuando crece
 * (popup del HUB, contenedor angosto por la imagen fija de 300px).
 * flex-start lo pega siempre a la altura del badge. Exclusivo de
 * desktop — mobile ya usa align-items:center en .podcast-top (no
 * stretch) y no se ve afectado, sin cambios ahí. Único cambio de esta
 * versión.
 *
 * v1.9.5 — FIX botón de velocidad (ancho estable). El texto cicla
 * 1.0x/1.25x/1.5x/1.75x/2.0x sin ancho mínimo; al crecer un carácter,
 * el botón ensanchaba .podcast-top-right (flex-shrink:0), le quitaba
 * ancho al título, lo reflotaba y corría waveform/controles/tiempos
 * hacia abajo. Ver .enfoque-audio__podcast-speed más abajo — único
 * cambio de esta versión, resto del archivo intacto desde v1.9.4.
 *
 * v1.3.2
 * FIXES:
 * - Eliminado espacio blanco superior en Spotify
 * - Eliminado comportamiento tipo acordeón
 * - Spotify ahora reemplaza completamente el poster
 * - iframe Spotify completamente normalizado
 * - Sin gaps ni alturas fantasma
 * - FIX SoundCloud Widget API READY
 * - Eliminado loading infinito SoundCloud
 * - iframe oculto estable para Widget API
 * - FIX SoundCloud: display:none en iframe-wrap impedía carga del iframe
 *
 * v1.4.0 — TARJETA PODCAST (audio_source = mp3)
 * - Nuevo layout de dos columnas para el reproductor de audio self-hosted,
 *   completamente separado del layout vertical de Spotify/SoundCloud.
 * - Forma de onda decorativa (mismo mecanismo que enfoque-play-bloque.php).
 * - Controles nuevos: skip ±10s, velocidad, volumen, repetir, compartir,
 *   descargar.
 */

/* =====================================================
 * WRAP
 * ===================================================== */

.enfoque-audio-wrap {
  width: 100%;
  max-width: 820px;
  margin: 40px auto;
}

.enfoque-audio-wrap .enfoque-media-inner {
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 18px 60px rgba(0,0,0,.48);
  transition:
    transform .55s cubic-bezier(.22,.61,.36,1),
    box-shadow .55s cubic-bezier(.22,.61,.36,1);
}

.enfoque-audio-wrap:hover .enfoque-media-inner {
  transform: translateY(-2px);
  box-shadow:
    0 28px 80px rgba(0,0,0,.58),
    0 0 0 1px rgba(255,255,255,.03);
}

/* =====================================================
 * CONTENEDOR PRINCIPAL
 * ===================================================== */

.enfoque-audio {
  position: relative;
  width: 100%;
  background: var(--enfoque-color-surface);
  overflow: hidden;
  font-family: var(--enfoque-font-ui);
  color: var(--enfoque-color-text);
}

/* =====================================================
 * POSTER
 * ===================================================== */

.enfoque-audio__poster {
  position: relative;
  width: 100%;
  aspect-ratio: 2 / 1;
  overflow: hidden;
  background: var(--enfoque-color-surface-alt);
  cursor: pointer;
}

.enfoque-audio__poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--enfoque-transition-slow);
}

.enfoque-audio:hover .enfoque-audio__poster img {
  transform: scale(1.04);
}

.enfoque-audio__poster::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--enfoque-overlay-gradient);
  pointer-events: none;
}

/* =====================================================
 * PLAY TRIGGER
 * ===================================================== */

.enfoque-audio__play-trigger {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: var(--enfoque-z-controls);
  cursor: pointer;
  background: transparent;
  border: none;
  padding: 0;
}

.enfoque-audio__play-trigger-inner {
  width: 64px;
  height: 64px;
  border-radius: var(--enfoque-radius-pill);
  background: var(--enfoque-glass);
  border: 1.5px solid var(--enfoque-glass-border);
  backdrop-filter: var(--enfoque-glass-blur);
  -webkit-backdrop-filter: var(--enfoque-glass-blur);
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    transform var(--enfoque-transition-spring),
    background var(--enfoque-transition-fast),
    border-color var(--enfoque-transition-fast),
    box-shadow var(--enfoque-transition-fast);
  box-shadow: var(--enfoque-shadow-md);
}

.enfoque-audio__play-trigger:hover .enfoque-audio__play-trigger-inner {
  transform: var(--enfoque-hover-scale);
  background: var(--enfoque-glass-hover);
  border-color: rgba(207,0,0,.45);
  box-shadow: 0 0 0 4px rgba(207,0,0,.18), var(--enfoque-shadow-md);
}

.enfoque-audio__play-trigger:active .enfoque-audio__play-trigger-inner {
  transform: var(--enfoque-active-scale);
}

.enfoque-audio__play-trigger-inner svg {
  width: 24px;
  height: 24px;
  fill: #cf0000;
  margin-left: 3px;
  filter: drop-shadow(0 1px 6px rgba(207,0,0,.55));
}

/* =====================================================
 * BADGE
 * ===================================================== */

.enfoque-audio__badge {
  position: absolute;
  top: var(--enfoque-space-md);
  left: var(--enfoque-space-md);
  z-index: var(--enfoque-z-overlay);
  display: flex;
  align-items: center;
  gap: var(--enfoque-space-xs);
  padding: 4px 10px;
  background: rgba(207,0,0,.82);
  border: 1px solid rgba(255,255,255,.10);
  backdrop-filter: var(--enfoque-glass-blur);
  -webkit-backdrop-filter: var(--enfoque-glass-blur);
  border-radius: var(--enfoque-radius-pill);
  font-size: var(--enfoque-text-xs);
  font-weight: 600;
  letter-spacing: var(--enfoque-tracking-wider);
  text-transform: uppercase;
  color: #fff;
  box-shadow: 0 8px 22px rgba(207,0,0,.22);
  pointer-events: none;
}

.enfoque-audio__badge svg {
  width: 10px;
  height: 10px;
  opacity: .9;
}

.enfoque-audio[data-provider="spotify"] .enfoque-audio__badge svg {
  fill: #1ed760;
}

.enfoque-audio[data-provider="soundcloud"] .enfoque-audio__badge svg,
.enfoque-audio[data-provider="self"] .enfoque-audio__badge svg {
  fill: #ffffff;
}

/* =====================================================
 * META
 * ===================================================== */

.enfoque-audio__meta {
  padding: var(--enfoque-space-md) var(--enfoque-space-lg);
  background: var(--enfoque-color-surface);
  display: flex;
  flex-direction: column;
  gap: var(--enfoque-space-xs);
}

.enfoque-audio__title {
  font-family: var(--enfoque-font-display);
  font-size: var(--enfoque-text-lg);
  font-weight: 700;
  letter-spacing: var(--enfoque-tracking-tight);
  color: var(--enfoque-color-text);
  line-height: 1.3;
  margin: 0;
}

.enfoque-audio__subtitle {
  font-size: var(--enfoque-text-sm);
  color: var(--enfoque-color-text-muted);
  letter-spacing: .01em;
  margin: 0;
}

/* =====================================================
 * CONTROLES
 * ===================================================== */

.enfoque-audio__controls {
  display: none;
  align-items: center;
  gap: var(--enfoque-space-md);
  padding: var(--enfoque-space-sm) var(--enfoque-space-lg) var(--enfoque-space-md);
  background: var(--enfoque-color-surface);
}

.enfoque-audio.is-playing .enfoque-audio__controls,
.enfoque-audio.is-paused .enfoque-audio__controls {
  display: flex;
}

.enfoque-audio__btn-playpause {
  width: 40px;
  height: 40px;
  border-radius: var(--enfoque-radius-pill);
  background: var(--enfoque-glass);
  border: 1px solid var(--enfoque-glass-border);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}

.enfoque-audio__btn-playpause svg {
  width: 16px;
  height: 16px;
  fill: var(--enfoque-color-text);
}

.enfoque-audio__icon-play {
  display: block;
}

.enfoque-audio__icon-pause {
  display: none;
}

.enfoque-audio.is-playing .enfoque-audio__icon-play {
  display: none;
}

.enfoque-audio.is-playing .enfoque-audio__icon-pause {
  display: block;
}

/* =====================================================
 * PROGRESS
 * ===================================================== */

.enfoque-audio__progress-wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.enfoque-audio__progress-track {
  position: relative;
  height: 3px;
  background: var(--enfoque-glass);
  border-radius: var(--enfoque-radius-pill);
  overflow: hidden;
}

.enfoque-audio__progress-buffer,
.enfoque-audio__progress-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
}

.enfoque-audio__progress-buffer {
  background: rgba(255,255,255,.15);
}

.enfoque-audio__progress-fill {
  background: var(--enfoque-color-text);
}

.enfoque-audio__time {
  display: flex;
  justify-content: space-between;
  font-size: var(--enfoque-text-xs);
  color: var(--enfoque-color-text-muted);
  font-variant-numeric: tabular-nums;
}

/* =====================================================
 * IFRAME WRAP
 * ===================================================== */

.enfoque-audio__iframe-wrap {
  display: none;
  width: 100%;
  overflow: hidden;
  background: #121212;
  position: relative;
  line-height: 0;
}

/* =====================================================
 * SPOTIFY FIX CRÍTICO
 * ===================================================== */

.enfoque-audio[data-provider="spotify"].is-playing .enfoque-audio__iframe-wrap,
.enfoque-audio[data-provider="spotify"].is-paused .enfoque-audio__iframe-wrap {
  display: block;
}

.enfoque-audio__iframe-sp {
  display: block !important;
  width: 100% !important;
  height: 352px !important;
  border: 0 !important;
  margin: 0 !important;
  padding: 0 !important;
  vertical-align: top !important;
  background: #121212 !important;
  min-height: 0 !important;
  max-height: none !important;
  position: relative !important;
  z-index: 1 !important;
}

/* =====================================================
 * SOUNDCLOUD — FIX WIDGET API
 *
 * CRÍTICO: display:block es obligatorio.
 * display:none impide que el navegador cargue el iframe,
 * lo que hace que el Widget API nunca dispare READY.
 * El iframe se oculta visualmente con left:-99999px,
 * no con display:none.
 * ===================================================== */

.enfoque-audio[data-provider="soundcloud"] .enfoque-audio__iframe-wrap {
  display: block;
  position: absolute;
  top: 0;
  left: -99999px;
  width: 100%;
  height: 166px;
  overflow: hidden;
  pointer-events: none;
}

.enfoque-audio__iframe-sc {
  width: 100%;
  height: 166px;
  border: 0;
  display: block;
}

/* =====================================================
 * SPOTIFY POSTER REPLACEMENT
 * ===================================================== */

.enfoque-audio[data-provider="spotify"].is-playing .enfoque-audio__poster,
.enfoque-audio[data-provider="spotify"].is-paused .enfoque-audio__poster {
  display: none;
}

/* =====================================================
 * SOUNDCLOUD — ACTIVACIÓN VISIBLE
 * ===================================================== */

.enfoque-audio[data-provider="soundcloud"].is-playing .enfoque-audio__poster,
.enfoque-audio[data-provider="soundcloud"].is-paused .enfoque-audio__poster {
  display: none;
}

.enfoque-audio[data-provider="soundcloud"].is-playing .enfoque-audio__iframe-wrap,
.enfoque-audio[data-provider="soundcloud"].is-paused .enfoque-audio__iframe-wrap {
  position: static;
  left: auto;
  height: 166px;
  pointer-events: auto;
}

.enfoque-audio[data-provider="soundcloud"].is-playing .enfoque-audio__iframe-sc,
.enfoque-audio[data-provider="soundcloud"].is-paused .enfoque-audio__iframe-sc {
  height: 166px;
}

/* =====================================================
 * SPOTIFY NOTE
 * ===================================================== */

.enfoque-audio__spotify-note {
  display: block;
  padding: var(--enfoque-space-sm) var(--enfoque-space-lg);
  font-size: var(--enfoque-text-xs);
  color: var(--enfoque-color-text-muted);
  background: #121212;
  line-height: 1.4;
}

/* =====================================================
 * LOADER
 * ===================================================== */

/* v1.9.10 — FIX real del parpadeo (post+popup, mobile+desktop) al
   iniciar reproducción: este overlay (fondo oscuro al 50%, cubre toda
   la tarjeta) alternaba display:none/flex de forma INSTANTÁNEA junto
   con is-loading — y is-loading dura ~15-20ms para un mp3 ya
   bufferizado (confirmado con la consola real del usuario), así que
   el overlay se encendía y apagaba de golpe en ese lapso: eso era el
   parpadeo. No depende del póster (por eso pasaba en post Y popup por
   igual) ni del ancho (por eso en mobile Y desktop). Solución: en vez
   de display:none/flex, se usa opacity+visibility con transición
   RETRASADA 200ms solo al ENTRAR a is-loading — si la carga real dura
   menos que eso (el caso normal, audio ya cacheado), is-loading
   termina antes de que el retraso se cumpla y el overlay nunca llega
   a mostrarse. La salida (is-loading→cualquier otro estado) siempre
   es inmediata, sin retraso, para no demorar el caso real de carga
   lenta donde sí hace falta avisar. */
.enfoque-audio__loader {
  display: flex;
  position: absolute;
  inset: 0;
  z-index: var(--enfoque-z-overlay);
  align-items: center;
  justify-content: center;
  background: var(--enfoque-overlay-medium);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .15s ease, visibility 0s linear .15s;
}

.enfoque-audio.is-loading .enfoque-audio__loader {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity .15s ease .2s, visibility 0s linear .2s;
}

.enfoque-audio__loader-spinner {
  width: 32px;
  height: 32px;
  border: 2px solid rgba(255,255,255,.15);
  border-top-color: rgba(255,255,255,.80);
  border-radius: 999px;
  animation: enfoque-spin .75s linear infinite;
}

@keyframes enfoque-spin {
  to {
    transform: rotate(360deg);
  }
}

/* =====================================================
 * ERROR
 * ===================================================== */

.enfoque-audio__error {
  display: none;
  align-items: center;
  gap: var(--enfoque-space-sm);
  padding: var(--enfoque-space-sm) var(--enfoque-space-lg);
  background: rgba(220,50,50,.12);
  border-top: 1px solid rgba(220,50,50,.25);
  font-size: var(--enfoque-text-sm);
  color: #ff7070;
}

.enfoque-audio.is-error .enfoque-audio__error {
  display: flex;
}

/* =====================================================
 * RESPONSIVE
 * ===================================================== */

@media (max-width: 768px) {

  .enfoque-audio-wrap {
    max-width: 100%;
    margin: 24px auto;
  }

  .enfoque-audio-wrap .enfoque-media-inner {
    border-radius: 16px;
  }

}

@media (max-width: 600px) {

  .enfoque-audio__play-trigger-inner {
    width: 52px;
    height: 52px;
  }

  .enfoque-audio__play-trigger-inner svg {
    width: 20px;
    height: 20px;
  }

  .enfoque-audio__meta {
    padding: var(--enfoque-space-md);
  }

  .enfoque-audio__controls {
    padding: var(--enfoque-space-xs) var(--enfoque-space-md) var(--enfoque-space-md);
    gap: var(--enfoque-space-sm);
  }

  .enfoque-audio__title {
    font-size: var(--enfoque-text-md);
  }

  .enfoque-audio__iframe-sp {
    height: 352px !important;
  }

}

/* =====================================================
 * ACCESIBILIDAD
 * ===================================================== */

.enfoque-audio__btn-playpause:focus-visible,
.enfoque-audio__play-trigger:focus-visible {
  outline: 2px solid rgba(255,255,255,.6);
  outline-offset: 3px;
}

/* v1.9.11 — Sin anillo de foco en los controles de la tarjeta (ver el
 * changelog arriba). Especificidad (0,3,0): supera a la regla anterior
 * del play (0,2,0) y al foco global de Blocksy. Solo quita el outline:
 * el box-shadow del play y el fondo de los ítems del menú compartir no
 * se tocan. */
.enfoque-audio :is(button, a, input, [role="slider"], [tabindex]):is(:focus, :focus-visible) {
  outline: none;
}

@media (prefers-reduced-motion: reduce) {

  .enfoque-audio *,
  .enfoque-audio *::before,
  .enfoque-audio *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }

}

/* =====================================================
 * TARJETA PODCAST (audio_source = mp3)
 *
 * Layout de dos columnas, completamente separado del layout vertical
 * de Spotify/SoundCloud de arriba.
 *
 * COLORES: fijos y literales, medidos píxel por píxel del mockup de
 * referencia (reproductor_audio_top.png), NO heredados de los tokens
 * compartidos (--enfoque-color-surface, --enfoque-color-text, etc.).
 * Se decidió así a propósito: esos tokens heredan la paleta de Blocksy
 * de este sitio, que no es oscura, y el mockup exige un negro/rojo
 * cinematográfico exacto e inamovible sin importar la configuración
 * del tema. Valores medidos:
 *   - Fondo del panel:            #030406
 *   - Acento rojo (badge, play,
 *     forma de onda, progreso):   #e6070a
 *   - Barras de onda sin sonar:   #393d45
 *   - Track de progreso pendiente:#525a63
 *   - Todo el texto (título,
 *     subtítulo, meta, tiempos):  #ffffff (medido, sin jerarquía de grises)
 * ===================================================== */

.enfoque-audio-wrap--podcast {
  max-width: 980px;
}

.enfoque-audio--podcast {
  background: #030406;
}

.enfoque-audio__podcast-grid {
  display: none;
  grid-template-columns: 300px 1fr;
  align-items: stretch;
}

/* Revelado: mismo mecanismo que Spotify/SoundCloud (poster se oculta,
   el reproductor completo aparece, al pasar a playing/paused). is-ended
   se agrega para que, al terminar el audio, el reproductor se quede
   visible en vez de volver al póster (el usuario puede usar ahí mismo
   "Volver a escuchar").
   v1.9.8 — se agrega is-loading: play() (enfoque-multiformato-audio.js)
   pasa SIEMPRE por engine.setState(STATES.LOADING) antes de que el
   audio realmente empiece ("this._audio.play()" se llama después de
   ese setState) — is-loading no estaba en esta lista, así que en cada
   click de play el grid completo pasaba por display:none y volvía a
   display:grid apenas después, colapsando y expandiendo el contenedor
   — el salto/flash reportado. .enfoque-audio__loader (el spinner) es
   position:absolute + inset:0 (no participa del flujo/tamaño), así
   que puede mostrarse ENCIMA del grid ya visible sin que éste tenga
   que ocultarse — no hace falta tocar el loader ni su CSS para esto.
   No modifica nada de .podcast-top-right/badge/duración/velocidad. */
.enfoque-audio[data-provider="self"].is-playing .enfoque-audio__podcast-grid,
.enfoque-audio[data-provider="self"].is-paused .enfoque-audio__podcast-grid,
.enfoque-audio[data-provider="self"].is-ended .enfoque-audio__podcast-grid,
.enfoque-audio[data-provider="self"].is-loading .enfoque-audio__podcast-grid {
  display: grid;
}

.enfoque-audio[data-provider="self"].is-playing .enfoque-audio__poster,
.enfoque-audio[data-provider="self"].is-paused .enfoque-audio__poster,
.enfoque-audio[data-provider="self"].is-ended .enfoque-audio__poster,
.enfoque-audio[data-provider="self"].is-loading .enfoque-audio__poster {
  display: none;
}

.enfoque-audio__podcast-media {
  position: relative;
  overflow: hidden;
  background: #0c0204;
}

.enfoque-audio__podcast-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left center;
  display: block;
}

.enfoque-audio__podcast-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: var(--enfoque-space-lg);
  min-width: 0;
  color: #ffffff;
}

.enfoque-audio__podcast-info,
.enfoque-audio__podcast-player {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.enfoque-audio__podcast-top {
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: var(--enfoque-space-md);
}

.enfoque-audio__podcast-headline {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
}

.enfoque-audio__podcast-headline .enfoque-audio__podcast-title {
  margin: 0;
}

.enfoque-audio__podcast-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  line-height: 1;
  background: rgba(230, 7, 10, .85);
  color: #ffffff;
  font-size: var(--enfoque-text-xs);
  font-weight: 700;
  letter-spacing: var(--enfoque-tracking-wider);
  text-transform: uppercase;
  border-radius: var(--enfoque-radius-pill);
  white-space: nowrap;
}

.enfoque-audio__podcast-badge svg {
  width: 12px;
  height: 12px;
  fill: #ffffff;
}

.enfoque-audio__podcast-top-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 8px;
  flex-shrink: 0;
  padding-left: var(--enfoque-space-md);
  border-left: 1px solid rgba(255, 255, 255, .12);
}

.enfoque-audio__podcast-duration {
  display: flex;
  align-items: center;
  gap: 4px;
  color: #ffffff;
  font-size: var(--enfoque-text-xs);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.enfoque-audio__podcast-duration svg {
  width: 14px;
  height: 14px;
  color: #e6070a;
}

.enfoque-audio__podcast-speed {
  padding: 6px 14px;
  border: 1px solid rgba(230, 7, 10, .5);
  border-radius: var(--enfoque-radius-pill);
  background: transparent;
  color: #e6070a;
  font-size: var(--enfoque-text-xs);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: background var(--enfoque-transition-fast);
  /* v1.9.5 — FIX: el texto cicla 1.0x/1.25x/1.5x/1.75x/2.0x (hasta 5
     caracteres) sin ancho mínimo; al crecer un carácter, el botón
     ensanchaba .podcast-top-right (flex-shrink:0), que le quitaba
     ancho al título, lo reflotaba y corría todo el bloque de abajo
     (waveform/controles/tiempos). box-sizing:border-box para que el
     min-width incluya el padding; 5ch reserva el texto más largo
     ("1.75x"); tabular-nums evita que los dígitos angostos/anchos de
     la fuente varíen el ancho entre valores. */
  box-sizing: border-box;
  min-width: calc(5ch + 30px);
  text-align: center;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.enfoque-audio__podcast-speed:hover {
  background: rgba(230, 7, 10, .12);
}

.enfoque-audio__podcast-title {
  font-family: var(--enfoque-font-ui);
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: var(--enfoque-tracking-tight);
  color: #ffffff;
  line-height: 1.2;
  /* Cancela el "half-leading" que agrega line-height por encima y por
     debajo del texto (0.1em = (1.2-1)/2), en em (relativo a la propia
     fuente de este elemento) — así el hueco visible real hacia el
     badge y hacia el subtítulo pasa a ser EXACTAMENTE el gap del flex
     (10px), sin importar que este texto sea más grande que los demás.
     Esta es la causa real de que ratios de line-height a ojo nunca
     den huecos parejos entre textos de distinto tamaño. */
  margin-block: -0.1em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.enfoque-audio__podcast-subtitle {
  font-size: var(--enfoque-text-base);
  color: #ffffff;
  line-height: 1.3;
  margin-block: -0.15em;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.enfoque-audio__podcast-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--enfoque-text-sm);
  color: #ffffff;
  line-height: 1.2;
  margin-block: -0.1em;
}

.enfoque-audio__podcast-meta-sep {
  opacity: .5;
}

/* --- Forma de onda --- */

.enfoque-audio__waveform {
  position: relative;
  height: 48px;
  margin: 6px 0 2px;
  cursor: pointer;
  --enfoque-wave-progress: 0%;
}

.enfoque-audio__waveform-bars {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  gap: 2px;
  overflow: hidden;
}

.enfoque-audio__waveform-bars span {
  flex: 1 1 auto;
  min-width: 2px;
  max-width: 4px;
  border-radius: 2px;
  background: #393d45;
  transform-origin: bottom;
}

.enfoque-audio__waveform-bars--progress {
  width: var(--enfoque-wave-progress);
}

.enfoque-audio__waveform-bars--progress span {
  background: #e6070a;
}

.enfoque-audio.is-playing .enfoque-audio__waveform-bars span {
  animation: enfoque-audio-eq var(--eq-d, 1s) ease-in-out infinite alternate;
  animation-delay: var(--eq-delay, 0s);
}

@keyframes enfoque-audio-eq {
  from { transform: scaleY(.55); }
  to   { transform: scaleY(1); }
}

/* --- Controles: skip / play-pause grande --- */

.enfoque-audio__podcast-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--enfoque-space-md);
  padding: 4px 0;
}

.enfoque-audio__podcast-track {
  width: 32px;
  height: 32px;
  border: none;
  background: transparent;
  color: #ffffff;
  opacity: .35;
  cursor: not-allowed;
  display: flex;
  align-items: center;
  justify-content: center;
}

.enfoque-audio__podcast-track svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}

.enfoque-audio__podcast-skip {
  position: relative;
  width: 40px;
  height: 40px;
  border: none;
  background: transparent;
  color: #ffffff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.enfoque-audio__podcast-skip svg {
  width: 28px;
  height: 28px;
  fill: currentColor;
}

.enfoque-audio__podcast-skip--fwd svg {
  transform: scaleX(-1);
}

.enfoque-audio__podcast-skip span {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  padding-top: 2px;
}

.enfoque-audio__podcast-playpause {
  position: static;
  width: 60px;
  height: 60px;
  border-radius: var(--enfoque-radius-pill);
  background: #e6070a;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 10px 28px rgba(230, 7, 10, .35);
  transition: transform var(--enfoque-transition-fast);
}

.enfoque-audio__podcast-playpause:hover {
  transform: var(--enfoque-hover-scale-sm);
}

.enfoque-audio__podcast-playpause svg {
  width: 24px;
  height: 24px;
  fill: #fff;
  margin-left: 2px;
}

.enfoque-audio__podcast-playpause .enfoque-audio__icon-pause {
  margin-left: 0;
}

/* --- Barra de progreso + tiempos --- */

.enfoque-audio__progress-wrap--podcast {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
}

.enfoque-audio__progress-wrap--podcast .enfoque-audio__progress-track {
  flex: 1;
  height: 4px;
  border-radius: var(--enfoque-radius-pill);
  background: #525a63;
}

.enfoque-audio__progress-wrap--podcast .enfoque-audio__progress-fill {
  background: #e6070a;
}

.enfoque-audio__progress-wrap--podcast .enfoque-audio__time-current,
.enfoque-audio__progress-wrap--podcast .enfoque-audio__time-duration {
  font-size: var(--enfoque-text-xs);
  color: #ffffff;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

/* --- Volumen + acciones --- */

.enfoque-audio__podcast-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--enfoque-space-md);
  padding-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, .08);
  flex-wrap: wrap;
}

.enfoque-audio__podcast-volume {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 120px;
}

.enfoque-audio__podcast-volume-btn {
  border: none;
  background: transparent;
  color: #ffffff;
  cursor: pointer;
  display: flex;
  padding: 2px;
}

.enfoque-audio__podcast-volume-btn svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.enfoque-audio__podcast-volume-btn.is-muted {
  color: #e6070a;
}

.enfoque-audio__podcast-volume-range {
  width: 90px;
  accent-color: #e6070a;
  cursor: pointer;
}

.enfoque-audio__podcast-volume-max {
  border: none;
  background: transparent;
  color: #ffffff;
  cursor: pointer;
  display: flex;
  padding: 2px;
  flex-shrink: 0;
}

.enfoque-audio__podcast-volume-max svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.enfoque-audio__podcast-divider {
  width: 1px;
  align-self: stretch;
  background: rgba(255, 255, 255, .12);
  flex-shrink: 0;
}

.enfoque-audio__podcast-actions {
  display: flex;
  align-items: center;
  gap: var(--enfoque-space-md);
}

.enfoque-audio__podcast-action {
  display: flex;
  align-items: center;
  gap: 5px;
  border: none;
  background: transparent;
  color: #ffffff;
  font-size: var(--enfoque-text-xs);
  cursor: pointer;
  padding: 2px;
  text-decoration: none;
  transition: color var(--enfoque-transition-fast);
}

.enfoque-audio__podcast-action:hover {
  color: #e6070a;
}

.enfoque-audio__podcast-action svg {
  width: 16px;
  height: 16px;
}

.enfoque-audio__podcast-share-wrap {
  position: relative;
}

.enfoque-audio__podcast-share-menu {
  /* FIX: display:flex en la clase ganaba sobre el estilo por defecto
     del atributo [hidden] (misma especificidad, esta regla de autor
     va después en la cascada) — por eso el menú aparecía siempre
     abierto sin forma de cerrarlo. Por defecto ahora está oculto; solo
     se muestra cuando el JS quita el atributo hidden. */
  display: none;
  position: absolute;
  bottom: calc(100% + 10px);
  right: 0;
  z-index: 5;
  flex-direction: column;
  min-width: 190px;
  padding: 8px;
  background: #14171a;
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 12px;
  box-shadow: 0 16px 32px rgba(0, 0, 0, .5);
}

.enfoque-audio__podcast-share-menu:not([hidden]) {
  display: flex;
}

.enfoque-audio__podcast-share-item {
  display: flex;
  align-items: center;
  gap: 10px;
  border: none;
  background: transparent;
  color: #ffffff;
  font-size: var(--enfoque-text-sm);
  text-align: left;
  padding: 8px;
  border-radius: 8px;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--enfoque-transition-fast);
}

.enfoque-audio__podcast-share-item:hover,
.enfoque-audio__podcast-share-item:focus-visible {
  background: rgba(255, 255, 255, .08);
}

.enfoque-audio__podcast-share-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .06);
  color: #ffffff;
}

.enfoque-audio__podcast-share-icon svg {
  width: 15px;
  height: 15px;
  fill: currentColor;
}

.enfoque-audio__podcast-share-item[data-network="facebook"] .enfoque-audio__podcast-share-icon { background: #1877f2; }
.enfoque-audio__podcast-share-item[data-network="whatsapp"] .enfoque-audio__podcast-share-icon { background: #25d366; }
.enfoque-audio__podcast-share-item[data-network="twitter"]  .enfoque-audio__podcast-share-icon { background: #000000; }
.enfoque-audio__podcast-share-item[data-network="email"]    .enfoque-audio__podcast-share-icon { background: rgba(255, 255, 255, .14); }
.enfoque-audio__podcast-share-item[data-network="copy"]     .enfoque-audio__podcast-share-icon { background: rgba(255, 255, 255, .14); }

.enfoque-audio__podcast-share-sep {
  display: block;
  height: 1px;
  margin: 6px 4px;
  background: rgba(255, 255, 255, .1);
}

.enfoque-audio__podcast-share.is-copied span::after {
  content: '\2713';
  margin-left: 4px;
}

/* --- Responsive --- */

@media (max-width: 640px) {

  .enfoque-audio__podcast-grid {
    grid-template-columns: 104px 1fr;
    grid-template-areas:
      "media info"
      "player player";
    align-items: start;
    row-gap: 12px;
  }

  /* .podcast-body deja de generar su propia caja (display:contents):
     sus dos hijos (.podcast-info y .podcast-player) pasan a ser ítems
     directos del grid de arriba, ubicables por grid-area. En desktop
     esta regla no existe, así que .podcast-body sigue siendo un flex
     normal — este cambio es exclusivo de mobile. */
  .enfoque-audio__podcast-body {
    display: contents;
  }

  .enfoque-audio__podcast-media {
    grid-area: media;
    width: 100%;
    aspect-ratio: 3 / 4;
    border-radius: 10px;
  }

  .enfoque-audio__podcast-media img {
    border-radius: inherit;
  }

  .enfoque-audio__podcast-info {
    grid-area: info;
    padding: var(--enfoque-space-md) var(--enfoque-space-md) 0 0;
    gap: 6px;
  }

  .enfoque-audio__podcast-player {
    grid-area: player;
    padding: 0 var(--enfoque-space-md) var(--enfoque-space-md);
    gap: 8px;
  }

  .enfoque-audio__podcast-title {
    order: 3;
    flex: 1 1 100%;
    font-size: var(--enfoque-text-md);
    -webkit-line-clamp: 2;
  }

  .enfoque-audio__podcast-subtitle {
    -webkit-line-clamp: 2;
  }

  .enfoque-audio__podcast-bottom {
    justify-content: center;
  }

  .enfoque-audio__podcast-top {
    flex-wrap: wrap;
    align-items: center;
  }

  /* Deja de agrupar visualmente badge+título: sus hijos pasan a ser
     ítems directos de .podcast-top (ver order: en badge/título) —
     así el badge puede compartir fila con duración/velocidad, y el
     título pasa a su propia fila completa debajo. Exclusivo de
     mobile — en escritorio .podcast-headline sigue agrupando ambos
     tal como está, sin cambios. */
  .enfoque-audio__podcast-headline {
    display: contents;
  }

  .enfoque-audio__podcast-badge {
    order: 1;
    padding: 3px 9px;
    font-size: .66rem;
  }

  .enfoque-audio__podcast-badge svg {
    width: 10px;
    height: 10px;
  }

  .enfoque-audio__podcast-top-right {
    order: 2;
    flex-direction: row;
    align-items: center;
    margin-left: auto;
    padding-left: var(--enfoque-space-sm);
  }

  /* Recorte adicional de alto: forma de onda y controles más chicos */
  .enfoque-audio__waveform {
    height: 36px;
    margin: 4px 0 0;
  }

  .enfoque-audio__podcast-controls {
    gap: var(--enfoque-space-sm);
    padding: 0;
  }

  .enfoque-audio__podcast-playpause {
    width: 52px;
    height: 52px;
  }

  .enfoque-audio__podcast-skip,
  .enfoque-audio__podcast-track {
    width: 32px;
    height: 32px;
  }

}

/* v1.9.7 — FIX real: en mobile, badge (order:1) y .podcast-top-right
   (order:2, duración+velocidad) comparten renglón vía flex-wrap SOLO
   si entran juntos en el ancho disponible — igual que en el post
   individual (imagen 2 de referencia del usuario). El popup del HUB
   (.enf-hub-embed-panel: width:92% + padding:16px) le come al
   contenedor entre 40 y 50px más que un post individual a la misma
   pantalla, así que en teléfonos angostos badge+top-right dejan de
   entrar juntos y top-right cae a su propio renglón (empujado por su
   margin-left:auto, que ahora actúa solo, produciendo el corrimiento
   reportado). Causa raíz real: no es un bug de la regla compartida —
   es que en el popup hay menos ancho disponible para el mismo
   contenido. Por decisión explícita del usuario, la corrección es
   achicar badge/duración/velocidad SOLO en este contexto (para que
   vuelvan a entrar en el mismo renglón), sin tocar la regla base de
   arriba (compartida con el post, que sigue intacta) ni nada de
   escritorio. Doble condición en el selector — .enfoque-audio-wrap--hub
   (SOLO existe en el markup del popup, enfoque_render_audio_podcast_
   card_generico(), enfoque-audio.php) + el mismo max-width:640px de
   arriba — así que estructuralmente no puede aplicarse ni a mobile+post
   ni a ningún ancho de escritorio, sea cual sea el contexto. */
@media (max-width: 640px) {

  .enfoque-audio-wrap--hub .enfoque-audio__podcast-badge {
    padding: 2px 7px;
    font-size: .6rem;
    gap: 4px;
  }

  .enfoque-audio-wrap--hub .enfoque-audio__podcast-badge svg {
    width: 9px;
    height: 9px;
  }

  .enfoque-audio-wrap--hub .enfoque-audio__podcast-top-right {
    gap: 4px;
    padding-left: var(--enfoque-space-xs);
  }

  .enfoque-audio-wrap--hub .enfoque-audio__podcast-duration {
    gap: 3px;
    font-size: .6rem;
  }

  .enfoque-audio-wrap--hub .enfoque-audio__podcast-duration svg {
    width: 11px;
    height: 11px;
  }

  .enfoque-audio-wrap--hub .enfoque-audio__podcast-speed {
    padding: 3px 7px;
    font-size: .6rem;
    min-width: calc(4.2ch + 16px);
  }

}