# Radio La Esquina Azul — `/radio`

Una "radio" que suena las 24 h. La gracia: **no arranca siempre desde la
primera canción**. Al abrir la página se calcula la hora local del visitante y
suena lo que correspondería a *ese* instante, como una radio que siempre estuvo
sonando. Según el momento del día cambia el tipo de música (mañana tranquila,
mediodía movido, tarde, noche, madrugada).

Es una página estática (HTML + CSS + JS, sin build ni dependencias) pensada para
Cloudflare Pages, mobile-first, en es-UY, con la identidad del sitio
(azul `#1f3a93` + verde `#16a34a`, `system-ui`).

## Archivos

```
storefront/radio/
├── index.html        Estructura de la página
├── radio.css         Estilos (mobile-first)
├── programacion.js   ← LA GRILLA: franjas, moods y pistas (esto se edita)
├── radio.js          Motor de audio + interfaz (no hace falta tocarlo)
├── audio/            Acá van los MP3 con licencia (vacío por defecto)
└── README.md         Este archivo
```

## Cómo funciona la grilla horaria

El día se parte en **franjas continuas que cubren las 24 h sin huecos**. Cada
franja tiene una *playlist* que se repite en loop mientras dura la franja:

| Franja | Horario | Mood |
|---|---|---|
| 🌙 Madrugada | 23:00 – 06:00 | ambiente bajo y espacioso |
| ☕ Mañana tranquila | 06:00 – 11:00 | suave, despejado |
| 🍽️ Mediodía movido | 11:00 – 15:00 | más ritmo y brillo |
| 🧉 Tarde | 15:00 – 19:00 | cálido, relajado |
| 🍷 Noche | 19:00 – 23:00 | cálido, lleno, tranquilo |

La lógica central está en `programacion.js`, en `resolverMomento(fecha)`:

1. Toma la hora local del dispositivo del visitante.
2. Busca en qué franja cae (contemplando el cruce de medianoche de la
   madrugada).
3. Calcula los segundos transcurridos **desde que empezó la franja**.
4. Con `segundos % (duración total de la playlist)` obtiene la posición dentro
   del loop, y de ahí **qué pista y en qué segundo exacto** debería estar
   sonando.
5. La radio salta ("seek") a esa pista + ese offset. No reinicia desde cero.

La franja activa, la pista y el segundo se muestran en pantalla, junto con una
línea de tiempo de 24 h con un marcador de "ahora".

> Es la hora **del dispositivo del visitante**, no la de Uruguay. Para la
> mayoría del público (local) coincide. Si quisieras fijarla siempre a
> Montevideo, habría que calcular la hora con `America/Montevideo` en
> `resolverMomento` (hoy usa `new Date()` local).

### Editar la grilla

Todo se edita en `programacion.js`:

- **Horarios de las franjas**: `desde` / `hasta` (en horas, 0–24). Tienen que
  encadenarse sin huecos (el `hasta` de una es el `desde` de la siguiente). La
  madrugada es la que cruza la medianoche (`desde: 23, hasta: 6`).
- **El "mood"** (cómo suena el placeholder): escala, tempo, tipo de onda,
  filtro, etc. Solo aplica al sonido de demostración.
- **Las pistas** de cada franja: título, artista, duración, licencia y `src`.

## Música y licencias ⚠️

**Reglas:** solo música **libre de regalías** (royalty-free) o **Creative
Commons con atribución**. Nada de canciones comerciales con copyright. No se
sube música con derechos al repositorio.

### Lo que suena ahora

La radio trae **13 pistas instrumentales** con licencia que permite uso
comercial citando la fuente. La atribución se muestra sola en la sección
**"Música"** de la página (se arma desde `programacion.js`). Los MP3 están en
`audio/`, re-codificados a 128 kbps para que pesen poco en el celular:

- **Kevin MacLeod** (incompetech.com) — **CC BY 4.0**: 10 temas (bossa, jazz,
  lounge y ambient) repartidos por franja.
- **Zezinho Fernandes** — *Samba Brazil*, **CC BY 4.0** (samba brasilera, en
  Mediodía).
- **Nueve Millas** (banda de Montevideo) — *El secreto del roots* y *Tu lugar
  está acá*, **dominio público** (reggae roots uruguayo, en Tarde y Noche).

