/* ==================== POMAROLA RADIO — PORTAL ====================
   Cassette: arena, tinta y las cuatro tintas planas de una carátula de los 80
   (naranja, azul, amarillo, verde). Todo va en cajas con borde de 3 px y
   sombras duras — sin degradados, sin bordes redondeados, sin sombras difusas.

   IBM Plex Mono en las tres capas (títulos, datos e interfaz), self-hosted en
   /fonts. Nada de CDN: un @font-face remoto compite con el handshake TLS del
   stream, que es lo único que de verdad apura en este sitio.

   El verde no es el del mockup (#0f8f6b): sobre él, texto chico en crema da
   3.9:1 y no pasa AA. #0c7a5c da 5.1:1 y a simple vista es el mismo verde.
   ============================================================================ */

@font-face {
    font-family: 'Plex Mono';
    src: url('../fonts/plex-mono-400.woff2') format('woff2');
    font-weight: 400;
    font-display: swap;
}
@font-face {
    font-family: 'Plex Mono';
    src: url('../fonts/plex-mono-600.woff2') format('woff2');
    font-weight: 600;
    font-display: swap;
}
@font-face {
    font-family: 'Plex Mono';
    src: url('../fonts/plex-mono-700.woff2') format('woff2');
    font-weight: 700;
    font-display: swap;
}

:root {
    --arena:   #f0e6d6;
    --crema:   #fffaf2;
    --tinta:   #14140f;
    --naranja: #e8611f;
    --azul:    #1b3ac9;
    --amarillo:#ffd84d;
    --verde:   #0c7a5c;

    --mono: 'Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    --borde: 3px solid var(--tinta);
    --hair: 2px solid var(--tinta);
    --ancho: 1280px;
}

*, *::before, *::after { box-sizing: border-box; }

/* Casi todas las secciones nacen con [hidden] y las revela el JS cuando tienen
   datos. Sin esto no sirve de nada: cualquier `display: flex|grid` de más abajo
   le gana al `display:none` que el navegador le da a [hidden] por especificidad,
   y la sección se ve igual — vacía. */
[hidden] { display: none !important; }

body {
    margin: 0;
    background: var(--arena);
    color: var(--tinta);
    font-family: var(--mono);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    -webkit-text-size-adjust: 100%;
}

.hoja {
    max-width: var(--ancho);
    margin: 0 auto;
    background: var(--crema);
    border: var(--borde);
}

h1, h2, h3 { margin: 0; line-height: 1.1; }

/* Título de sección: mayúsculas, apretado. El tamaño lo pone cada zona. */
h2 {
    font-size: 1.85rem; font-weight: 600;
    letter-spacing: -.02em; text-transform: uppercase;
    margin-bottom: .85rem;
}
p { margin: 0 0 .6rem; }
a { color: var(--azul); text-underline-offset: 3px; }
a:hover { color: var(--naranja); }

:focus-visible { outline: 3px solid var(--azul); outline-offset: 2px; }

.skip {
    position: absolute; left: -9999px;
    background: var(--tinta); color: var(--crema);
    padding: .6rem 1rem; z-index: 99;
}
.skip:focus { left: 8px; top: 8px; }

