/**
 * RADIO UNaF — COMPONENTES
 * Piezas reutilizables: botones, etiquetas, indicador AL AIRE, ecualizador,
 * tarjetas editoriales y tratamiento de imagen.
 */

/* ==========================================================================
   BOTONES
   Rectos como todo el sitio. El único elemento circular es el PLAY.
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  border: var(--border-hairline) solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  cursor: pointer;
  /* Objetivo táctil cómodo en móvil. */
  min-height: 48px;
  transition:
    background-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    transform var(--duration-fast) var(--ease-out);
}

/* Microinteracción: 1px de hundimiento al presionar. Nada más. */
.btn:active { transform: translateY(1px); }

/*
 * Controles deshabilitados.
 *
 * Mientras no haya transmisión configurada, el JS deshabilita todos los
 * botones de reproducción. Si además no cambian de aspecto, la página muestra
 * un botón rojo intenso que no hace nada al tocarlo: promete algo que no
 * puede cumplir. En gris, el aviso de abajo se entiende solo.
 */
.btn:disabled,
.btn-live:disabled,
.play-btn:disabled,
.dock__play:disabled {
  background: var(--ink-600);
  border-color: var(--ink-600);
  color: var(--gray-400);
  cursor: not-allowed;
}

.btn:disabled:hover,
.btn-live:disabled:hover,
.play-btn:disabled:hover,
.dock__play:disabled:hover {
  background: var(--ink-600);
  border-color: var(--ink-600);
  transform: none;
}

.btn:disabled:active,
.play-btn:disabled:active { transform: none; }

.btn--primary {
  background: var(--red-500);
  color: var(--white);
  border-color: var(--red-500);
}
.btn--primary:hover { background: var(--red-600); border-color: var(--red-600); }

.btn--outline {
  background: transparent;
  color: var(--text);
  border-color: var(--border-strong);
}
.btn--outline:hover { border-color: var(--text); background: var(--text); color: var(--surface); }

.btn--ghost {
  background: transparent;
  color: var(--text);
  border-color: transparent;
  padding-inline: 0;
}
.btn--ghost:hover { color: var(--action); }

.btn--sm { padding: var(--space-3) var(--space-4); min-height: 44px; }

/* Fila de botones. gap y wrap juntos: si no entran en una línea bajan
   completos, nunca escalonados. */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-2);
}

/* Enlace «ver todas» con flecha que avanza al pasar el mouse. */
.link-more {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--text);
  border-bottom: var(--border-hairline) solid var(--border-strong);
  padding-bottom: 2px;
  transition: color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
}
.link-more:hover { color: var(--action); border-color: var(--action); }
.link-more svg { transition: transform var(--duration) var(--ease-out); }
.link-more:hover svg { transform: translateX(4px); }

/* ==========================================================================
   ETIQUETAS
   ========================================================================== */

.tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--action);
}

.tag--solid {
  background: var(--red-500);
  color: var(--white);
  padding: var(--space-1) var(--space-3);
}

.tag--neutral { color: var(--text-subtle); }

/* ==========================================================================
   INDICADOR AL AIRE
   Punto rojo con halo que late. Es el latido del sitio: si la radio está
   transmitiendo, esto se mueve.
   ========================================================================== */

.live-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  background: var(--red-500);
  color: var(--white);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
}

.live-badge--outline {
  background: transparent;
  color: var(--live);
  border: var(--border-hairline) solid currentColor;
}

.live-dot {
  position: relative;
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: currentColor;
}

/* El halo es un pseudoelemento: no agrega nodos ni afecta al layout. */
.live-dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--radius-full);
  background: currentColor;
  animation: live-pulse 2s var(--ease-out) infinite;
}

@keyframes live-pulse {
  0%   { transform: scale(1);   opacity: 0.7; }
  70%  { transform: scale(3.2); opacity: 0; }
  100% { transform: scale(3.2); opacity: 0; }
}

/* Fuera del aire: gris y quieto. */
.live-badge--off {
  background: transparent;
  color: var(--text-subtle);
  border: var(--border-hairline) solid var(--border-strong);
}
.live-badge--off .live-dot::after { animation: none; }