> **Fallback sin copyright:** si una pista marca `placeholder: true` o su
> archivo no carga, esa franja suena con un **placeholder sintetizado** (Web
> Audio, sin archivos). Así la radio nunca queda muda.

### Cambiar o agregar música con licencia

1. Conseguí pistas con licencia. Fuentes recomendadas (revisá siempre la
   licencia de cada track y guardá la atribución):
   - **Free Music Archive** (CC) — freemusicarchive.org
   - **ccMixter** (CC) — ccmixter.org
   - **Pixabay Music** (royalty-free) — pixabay.com/music
   - **Incompetech** de Kevin MacLeod (CC-BY) — incompetech.com
   - **Bensound** (gratis con atribución / licencia) — bensound.com
   - **YouTube Audio Library** (según cada track) — studio.youtube.com
2. Copiá los archivos a `audio/`. Los nombres por defecto que espera la grilla
   son `audio/<franja>-<n>.mp3` (ej. `audio/manana-1.mp3`); están en el `src`
   de cada pista en `programacion.js`.
3. En `programacion.js`, por cada pista: poné el nombre real en `src`, completá
   `artista`, `licencia` y agregá `atribucion`, y marcá **`placeholder: false`**.
4. Cada pista con `placeholder: false` y `src` se reproduce como archivo; la
   atribución aparece sola en los créditos. Si falta un archivo, esa franja cae
   al placeholder sintetizado (y avisa en la consola).

> La atribución CC-BY se muestra en la página (sección "Música"), armada desde
> los campos `atribucion` / `licencia` / `url` de cada pista.

## Cómo reproduce el audio (y por qué)

Los MP3 se reproducen con **Web Audio**: se baja el archivo entero, se decodifica
y se arranca el buffer **en el segundo exacto** que corresponde a la hora. Se
hace así —y no con un `<audio>` común— porque **Cloudflare Pages sirve los MP3
sin soporte de _range requests_**, y sin eso un `<audio>` no puede hacer "seek"
(arrancaría siempre desde 0). Con el buffer completo el salto al vivo es preciso.
Como contrapartida, al empezar una pista se baja completa (~2–8 MB); la siguiente
se precarga para que no haya hueco entre temas.

## Autoplay y otras limitaciones

- **Autoplay**: los navegadores bloquean el audio hasta que el usuario
  interactúa. Por eso hay un botón grande **"Encender radio"**: recién ahí se
  crea el `AudioContext` y arranca. Es intencional y no se puede saltear.
- **Hora = la del dispositivo** del visitante (ver nota más arriba).
- **Primer play de cada pista** baja el MP3 entero antes de sonar (1–3 s según
  la conexión); después queda en caché.
- **Sin backend**: todo corre en el navegador. No guarda datos ni usa cookies.

## Cómo se deploya (Cloudflare Pages)

Este repo (`la-esquina-azul-carta`) publica en **Cloudflare Pages**, proyecto
**`laesquinaazul`** (`laesquinaazul.pages.dev`). Se sube la carpeta `dist/`, que
contiene `index.html` (la carta) + `radio/`. Con los *clean URLs* de Pages, la
carpeta `radio/` queda servida en **`/radio`**.

Armar `dist/` y deployar:

```bash
rm -rf dist && mkdir dist && cp index.html dist/ && cp -R radio dist/radio
npx wrangler pages deploy dist --project-name=laesquinaazul
```

- `--branch=main` publica en **producción**; cualquier otra rama (ej.
  `--branch=radio-preview`) deja un **preview** sin tocar el sitio en vivo.
- Requiere `npx wrangler login` (cuenta de Cloudflare) o un `CLOUDFLARE_API_TOKEN`.
- Clean URL: `/radio` sirve `radio/index.html` solo (no hace falta redirects).

### Probar local

Ojo: `python3 -m http.server` **no soporta range requests**, igual que Pages,
así que el audio por Web Audio anda bien. Desde la raíz del repo:

```bash
python3 -m http.server 4322
```

Y abrir `http://localhost:4322/radio/`.

## Qué queda pendiente

- Enlazar `/radio` desde la home cuando esté la navegación (WS1).
- Opcional: fijar la hora a `America/Montevideo`; crossfade entre pistas.