.visualmente-oculto {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Rótulo chico en versalitas: kickers, fechas, etiquetas. */
.kicker, .cab-nav, .cab-clima, .suena-kicker, .hoy-rotulo, .noticia-fecha,
.destacado-kicker, .programa-horario, .libro-estado, .pie,
.cta-kicker, .ficha-rotulo, .compartir {
    letter-spacing: .1em; text-transform: uppercase;
}

/* ---------- cabecera ---------- */

.cabecera { display: flex; align-items: stretch; border-bottom: var(--borde); }

/* Sin padding: el logo trae su propio fondo negro y llega hasta el borde, así
   que el recuadro de la marca ES la imagen. Un padding acá dibujaría un marco
   negro alrededor de un rectángulo negro — invisible, pero corriendo todo. El
   background queda igual como piso mientras la imagen carga. */
.cab-marca {
    background: #000;
    padding: 0;
    display: flex;
    /* flex-start y no el stretch por defecto: una imagen con height:auto SÍ se
       estira en el eje cruzado, así que el día que el menú ocupe más alto que
       el logo (pantalla angosta, un ítem más), el logo saldría deformado. El
       hueco que queda es negro sobre negro, no se ve. */
    align-items: flex-start;
    border-right: var(--borde);
}
/* En las páginas de texto el logo es el enlace de vuelta a la portada. El <a>
   tiene que ser flex y centrar: como el ancho del logo va en `%`, dentro de un
   <a> dimensionado por su contenido la medida se resuelve al revés y el enlace
   se estiraba a todo el ancho dejando el logo pegado a la izquierda. */
.cab-marca > a { display: flex; justify-content: center; min-width: 0; }
/* El ancho manda y el alto sale solo: el logo es apaisado (2,66:1) y fijarle el
   alto lo deja o diminuto o desbordado. */
.cab-logo {
    width: clamp(250px, 26vw, 340px);
    height: auto;
    display: block;
    flex: none;
}

/* Celdas de ancho igual y altura completa, no una fila de links sueltos.
   El alto de la cabecera lo fija el logo (128 px a tamaño máximo) y la versión
   anterior dejaba 30 px de texto centrados ahí con ~100 px muertos a la
   derecha: mucho crema vacío y las etiquetas largas partidas en dos líneas sin
   que nada explicara por qué. Repartidas en `1fr` ocupan todo el ancho, y con
   la celda entera clickeable el hueco vertical pasa a ser área útil.
   `grid-auto-columns: 1fr` y no `minmax(0,1fr)`: acá SÍ conviene que el mínimo
   sea el contenido, porque una etiqueta partida en tres líneas es peor que
   celdas de ancho desparejo. */
.cab-nav {
    flex: 1;
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
    padding: 0;
    font-size: .76rem; font-weight: 700;
}
.cab-nav a {
    display: flex; align-items: center; justify-content: center;
    text-align: center; text-wrap: balance;
    padding: .5rem .7rem;
    color: var(--tinta); text-decoration: none;
    border-right: var(--hair);
}
.cab-nav a:last-child { border-right: none; }
.cab-nav a:hover { background: var(--arena); color: var(--naranja); }
/* Naranja y no tinta: la celda activa es la PRIMERA y queda pegada al bloque
   del logo, que es negro — en tinta las dos se leían como una sola mancha y el
   borde de 3 px entre ellas es negro sobre negro, o sea invisible. El texto va
   en tinta y no en crema porque sobre este naranja la crema da 3.28:1 y no pasa
   AA; la tinta da 5.42:1. */
.cab-nav a.es-actual { background: var(--naranja); color: var(--tinta); }
.cab-nav a.es-actual:hover { background: var(--naranja); color: var(--crema); }

/* La esquina de Santiago: ciudad, temperatura y hora de Chile. La temperatura
   puede venir vacía (si open-meteo no responde) y entonces queda
   "SANTIAGO · 16:32", que se lee igual de bien. El separador cuelga de la hora
   y no de la temperatura justamente por eso. */
.cab-clima {
    background: var(--azul); color: var(--crema);
    padding: 1rem 1.4rem;
    border-left: var(--borde);
    display: flex; align-items: center; gap: .45rem;
    font-size: .8rem; font-weight: 700;
    margin: 0; white-space: nowrap;
}
#clima-temp:not(:empty) { color: var(--amarillo); }
#clima-hora::before { content: '· '; opacity: .55; }

/* ---------- lo que suena ---------- */

.hero { display: grid; grid-template-columns: 1.15fr .85fr; border-bottom: var(--borde); }

/* Grid y no flujo normal para que la carátula ocupe su propia columna al lado
   del título: en flujo quedaba flotando entre el artista y el botón. Sin
   carátula la columna auto colapsa sola y el texto usa todo el ancho. */
.suena {
    background: var(--azul); color: var(--crema);
    padding: 2rem 1.9rem;
    border-right: var(--borde);
    min-width: 0;
    /* Ancla del botón de compartir, que va absoluto en la esquina de abajo. */
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0 1.5rem;
    align-content: start;
}
.suena > * { grid-column: 1; }
.suena-kicker {
    grid-column: 1 / -1;
    font-size: .78rem; font-weight: 700; color: var(--amarillo);
    margin: 0 0 .8rem;
}
/* El nombre del bloque al aire lo agrega la cartelera; sin dato no debe
   quedar el separador colgando. */
#np-bloque:not(:empty)::before { content: ' · '; }

.suena-titulo {
    font-size: clamp(2.1rem, 4.4vw, 3.9rem); font-weight: 600;
    letter-spacing: -.03em; text-transform: uppercase;
    line-height: .98;
    margin: 0 0 .35rem;
    overflow-wrap: anywhere;
}
.suena-artista { font-size: 1.35rem; margin: 0; opacity: .9; overflow-wrap: anywhere; }
/* La carátula ocupa el alto del título, el artista y los controles, que es el
   hueco que ya existía a la derecha. El tope de 176 px no es estético: es lo
   que miden esas tres filas con el título más corto posible (179 px medidos),
   y pasarse de ahí empuja la caja azul hacia abajo — con 240 px la estiraba
   84 px. Ojo con `grid-row: 2 / -1`: sin filas explícitas, -1 apunta a la
   línea 1 del grid explícito y el ítem termina donde no debe. */
.suena-art {
    grid-column: 2; grid-row: 2 / span 3;
    align-self: start;
    width: clamp(130px, 13.5vw, 176px); height: auto; aspect-ratio: 1;
    object-fit: cover;
    border: var(--hair); border-color: var(--crema);
}
/* Su regla queda en la columna del texto: cruzando las dos, la línea pasaba
   por encima de la carátula. */
.suena-sigue { grid-column: 1; }

.suena-controles {
    grid-column: 1;
    display: flex; align-items: center; gap: 1.1rem; margin-top: 1.6rem;
}

.play {
    flex: none;
    display: flex; align-items: center; justify-content: center; gap: .75rem;
    font-family: var(--mono);
    font-size: 1.05rem; font-weight: 700; letter-spacing: .04em;
    color: var(--tinta); background: var(--amarillo);
    border: var(--borde);
    box-shadow: 6px 6px 0 var(--tinta);
    padding: .9rem 1.6rem;
    cursor: pointer;
    transition: transform .08s ease, box-shadow .08s ease;
}
.play:hover { transform: translate(2px, 2px); box-shadow: 4px 4px 0 var(--tinta); }
.play:active { transform: translate(6px, 6px); box-shadow: none; }
.play.sonando { background: var(--naranja); color: var(--crema); }

/* Triángulo de play / dos barras de stop, dibujados en CSS. */
.play-icono {
    width: 0; height: 0; flex: none;
    border-left: 16px solid currentColor;
    border-top: 10px solid transparent;
    border-bottom: 10px solid transparent;
}
.play.sonando .play-icono {
    width: 15px; height: 20px;
    border: none;
    background: currentColor;
    /* dos barras con un corte al medio */
    -webkit-mask: linear-gradient(#000 0 0) left/5px 100% no-repeat,
                  linear-gradient(#000 0 0) right/5px 100% no-repeat;
            mask: linear-gradient(#000 0 0) left/5px 100% no-repeat,
                  linear-gradient(#000 0 0) right/5px 100% no-repeat;
}

/* El ecualizador solo se mueve mientras el audio corre de verdad: la clase la
   pone el reproductor. Animar siempre sería decir que suena algo cuando no. */
.eq { display: flex; align-items: flex-end; gap: 4px; height: 44px; flex: 1; min-width: 0; }
.eq span { flex: 1; background: var(--amarillo); height: 22%; }
.eq span:nth-child(even) { background: var(--crema); }
body.sonando .eq span { animation: eq .9s infinite ease-in-out; }
body.sonando .eq span:nth-child(2) { animation-duration: .75s; animation-delay: .1s; }
body.sonando .eq span:nth-child(3) { animation-duration: 1.1s; animation-delay: .2s; }
body.sonando .eq span:nth-child(4) { animation-duration: .85s; animation-delay: .05s; }
body.sonando .eq span:nth-child(5) { animation-duration: 1s; animation-delay: .15s; }
body.sonando .eq span:nth-child(6) { animation-duration: .8s; animation-delay: .25s; }
@keyframes eq { 0%, 100% { height: 22% } 50% { height: 100% } }

.suena-sigue {
    margin: 1.5rem 0 0; padding-top: 1rem;
    border-top: 2px solid rgba(255, 250, 242, .3);
    font-size: .88rem;
    min-height: 1.2em;
    /* Le deja el rincón al botón de compartir, que está encima en absoluto: sin
       esto, un "Sigue: artista — título" largo le pasa por debajo. */
    padding-right: 9rem;
}
.suena-sigue b { font-weight: 600; }

/* ---------- compartir ---------- */
/* El mismo componente en tres lugares, los tres sobre fondo oscuro con texto
   crema: la esquina del recuadro azul, el pie y la barra del teléfono. */

.compartir-zona { position: relative; }
.compartir {
    display: inline-flex; align-items: center; gap: .5rem;
    font-family: var(--mono); font-size: .72rem;
    color: var(--crema); background: transparent;
    border: var(--hair); border-color: rgba(255, 250, 242, .5);
    padding: .55rem .8rem;
    cursor: pointer;
}
.compartir:hover { background: rgba(255, 250, 242, .15); border-color: var(--crema); }
.compartir[aria-expanded="true"] { background: var(--crema); color: var(--tinta); }

/* Pegado a la esquina inferior derecha del recuadro azul. */
.compartir-esquina { position: absolute; right: 1.9rem; bottom: 1.9rem; }

/* El menú del escritorio (WhatsApp / copiar link). En el teléfono no existe:
   ahí manda navigator.share y abre la hoja del sistema. */
.compartir-menu {
    position: absolute; right: 0; bottom: calc(100% + .4rem);
    z-index: 40;
    display: flex; flex-direction: column;
    min-width: 11rem;
    background: var(--crema);
    border: var(--borde);
    box-shadow: 6px 6px 0 rgba(20, 20, 15, .35);
}
.compartir-opcion {
    font-family: var(--mono); font-size: .8rem; font-weight: 700;
    text-align: left; text-decoration: none;
    color: var(--tinta); background: transparent;
    border: none; border-bottom: var(--hair);
    padding: .7rem .9rem; cursor: pointer;
}
.compartir-opcion:last-child { border-bottom: none; }
.compartir-opcion:hover { background: var(--amarillo); }

/* ---------- programas destacados ---------- */

.destacados { display: grid; grid-template-rows: 1fr 1fr; min-width: 0; }
.destacados > .destacado { padding: 1.35rem 1.6rem; min-width: 0; }
/* Acotados a > .destacado a propósito: en la lista de Programas hay artículos
   con la clase `destacado` y sin este alcance el primero de esa lista se
   pintaba de amarillo por ser :first-child de otra caja. */
.destacados > .destacado:first-child { background: var(--amarillo); border-bottom: var(--borde); }
.destacados > .destacado:last-child { background: var(--verde); color: var(--crema); }
.destacados > .destacado:only-child { border-bottom: none; }

/* El afiche a la derecha del texto. Va en una columna `auto` y con el ancho
   acotado por vw: si creciera libremente empujaría el alto de su fila y con eso
   el hero entero (mismo problema que la carátula de `.suena`, documentado
   arriba). `align-self: start` lo pega al borde de arriba en vez de estirarlo. */
.destacados > .destacado {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: 1.1rem; align-items: start;
}
/* Columna explícita y no por orden de aparición: el afiche va PRIMERO en el DOM
   (lo necesita el float del teléfono, ver abajo) y sin esto la colocación
   automática lo mandaría a la columna 1, con el texto a la derecha. */
.destacado-texto { grid-column: 1; grid-row: 1; min-width: 0; }
/* Marco blanco tipo polaroid. Va de `border` y no de `padding` porque el afiche
   es opaco y llega a su propio borde: un padding pintaría el amarillo o el verde
   de la caja alrededor, no blanco. */
.destacado-arte {
    grid-column: 2; grid-row: 1;
    width: clamp(74px, 8.5vw, 116px); height: auto; aspect-ratio: 1;
    display: block; align-self: start;
    border: 4px solid var(--crema);
}
.destacado-kicker { font-size: .74rem; font-weight: 700; margin: 0 0 .55rem; }
.destacado h3 {
    font-size: clamp(1.5rem, 2.4vw, 2.3rem); font-weight: 600;
    letter-spacing: -.02em; text-transform: uppercase;
    margin: 0 0 .45rem;
}
.destacado p { font-size: .92rem; margin: 0; }
.destacado-pendiente { opacity: .75; }
/* El capítulo al aire del programa de la noche. Va sobre la descripción porque
   es el dato que cambia: la descripción es la misma todas las semanas. */
.destacado-capitulo, .programa-capitulo {
    font-weight: 700; margin: 0 0 .4rem;
}
.destacado-capitulo { font-size: .86rem; }

/* ---------- aviso de tapa ---------- */

.promo {
    background: var(--amarillo);
    border-bottom: var(--borde);
    padding: 1.1rem 1.6rem;
    display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem 1rem;
}
.promo h3 { font-size: 1.3rem; font-weight: 600; text-transform: uppercase; letter-spacing: -.01em; }
.promo p { font-size: .92rem; margin: 0; }
.promo a { color: var(--tinta); font-weight: 700; }
.promo-img { max-width: 100%; height: auto; display: block; border: var(--hair); }

/* ---------- el día de hoy ---------- */

.hoy { display: flex; border-bottom: var(--borde); }
.hoy-rotulo {
    background: var(--tinta); color: var(--crema);
    padding: 1rem 1.3rem;
    font-size: .78rem; font-weight: 700;
    display: flex; align-items: center; white-space: nowrap;
    margin: 0;
}
/* En escritorio el atajo sobra: el menú de arriba ya tiene "La cartelera" y
   además le robaría ancho a la franja, que va justo. */
.hoy-ver { display: none; }
/* Con muchos bloques los mínimos de abajo pueden pasarse del ancho: que se
   desplace la franja antes que desbordar la página entera de lado. */
.hoy-pista { flex: 1; display: flex; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.hoy-pista::-webkit-scrollbar { display: none; }

/* Cada bloque ocupa el ancho de su duración: la franja es el día a escala. */
/* El ancho es proporcional a la duración, pero con un piso: un bloque de una
   hora al lado del nocturno de ocho quedaba en tres letras y un puntito. */
.hoy-bloque {
    flex: var(--peso, 1) 1 0;
    /* 7.8rem y no más: el piso de los bloques cortos le quita ancho al largo, y
       con 8.4rem el nocturno ("Música para estudiar, relajarse o dormir") no
       entraba ni en tres líneas. Bajar el piso lo deja completo Y la franja
       queda más baja, porque el nombre largo necesita menos líneas. */
    min-width: 7.8rem;
    display: block; text-align: left;
    font-family: var(--mono); font-size: .92rem;
    color: var(--tinta); background: transparent;
    border: none; border-right: var(--hair);
    padding: .8rem .75rem;
    cursor: pointer;
}
.hoy-bloque:last-child { border-right: none; }
.hoy-bloque:hover { background: var(--arena); }
.hoy-hora { display: block; font-size: .72rem; font-weight: 700; opacity: .55; }
/* Dos líneas y no puntos suspensivos: desde que los bloques tienen nombres
   largos ("Música para estudiar, relajarse o dormir"), con ellipsis el de la
   noche se leía "Música para es…" y no decía nada. */
.hoy-nombre {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
    font-size: .8rem; font-weight: 700; line-height: 1.2;
    overflow: hidden;
}
.hoy-bloque.es-programa { background: var(--amarillo); }
.hoy-bloque.es-programa:hover { background: #ffe391; }
.hoy-bloque.al-aire { background: var(--naranja); color: var(--crema); }
.hoy-bloque.al-aire:hover { background: var(--naranja); }
.hoy-bloque.al-aire .hoy-hora { opacity: 1; }

/* ---------- portada ---------- */

.portada {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
}
.col-principal { padding: 1.8rem 1.9rem; border-right: var(--borde); min-width: 0; }
.col-lateral { padding: 1.8rem 1.5rem; min-width: 0; }
.col-principal > section { margin-bottom: 2rem; }
.col-principal > section:last-child { margin-bottom: 0; }
.col-lateral > section, .col-lateral > div > * { margin-bottom: 1.8rem; }
.col-lateral h2 { font-size: 1.45rem; }

.pie-nota { font-size: .74rem; opacity: .6; margin: .55rem 0 0; }

/* ---------- la vitrina de programas ----------
   Ocupa el lugar donde estuvo la sección Lecturas, retirada el 09-ago-2026 —
   su contenido sigue en contenido/lecturas.json por si vuelve.
   El afiche es cuadrado (todos los originales vienen 1254×1254), así que va con
   aspect-ratio y no con un alto fijo: un `height` recortaría los que no lo sean. */
.vitrina {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1.4rem;
}
.vitrina-item {
    border: var(--borde);
    background: var(--crema);
    display: flex; flex-direction: column;
}
.vitrina-arte {
    width: 100%; height: auto; aspect-ratio: 1;
    object-fit: cover; display: block;
    border-bottom: var(--borde);
    background: var(--arena);
}
.vitrina-ficha { padding: 1rem; }
.vitrina-kicker {
    display: inline-block;
    background: var(--verde); color: var(--crema);
    font-size: .66rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    padding: .25rem .55rem; margin-bottom: .6rem;
}
.vitrina-item h3 {
    font-size: 1.2rem; font-weight: 600;
    letter-spacing: -.01em; text-transform: uppercase;
    line-height: 1.12; margin-bottom: .45rem;
}
.vitrina-ficha p:last-child { font-size: .85rem; margin: 0; opacity: .75; }
.vitrina-pendiente { opacity: .5 !important; }

/* ---------- noticias ---------- */

.noticias-lista { border-top: var(--hair); }
.noticia {
    display: grid; grid-template-columns: 5.2rem minmax(0, 1fr);
    gap: 0 1.1rem;
    padding: .95rem 0;
    border-bottom: var(--hair);
}
.noticia-fecha { font-size: .74rem; font-weight: 700; color: var(--naranja); }
.noticia h3 { font-size: 1.18rem; font-weight: 600; text-transform: uppercase; margin-bottom: .2rem; }
.noticia h3 a { color: inherit; text-decoration: none; }
.noticia h3 a:hover { color: var(--naranja); text-decoration: underline; }
.noticia p { font-size: .88rem; opacity: .75; margin: 0 0 .4rem; max-width: 62ch; }
.noticia p:last-child { margin-bottom: 0; }
.noticia-cuerpo { grid-column: 2; }

/* ---------- programas ---------- */

/* Dos grids anidados, y no uno con la imagen ocupando varias filas: la ficha
   tiene un número variable de párrafos (capítulo, muestra y podcast son
   opcionales), así que un `grid-row: 1 / span N` acertaría solo a veces — y
   `1 / -1` es la trampa ya conocida: sin `grid-template-rows` explícito, el -1
   apunta a la primera línea. Afuera reparte imagen | cuerpo; adentro el cuerpo
   hace lo que hacía antes. */
.programa {
    display: grid; grid-template-columns: 7rem minmax(0, 1fr);
    gap: 1.1rem; align-items: start;
    padding: .85rem 0;
    border-bottom: var(--hair);
}
.programa:first-child { border-top: var(--hair); }
/* Sin borde: los tomatitos son PNG/WebP con alfa y van recortados contra la
   crema, no enmarcados. Un borde alrededor de una imagen transparente dibuja
   una caja vacía con un dibujo flotando adentro. */
.programa-imagen {
    width: 100%; height: auto; aspect-ratio: 1;
    display: block;
}
/* `grid-column: 2` explícito y no por orden: en las fichas sin tomatito el
   cuerpo es el primer hijo y se metía en la columna de 112 px — el título
   quedaba de ancho 0 y la ficha entera se leía como una tira vertical. La
   columna se reserva igual sin imagen para que la lista quede a la misma
   sangría; un borde izquierdo dentado se lee como layout roto. */
.programa-cuerpo {
    grid-column: 2;
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: .2rem 1rem; align-items: baseline; min-width: 0;
}
.programa-cuerpo h3 { font-size: 1.12rem; font-weight: 600; text-transform: uppercase; }
.programa.destacado h3 { color: var(--naranja); }
.programa-horario { font-size: .72rem; font-weight: 700; opacity: .6; text-align: right; margin: 0; }
.programa-cuerpo > p:not(.programa-horario) {
    grid-column: 1 / -1; font-size: .88rem; opacity: .75; margin: 0; max-width: 62ch;
}
.programa-pendiente { opacity: .5; }

/* Estas dos van con el selector completo `.programa-cuerpo > p.x` y no con la
   clase sola: la regla de arriba pinta `> p:not(...)` y le ganaría por
   especificidad, así que la opacidad de acá no se aplicaría. */
.programa-cuerpo > p.programa-capitulo { font-size: .82rem; opacity: 1; color: var(--naranja); }

/* Las canciones de ejemplo, en letra chica bajo la descripción. Salen de las
   playlists reales (contenido/muestras.json), así que dicen la verdad sobre lo
   que suena en ese bloque. */
.programa-cuerpo > p.programa-muestra {
    font-size: .76rem; margin-top: .45rem;
    opacity: .55; font-style: italic;
}

/* ---------- el podcast en Spotify ----------
   Va oscura y no en arena a propósito: es lo único de la página que sale del
   sitio, y la carátula del programa ya es oscura. La sombra verde le hace el
   guiño a Spotify sin traerse su verde (#1DB954 no está en esta paleta y se
   nota de inmediato). Es hija directa de `.programa`, que es un grid de dos
   columnas: sin `grid-column` se metería en la primera. */
.podcast {
    grid-column: 1 / -1;
    display: grid; grid-template-columns: 104px minmax(0, 1fr);
    gap: 1rem; align-items: center;
    margin-top: 1rem;
    /* Al ras de la descripción de arriba, que va capada en 62ch (medido: 524 px).
       Sin esto la tarjeta se estira a los 870 px de la columna y sobresale del
       bloque de texto al que pertenece. */
    max-width: 33rem;
    padding: .85rem;
    background: var(--tinta); color: var(--crema);
    border: var(--borde);
    box-shadow: 6px 6px 0 var(--verde);
}
.podcast-arte { width: 100%; height: auto; display: block; border: var(--hair); }
.podcast-ficha { min-width: 0; }
.podcast-kicker {
    font-size: .64rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--amarillo); margin: 0 0 .35rem;
}
.podcast-episodio { font-size: .95rem; font-weight: 600; line-height: 1.25; margin: 0 0 .75rem; }
.podcast-play {
    display: inline-flex; align-items: center; gap: .55rem;
    font-family: var(--mono);
    font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--tinta); background: var(--amarillo);
    border: var(--hair);
    padding: .55rem .9rem;
    cursor: pointer;
    transition: background .08s ease;
}
.podcast-play:hover { background: var(--crema); }
.podcast-icono {
    width: 0; height: 0; flex: none;
    border-left: 11px solid currentColor;
    border-top: 7px solid transparent;
    border-bottom: 7px solid transparent;
}
.podcast-aviso { font-size: .68rem; opacity: .6; margin: .55rem 0 0; }
/* El `a` global es azul y sobre esta caja casi negra no se lee. */
.podcast-abrir {
    display: inline-block; margin-top: .5rem;
    font-size: .72rem; letter-spacing: .04em;
    color: var(--crema);
}
.podcast-abrir:hover { color: var(--amarillo); }
/* Con el reproductor cargado la caja pasa a una sola columna: el iframe trae su
   propia carátula y repetirla al lado sobraría. */
.podcast-sonando { grid-template-columns: minmax(0, 1fr); }
.podcast-marco { border: 0; width: 100%; display: block; }

/* En la columna lateral (≈300 px) la tarjeta se apila: con la carátula al lado
   quedaban tres palabras por línea. El `max-width` de la versión ancha tampoco
   aplica acá — lo manda la columna. */
.podcast-zona .podcast {
    grid-template-columns: minmax(0, 1fr);
    max-width: none;
    margin-top: 0;
}
/* Centrada: con `max-width` sola quedaba pegada a la izquierda de una columna
   bastante más ancha que ella. */
.podcast-zona .podcast-arte { max-width: 150px; margin-inline: auto; }

@media (max-width: 560px) {
    .podcast { grid-template-columns: 1fr; justify-items: start; }
    .podcast-arte { max-width: 140px; }
}

/* ---------- lateral ---------- */

.top-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.top-lista li {
    display: grid; grid-template-columns: 1.7rem minmax(0, 1fr);
    align-items: center; gap: .7rem;
    background: var(--arena);
    padding: .55rem .7rem;
    font-size: .84rem; line-height: 1.3;
}
.top-lista li:first-child { background: var(--naranja); color: var(--crema); }
.top-lista li::before {
    content: counter(rank); counter-increment: rank;
    font-size: 1.25rem; font-weight: 700;
}
.top-lista { counter-reset: rank; }
.top-titulo { font-weight: 700; }
.top-artista::before { content: ' · '; }

.recientes { list-style: none; margin: 0; padding: 0; font-size: .82rem; }
.recientes li { padding: .4rem 0; border-bottom: var(--hair); }
.recientes li:last-child { border-bottom: none; }
.recientes time { font-weight: 700; opacity: .55; margin-right: .45rem; }

.promo-lateral {
    background: var(--verde); color: var(--crema);
    border: var(--borde);
    padding: 1.1rem;
}
.promo-lateral h3 {
    font-size: 1.4rem; font-weight: 600; line-height: 1.05;
    text-transform: uppercase; margin-bottom: .5rem;
}
.promo-lateral p { font-size: .88rem; margin: 0; }
.promo-lateral a { color: var(--amarillo); font-weight: 700; }

/* ---------- de dónde salió la radio ---------- */
/* El azul se usa una sola vez más en la página (el recuadro de lo que suena),
   así que acá abajo tira la vista sin competir con nada de al lado. */
.cta-app {
    background: var(--azul); color: var(--crema);
    border: var(--borde);
    box-shadow: 7px 7px 0 var(--tinta);
    padding: 1.2rem;
}
.cta-kicker { font-size: .66rem; font-weight: 700; color: var(--amarillo); margin: 0 0 .5rem; }
.cta-app h2 {
    font-size: 1.9rem; font-weight: 600; line-height: 1;
    letter-spacing: -.02em; text-transform: uppercase;
    margin: 0 0 .5rem;
}
.cta-app p { font-size: .86rem; margin: 0; }
.cta-boton {
    display: inline-block; margin-top: .9rem;
    font-size: .78rem; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--tinta); background: var(--amarillo);
    border: var(--hair); text-decoration: none;
    padding: .55rem .9rem;
}
.cta-boton:hover { background: var(--crema); }

/* ---------- libro de visitas ---------- */

.libro-intro { font-size: .88rem; opacity: .75; }
#libro-form { margin-bottom: 1.4rem; }
#libro-form label {
    display: block;
    font-size: .68rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    opacity: .6; margin-bottom: .25rem;
}
#libro-form input[type="text"], #libro-form textarea {
    width: 100%;
    font-family: var(--mono); font-size: .9rem; color: var(--tinta);
    background: var(--crema);
    border: var(--borde);
    padding: .6rem;
    margin-bottom: .8rem;
}
#libro-form input:focus, #libro-form textarea:focus { border-color: var(--azul); }
#libro-form textarea { resize: vertical; min-height: 4.5rem; }

.boton {
    width: 100%;
    font-family: var(--mono); font-size: .85rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--crema); background: var(--azul);
    border: var(--borde);
    box-shadow: 5px 5px 0 var(--tinta);
    padding: .75rem 1rem; cursor: pointer;
    transition: transform .08s ease, box-shadow .08s ease;
}
.boton:hover { transform: translate(2px, 2px); box-shadow: 3px 3px 0 var(--tinta); }
.boton:disabled { opacity: .55; cursor: default; transform: none; box-shadow: 5px 5px 0 var(--tinta); }

.libro-estado { font-size: .74rem; font-weight: 700; margin: .6rem 0 0; min-height: 1.2em; }
.libro-legal { font-size: .74rem; margin: .5rem 0 0; opacity: .75; }
.libro-estado.ok { color: var(--verde); }
.libro-estado.error { color: var(--naranja); }

.mensaje {
    margin: 0 0 .9rem; padding: .8rem .9rem;
    background: var(--arena);
    border-left: 6px solid var(--amarillo);
}
.mensaje p { font-size: .86rem; margin: 0 0 .35rem; }
.mensaje cite {
    font-size: .68rem; font-style: normal; font-weight: 700;
    letter-spacing: .09em; text-transform: uppercase;
    color: var(--naranja);
}
.mensaje cite::before { content: '— '; }

/* ---------- cartelera ---------- */

.cartelera-zona { background: var(--arena); border-bottom: var(--borde); padding: 1.9rem; }
.cartelera-bajada { font-size: .95rem; opacity: .75; margin-bottom: 1.3rem; max-width: 52ch; }

/* Columna de horas + 7 días. Cada pista es una grilla de 48 medias horas y
   cada bloque se posiciona con --fila y --span, calculados en cartelera.js. */
.cg-grid {
    display: grid;
    grid-template-columns: 3.6rem repeat(7, minmax(0, 1fr));
    gap: .3rem;
    align-items: start;
}
/* La barra de días es solo del teléfono; en escritorio caben los siete. */
.cg-dias { display: none; }
.cg-horas, .cg-pista { display: grid; grid-template-rows: repeat(var(--filas, 48), 17px); }
.cg-horas { margin-top: 1.9rem; }
.cg-hora {
    grid-row: calc(var(--fila) + 1);
    font-size: .66rem; font-weight: 700; opacity: .5;
    transform: translateY(-.35em);
}
.cg-titulo-dia {
    font-size: .7rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    text-align: center; margin: 0 0 .45rem; padding: .2rem 0 .3rem;
    border-bottom: var(--hair);
}
/* Solo color: si el día de hoy cambiara su padding, su columna entera bajaría
   dos píxeles respecto a las otras seis y la semana quedaría torcida. */
.cg-dia.es-hoy .cg-titulo-dia { background: var(--tinta); color: var(--crema); }
.cg-pista { position: relative; }

.cg-bloque {
    grid-row: calc(var(--fila) + 1) / span var(--span);
    display: flex; flex-direction: column; justify-content: flex-start; gap: 1px;
    overflow: hidden; text-align: left;
    font-family: var(--mono); font-size: .72rem; line-height: 1.2;
    color: var(--tinta);
    background: var(--crema);
    border: var(--hair);
    padding: .3rem .4rem;
    margin-bottom: 2px;
    cursor: pointer;
}
.cg-bloque:hover { border-color: var(--naranja); }
.cg-bloque.corto { justify-content: center; padding-block: .1rem; }
.cg-bloque.corto .cg-hora-bloque { display: none; }
.cg-nombre { font-weight: 700; }
.cg-hora-bloque { font-size: .64rem; opacity: .6; }

/* Cada bloque con su color, para leer la semana de un vistazo. Los tonos son
   los de la paleta rebajados; los programas van a tinta plena.
   Los tres bloques que salen de la playlist Movida comparten color a propósito:
   se llaman distinto porque son horas distintas del día, pero la música que
   sale del sorteo es la misma y el color no debería decir lo contrario. */
.cg-bloque[data-programa="shot-energetico"],
.cg-bloque[data-programa="no-hay-siesta"],
.cg-bloque[data-programa="ultimo-shot"]        { background: #fbe0c4; }
.cg-bloque[data-programa="trabaja-con-onda"]   { background: #ffeeb8; }
.cg-bloque[data-programa="rock-todas-sus-formas"] { background: #c9e3d5; }
.cg-bloque[data-programa="bajando-la-velocidad"]  { background: #cdd6f5; }
.cg-bloque[data-programa="para-estudiar"]      { background: var(--tinta); color: var(--crema); }
.cg-bloque[data-programa="para-estudiar"] .cg-hora-bloque { opacity: .7; }
.cg-bloque[data-programa="rigor-mortis"]       { background: var(--amarillo); }
.cg-bloque[data-programa="variante-mortiz"]    { background: var(--verde); color: var(--crema); }

.cg-bloque.al-aire { outline: 3px solid var(--naranja); outline-offset: 1px; box-shadow: 3px 3px 0 var(--naranja); }
.cg-al-aire { margin-top: auto; font-size: .58rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--naranja); }
.cg-bloque[data-programa="para-estudiar"] .cg-al-aire { color: var(--amarillo); }

/* La línea de la hora actual, sobre la columna de hoy. */
.cg-ahora {
    position: absolute; left: -3px; right: -3px; top: var(--pos);
    height: 3px; background: var(--naranja);
    pointer-events: none; z-index: 3;
}
.cg-ahora::before {
    content: ''; position: absolute; left: -5px; top: -3px;
    width: 9px; height: 9px; border-radius: 50%; background: var(--naranja);
}

/* Ficha de un bloque */
/* El alto lo decide el contenido —doce artistas en chips envueltos son muchas
   filas en un teléfono— y un <dialog> centrado que se pasa del viewport queda
   cortado ARRIBA y abajo a la vez, sin nada que scrollear. Medido a 375×812:
   la ficha más alta llegaba a 742 px, el 91% de la pantalla, y en un teléfono
   corto (667 px) se salía. El tope deja siempre un margen de página visible,
   que es lo que hace que se lea como tarjeta encima y no como pantalla nueva. */
.ficha {
    border: var(--borde); background: var(--crema); color: var(--tinta);
    padding: 0; max-width: 30rem; width: calc(100% - 2rem);
    max-height: calc(100vh - 4rem);
    max-height: calc(100dvh - 4rem);
    overflow: auto;
    box-shadow: 10px 10px 0 rgba(20, 20, 15, .25);
}
.ficha::backdrop { background: rgba(20, 20, 15, .6); }
.ficha-caja { padding: 1.5rem; }
/* Nombre y horario a la izquierda, tomatito a la derecha. La clase con arte se
   agrega desde el JS: sin ella la cabecera es una columna sola y no queda un
   hueco reservado para una imagen que no existe (no todas las fichas tienen). */
.ficha-cabeza { margin-bottom: .7rem; }
.ficha-cabeza-con-arte {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: 1rem; align-items: start;
}
.ficha-arte { width: 84px; height: auto; aspect-ratio: 1; display: block; }
.ficha-caja h3 { font-size: 1.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: -.02em; margin-bottom: .3rem; }
.ficha-caja .programa-horario { text-align: left; margin-bottom: .7rem; }
.ficha-caja .programa-capitulo { color: var(--naranja); font-size: .86rem; }
.ficha-caja .programa-muestra { font-size: .8rem; opacity: .6; font-style: italic; margin-top: .6rem; }
.ficha-rotulo { font-size: .66rem; font-weight: 700; opacity: .55; margin: 1.1rem 0 .5rem; }
/* Los artistas que de verdad viven en esa playlist, sacados del servidor. */
.ficha-artistas {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-wrap: wrap; gap: 4px;
}
.ficha-artistas li {
    font-size: .76rem; font-weight: 700;
    background: var(--arena); border: var(--hair);
    padding: .2rem .45rem;
}
.ficha-cerrar {
    margin-top: 1rem;
    font-family: var(--mono); font-size: .78rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    background: var(--tinta); color: var(--crema);
    border: none; padding: .6rem 1.1rem; cursor: pointer;
}
.ficha-cerrar:hover { background: var(--naranja); }

/* ---------- páginas de texto (privacidad) ---------- */
/* Reusan la cabecera y el pie del portal; lo único propio es la columna de
   lectura. El ancho va en `ch` y no en px porque lo que se está acotando es la
   línea de texto: 66 caracteres es el largo donde el ojo no se pierde al volver
   al margen, y con mono eso son ~640 px que cambian solos si cambia la fuente. */
.legal {
    max-width: 66ch;
    margin-inline: auto;
    padding: 2.4rem 1.9rem 3rem;
    font-size: .95rem; line-height: 1.65;
}
.legal h1 {
    font-size: clamp(2.2rem, 5vw, 3rem); font-weight: 600;
    letter-spacing: -.03em; text-transform: uppercase;
    margin-bottom: .4rem;
}
.legal h2 {
    font-size: 1.1rem; letter-spacing: .02em;
    margin: 2.1rem 0 .6rem;
    padding-bottom: .3rem; border-bottom: var(--hair);
}
.legal-fecha {
    font-size: .7rem; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--naranja);
    margin-bottom: 1.4rem;
}
.legal-bajada { font-size: 1.05rem; margin-bottom: 1.2rem; }
/* Lo que el lector tiene que ver aunque venga escaneando: el aviso de que no hay
   banner todavía y la nota de idioma. Barra al costado, sin color de alarma. */
.legal-nota {
    background: var(--arena);
    border-left: 6px solid var(--amarillo);
    padding: .8rem .9rem;
    font-size: .88rem;
    margin: 1.2rem 0;
}
.legal-lista { margin: 0 0 .6rem; padding-left: 1.2rem; }
.legal-lista li { margin-bottom: .35rem; }
.legal code {
    font-family: var(--mono); font-size: .85em;
    background: var(--arena); border: var(--hair);
    padding: .05em .3em;
}
.legal-volver {
    margin-top: 2.4rem; padding-top: 1.2rem;
    border-top: var(--borde);
    font-weight: 700;
}

/* ---------- pie ---------- */

.pie {
    background: var(--tinta); color: var(--crema);
    padding: 1.4rem 1.9rem;
    display: flex; justify-content: space-between; align-items: center;
    gap: 1rem; flex-wrap: wrap;
    font-size: .78rem; font-weight: 600;
}
.pie p { margin: 0; }
.pie a { color: var(--amarillo); }
/* El menú del pie se abre hacia arriba igual que el del hero, y ahí no hay
   nada tapándolo: es el último elemento de la página. */
.pie .compartir { font-size: .74rem; }

/* ---------- barra del teléfono ---------- */
/* En escritorio no existe: el hero con el play está siempre a un scroll. */

.barra { display: none; }

/* ---------- responsive ---------- */

@media (max-width: 1000px) {
    body { font-size: 15px; }
    .hoja { border-left: none; border-right: none; }

    /* La cabecera se apila: marca a lo ancho, nav con scroll propio. */
    .cabecera { flex-wrap: wrap; }
    .cab-marca {
        width: 100%; border-right: none; border-bottom: var(--borde);
        justify-content: center;
    }
    /* A todo el ancho el logo medía 141 px de alto: el 17% de la pantalla
       gastado en la marca antes de que empiece nada. Acotado y centrado ocupa
       87 px y sigue siendo la primera cosa que se ve. La banda que queda a los
       lados no se nota porque el fondo del logo es negro (medido: 0,0,0 al
       centro, 8,8,8 en el borde) y `.cab-marca` también. */
    .cab-logo { width: min(62%, 240px); }
    .cab-clima {
        order: 2; width: 100%; border-left: none; border-top: var(--borde);
        justify-content: center; padding: .6rem;
    }
    /* En el teléfono la esquina se queda solo con la hora. La hora sí hace
       falta —toda la parrilla se anuncia en hora de Chile— y la temperatura es
       el único dato del sitio que sale a pedirle algo a un tercero. clima.js
       mira si esto está pintado antes de consultar, así que acá no se esconde
       un dato: no se descarga. */
    #clima-temp { display: none; }
    /* Fuera el menú en el teléfono. Es una sola página: de los seis destinos,
       cuatro están a un scroll corto y el propio menú se comía una fila entera
       para esconder la mitad de sus ítems detrás de un desplazamiento lateral
       que nadie descubre. Los dos que sí quedaban lejos se resuelven distinto:
       la cartelera con el atajo de la franja del día, y el resto bajando. */
    .cab-nav { display: none; }
    .hoy-ver {
        display: inline; margin-left: auto; padding-left: .9rem;
        color: var(--amarillo); font-weight: 700;
        white-space: normal; text-align: right;
    }

    .hero { grid-template-columns: minmax(0, 1fr); }
    .suena { border-right: none; border-bottom: var(--borde); padding: 1.6rem 1.2rem; }
    /* En 375 px la carátula compite con el título por el ancho: acá manda el
       título, que es lo que se vino a leer. */
    .suena-art { width: 112px; height: auto; grid-row: 2 / span 2; }
    /* En el teléfono el botón de compartir vuelve al flujo: absoluto en la
       esquina obligaba a reservarle 9rem al "Sigue:", que en 375 px es casi la
       mitad del ancho. */
    .compartir-esquina { position: static; margin-top: 1.1rem; }
    .suena-sigue { padding-right: 0; }
    .destacado:last-child { border-top: var(--borde); }
    .destacados { grid-template-rows: none; }

    /* El afiche flota y el texto lo rodea, en vez de partir la caja en dos
       columnas fijas. En dos columnas el afiche solo puede crecer robándole
       ancho al texto, y el texto es lo que fija el alto de la caja: medido a
       375 px, pasarlo de 74 a 90 px ya estiraba la caja de 285 a 354. Flotando,
       la descripción recupera el ancho completo apenas pasa el afiche, así que
       a 116 px las dos cajas suman exactamente el mismo alto que antes (616 px)
       con el afiche 57% más grande. Más de 116 px y vuelven a crecer. */
    .destacados > .destacado { display: block; }
    .destacado-arte {
        float: right; width: 116px;
        margin: .15rem 0 .7rem .9rem;
    }

    /* El día de hoy pasa de franja a lista: ocho bloques en una fila de 375px
       dejan cada nombre en tres letras. */
    .hoy { flex-direction: column; }
    .hoy-rotulo { justify-content: space-between; }
    .hoy-pista { flex-direction: column; }
    .hoy-bloque {
        display: flex; align-items: center; gap: .9rem;
        border-right: none; border-bottom: var(--hair);
        padding: .7rem 1.2rem;
    }
    .hoy-bloque:last-child { border-bottom: none; }
    /* min-width y no width: la hora del bloque al aire dice "09:00 · AHORA" y
       con ancho fijo se cortaba justo en el AHORA. */
    .hoy-hora { min-width: 3.4rem; flex: none; }

    /* El horario se va abajo del nombre: en dos columnas, uno largo como
       "Desde que termina el programa hasta las 06:30" se comía el ancho
       entero y el nombre del bloque quedaba partido debajo del horario.
       OJO: esto va en el CUERPO, no en `.programa`. Aplicado a la caja de
       afuera aplastaba la columna del tomatito a 4 px — fijo o no, un track de
       7rem cede cuando el contenido de al lado no entra. */
    .programa-cuerpo { grid-template-columns: minmax(0, 1fr); }
    .programa { grid-template-columns: 4.5rem minmax(0, 1fr); gap: .9rem; }
    .programa-horario { text-align: left; }

    .portada { grid-template-columns: minmax(0, 1fr); }
    .col-principal { border-right: none; border-bottom: var(--borde); padding: 1.4rem 1.2rem; }
    .col-lateral { padding: 1.4rem 1.2rem; }

    /* La ficha en el teléfono. Medido a 375×812: llegaba a 742 px, el 91% de la
       pantalla, y 281 de esos —el 38%— eran los doce artistas en chips, que a
       este ancho se envuelven en nueve filas. Pasados a texto corrido con
       puntos medios dicen exactamente lo mismo en cuatro líneas y la ficha baja
       a dos tercios de pantalla, que es lo que la hace leerse como tarjeta y no
       como pantalla nueva. Los chips se quedan en escritorio, donde sobra
       ancho. */
    .ficha-caja { padding: 1.2rem; }
    .ficha-caja h3 { font-size: 1.45rem; }
    .ficha-artistas { display: block; font-size: .8rem; line-height: 1.5; }
    .ficha-artistas li {
        display: inline; font-size: inherit;
        background: none; border: none; padding: 0;
    }
    .ficha-artistas li:not(:last-child)::after {
        content: ' · '; font-weight: 400; opacity: .45;
    }

    .cartelera-zona { padding: 1.4rem 1.2rem; }
    /* La semana entera no cabe en un teléfono. Antes se desplazaba de lado
       dentro de su caja: la página no scrolleaba, pero cuatro de los siete días
       quedaban detrás de un gesto invisible. Ahora se elige el día en la barra
       y se ve completo, con la misma escala de tiempo. Arranca en hoy. */
    .cg-dias {
        display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
        border: var(--borde); margin-bottom: 1rem;
    }
    .cg-dia-tab {
        font-family: var(--mono); font-size: .72rem; font-weight: 700;
        letter-spacing: .04em; text-transform: uppercase;
        color: var(--tinta); background: var(--crema);
        border: none; border-right: var(--hair);
        padding: .6rem .1rem; cursor: pointer;
    }
    .cg-dia-tab:last-child { border-right: none; }
    /* Naranja con texto tinta, como la celda activa del menú de escritorio: la
       crema sobre este naranja da 3.28:1 y no pasa AA. */
    .cg-dia-tab[aria-pressed="true"] { background: var(--naranja); }
    .cg-grid { grid-template-columns: 3.6rem minmax(0, 1fr); }
    .cg-dia:not(.es-visible) { display: none; }
    /* Con un solo día, su título repetía debajo la misma palabra de la pestaña
       naranja. La pestaña ya dice cuál es y cuál es hoy; sin el título la
       columna de horas arranca arriba y se gana media hora de pantalla. */
    .cg-titulo-dia { display: none; }
    .cg-horas { margin-top: 0; }

    .pie { padding: 1.2rem; }

    /* La barra del reproductor, pegada abajo. Es el mismo <audio>: el botón
       comparte estado con el del hero. */
    .barra {
        position: sticky; bottom: 0; z-index: 30;
        display: flex; align-items: center; gap: .8rem;
        background: var(--tinta); color: var(--crema);
        border-top: 3px solid var(--naranja);
        padding: .6rem .8rem;
    }
    .play-mini {
        width: 44px; height: 44px; padding: 0;
        box-shadow: none; border: none;
    }
    .play-mini:hover, .play-mini:active { transform: none; box-shadow: none; }
    .play-mini .play-icono { margin-left: 3px; }
    .play.sonando .play-icono { margin-left: 0; }
    .barra-datos { flex: 1; min-width: 0; }
    .barra-kicker {
        font-size: .6rem; font-weight: 700; color: var(--amarillo);
        letter-spacing: .14em; text-transform: uppercase;
        margin: 0;
    }
    .barra-linea {
        font-size: .8rem; font-weight: 600; margin: 0;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .eq-mini { height: 18px; flex: none; width: 16px; gap: 3px; }
    .eq-mini span { background: var(--naranja); }
    .eq-mini span:nth-child(even) { background: var(--naranja); }
    .barra .compartir { width: 40px; height: 40px; justify-content: center; padding: 0; font-size: .95rem; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
    /* Sin animación, el ecualizador tiene que decir algo igual: barras fijas
       de distinto alto mientras suena, planas cuando no. */
    body.sonando .eq span:nth-child(odd) { height: 85%; }
    body.sonando .eq span:nth-child(even) { height: 55%; }
}