/* ==========================================================================
   ECUALIZADOR
   Barras animadas por CSS puro. Cada barra lleva su propia duración y retardo
   para que el conjunto no lata al unísono, que es lo que delata a un
   ecualizador falso.
   ========================================================================== */

.eq {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 18px;
}

.eq__bar {
  width: 3px;
  height: 100%;
  background: currentColor;
  transform-origin: bottom;
  animation: eq-bounce var(--eq-duration, 900ms) var(--ease-in-out) var(--eq-delay, 0ms) infinite alternate;
}

@keyframes eq-bounce {
  from { transform: scaleY(0.18); }
  to   { transform: scaleY(1); }
}

/* En pausa las barras se congelan, pero cada una a su propia altura de
   reposo (--eq-rest, que fija el PHP barra por barra). Congelarlas todas a la
   misma altura daba una línea punteada que parecía un error de maquetación,
   no una radio detenida. Así se lee como una forma de onda en silencio. */
.is-paused .eq__bar,
.eq--paused .eq__bar {
  animation-play-state: paused;
  transform: scaleY(var(--eq-rest, 0.22));
}

.eq--lg { height: 34px; }
.eq--lg .eq__bar { width: 4px; }

@media (prefers-reduced-motion: reduce) {
  .eq__bar { animation: none; transform: scaleY(0.45); }
}

/* ==========================================================================
   IMAGEN EDITORIAL
   Recorte fijo por relación de aspecto y un zoom contenido al pasar el mouse.
   El velo rojo en multiply es el tratamiento de imagen de la marca.
   ========================================================================== */

.media {
  position: relative;
  overflow: hidden;
  background: var(--surface-sunken);
  isolation: isolate;
}

.media > img,
.media > svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--duration-slow) var(--ease-out);
}

.media--16x9 { aspect-ratio: 16 / 9; }
.media--4x3  { aspect-ratio: 4 / 3; }
.media--1x1  { aspect-ratio: 1 / 1; }
.media--3x4  { aspect-ratio: 3 / 4; }
.media--21x9 { aspect-ratio: 21 / 9; }

/* Velo de marca: se enciende al pasar el mouse sobre la tarjeta. */
.media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--red-600);
  mix-blend-mode: multiply;
  opacity: 0;
  transition: opacity var(--duration) var(--ease-out);
  pointer-events: none;
}

.card:hover .media > img,
.card:focus-within .media > img,
.card:hover .media > svg,
.card:focus-within .media > svg { transform: scale(1.04); }

.card:hover .media::after,
.card:focus-within .media::after { opacity: 0.22; }

/* ==========================================================================
   TARJETA EDITORIAL
   Sin caja, sin sombra, sin borde redondeado: una tarjeta editorial es una
   imagen, un filete y jerarquía tipográfica.
   ========================================================================== */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

.card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  color: var(--text-subtle);
}

/* Separador entre metadatos: un punto medio, no una barra. */
.card__meta > * + *::before {
  content: '·';
  margin-right: var(--space-3);
  color: var(--border-strong);
}

.card__title {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: var(--step-1);
  line-height: var(--leading-snug);
  letter-spacing: -0.015em;
  color: var(--text);
  text-transform: none;
  transition: color var(--duration-fast) var(--ease-out);
}

.card:hover .card__title,
.card:focus-within .card__title { color: var(--action); }

.card__excerpt {
  font-size: var(--step--1);
  line-height: var(--leading-normal);
  color: var(--text-muted);
}

/* El enlace cubre toda la tarjeta pero el nombre accesible sale del título:
   así el lector de pantalla anuncia el título, no «leer más». */
.card__link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* Filete rojo que crece bajo la tarjeta al pasar el mouse. */
.card__rule {
  width: 32px;
  height: var(--border-thick);
  background: var(--action);
  transition: width var(--duration) var(--ease-out);
}
.card:hover .card__rule,
.card:focus-within .card__rule { width: 64px; }
