/* SUNWARD Web · hoja única.
   §1: la web ES SUNWARD Studio simplificado. Esto no es una interpretación del lenguaje de
   Studio: es su MISMO esqueleto —cabecera, carrusel de insignias, acordeón de cápsulas y
   barra de reproducción— con las clases `sw-*` y los valores copiados literalmente de
   `01_SUNWARD-Studio/src/theme/globals.css`. Lo que cambia es lo que se ha QUITADO, que es
   todo lo interno: herramientas de la cabecera, lápiz de editar, exportar derivados,
   continuidad, historial, la tira de los ocho pasos, los puntos de progreso, el botón de
   añadir escena y el arrastrar para reordenar. Nada de eso es público.
   Si algo de aquí se separa de Studio, es un error: se corrige mirando globals.css. */

/* La itálica de Fraunces (`ital,` y la serie `1,9..144,300`) entra el 4 de septiembre de 2026
   con la sección «Qué es Sunward», cuya cita va en cursiva. No es un capricho tipográfico: en
   `:root` hay `font-synthesis: none`, así que el navegador NO se inventa una cursiva falsa —
   sin esta variante, ese texto se habría quedado en redonda y nadie habría visto un error. */
@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300;0,9..144,500;0,9..144,600;1,9..144,300&family=Geist:wght@400;500;600&family=JetBrains+Mono:wght@400;500;700&display=swap');

:root {
  /* Los tokens de Studio, con sus mismos nombres y sus mismos valores. */
  --sw-paper: #F2EEE4;
  --sw-ink: #17160F;
  --sw-muted: #8C8874;
  --sw-line: rgba(23, 22, 15, .14);
  --sw-line-strong: rgba(23, 22, 15, .24);
  --sw-accent: #D88A3D;
  --sw-complete: #5E7C67;
  --sw-player-space: 88px;
  --sw-capsula: calc(80 / 420);
  --sw-tira-min: 44px;
  /* .75 → .95: la insignia se veía pequeña para ser el identificador del álbum (Alex,
     2026-08-26). Es un +27 %, dentro del 25-30 % pedido. Toda la geometría del carrusel
     cuelga de esta variable, así que el alto reservado y el margen negativo se ajustan
     solos — no hay ningún píxel que tocar aparte de este. */
  --sw-insignia-escala: .95;

  font-family: Geist, system-ui, sans-serif;
  color: var(--sw-ink);
  background: var(--sw-paper);
  font-synthesis: none;

  /* Medidas de los paneles de lectura de la canción (§13). */
  --t: 14px;
  --h: 19px;
}

/* Studio no lleva este reset; aquí sí, porque no hay build que normalice nada. */
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; }
/* El acordeon mide su alto contra la ventana: #sitio tiene que llegar hasta abajo. */
body[data-vista="album"] #sitio { height: 100%; }
/* El álbum es la aplicación: ocupa la ventana y no hace scroll, como Studio. La ficha sí. */
body[data-vista="album"] { overflow: hidden; }
body { background: var(--sw-paper); color: var(--sw-ink); font-family: Geist, system-ui, sans-serif; font-size: var(--t); line-height: 1.6; -webkit-font-smoothing: antialiased; }
button { font: inherit; }
/* TODO acento lleva el color de la insignia del album (Alex, 26 ago). El naranja de marca
   queda solo de respaldo, para cuando un lugar no tenga insignia SVG de la que leerlo. */
button:focus-visible { outline: 2px solid var(--sw-acento, var(--sw-accent)); outline-offset: 2px; }

.sw-app-shell { height: 100%; display: flex; flex-direction: column; background: var(--sw-paper); }

/* ---- cabecera: solo el logotipo. Las herramientas de Studio son trabajo interno ---- */
/* El alto lo reserva Studio con su logotipo de 145 px: la insignia activa crece hacia
   arriba (scale 1,2) y sin ese aire se sale por el techo de la ventana. */
.sw-header { flex: none; display: flex; align-items: center; min-height: 96px; padding: 14px 28px 0; }
/* El logotipo de Studio dice STUDIO: eso es la herramienta interna. Aqui va la marca sola,
   el mismo trazo que firma los videos. */
.sw-header-logo { width: 190px; height: auto; flex: none; opacity: .96; filter: brightness(0); }
/* El idioma: un icono `Earth` que alterna, con el superíndice del idioma que se está leyendo.
   Ni bandera ni dos botones — una bandera nombra un país, y ni el castellano ni el inglés son
   de uno solo.
   Al pasar por encima, el círculo se tiñe del cielo de la insignia activa y el icono toma su
   color de marco. Sin línea exterior (Alex, 26 ago): el borde convertía el sombreado en un
   botón, y esto es una sombra, no una caja. Los colores los escribe el generador leyendo el
   SVG de la propia insignia, así que la cabecera cambia de color con el álbum sin que nadie
   los repita a mano. Si un lugar no tiene insignia SVG, se queda en el naranja de marca. */
.sw-lang-btn {
  margin-left: auto; position: relative; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%;
  border: 0; background: none; cursor: pointer; padding: 0;
  /* El azul de marco de la insignia, siempre y no solo al pasar por encima (Alex, 26 ago):
     el idioma pertenece al álbum que se está viendo, igual que el reproductor. */
  color: var(--sw-acento, var(--sw-accent));
  transition: background-color .2s ease, color .2s ease;
}
.sw-lang-btn:hover {
  /* Al pasar por encima solo aparece el fondo: el color del trazo ya es el del marco. Es el
     mismo 52 % del cielo que usa el botón de play — al 100 % se veía más oscuro que aquel,
     siendo el mismo gesto en dos sitios de la pantalla. */
  background: color-mix(in srgb, var(--sw-cielo, var(--sw-accent)) 52%, transparent);
}
.sw-lang-btn:focus-visible { outline: 2px solid var(--sw-acento, var(--sw-accent)); outline-offset: 2px; }
/* Del icono queda solo su círculo exterior y las dos letras van DENTRO (Alex, 26 ago): en vez
   de un superíndice colgando de una esquina, una moneda. Es el Circle de Lucide tal cual lo
   pasó Alex: 20 × 20 y trazo 1,25, sin tocarle el tamaño. El interior mide 16,7 px y el texto
   12,4 — cabe con dos píxeles de aire a cada lado.
   La negrita es de verdad: el 700 se AÑADIÓ al @import de JetBrains Mono, que estaba cargada
   solo en 400 y 500 — con `font-synthesis: none` el navegador no la finge, la ignora. */
.sw-lang-txt {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700;
  line-height: 1; letter-spacing: .2px; pointer-events: none;
}

/* ---- grupo central: insignias + canciones, con su hueco para el reproductor ---- */
.sw-content-group { flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 18px; padding: 0 0 var(--sw-player-space); }

/* ---- insignias = álbumes (§4): la rueda cover flow de Studio, tal cual ---- */
.sw-badge-coverflow { flex: none; position: relative; height: calc(183px * var(--sw-insignia-escala)); }
.sw-badge-track {
  position: relative; width: min(760px, 94%); height: 183px;
  perspective: 1100px; perspective-origin: 50% 100%;
  margin: calc(-183px * (1 - var(--sw-insignia-escala))) auto 0;
  transform: scale(var(--sw-insignia-escala)); transform-origin: bottom center;
}
.sw-badge-slot {
  position: absolute; left: 50%; bottom: 0; transform-origin: bottom center;
  transition: transform .38s cubic-bezier(.22,.61,.36,1), opacity .3s ease;
}
.sw-badge-item { display: flex; background: none; border: 0; cursor: pointer; padding: 0; }
.sw-badge-item:hover { filter: brightness(1.08); }
.sw-badge-item img { width: 111px; height: auto; display: block; opacity: .5; filter: saturate(.45); transition: opacity .2s ease, filter .2s ease; }
.sw-badge-item:hover img { opacity: .78; filter: saturate(.7); }
.sw-badge-item[data-active="true"] img { opacity: 1; filter: saturate(1); }

/* El album como desplegable: solo en movil. En escritorio el carrusel de insignias hace este
   trabajo mucho mejor, y dos selectores del mismo dato a la vez confunden. */
.sw-album-menu { display: none; position: relative; }
.sw-album-menu > summary {
  display: flex; align-items: center; gap: 7px; cursor: pointer; list-style: none;
  padding: 4px 8px; border-radius: 999px;
}
.sw-album-menu > summary::-webkit-details-marker { display: none; }
.sw-album-menu > summary:hover { background: color-mix(in srgb, var(--sw-cielo, var(--sw-accent)) 52%, transparent); }
/* El pictograma va apaisado y a pelo: es un trazo en el azul del marco, no una lamina, asi
   que ni filete ni fondo. El sello, si toca caer a el, es vertical y necesita otra medida. */
.sw-album-mini { width: 24px; height: auto; display: block; flex: none; }
.sw-album-mini--sello { width: 15px; border-radius: 0; box-shadow: none; }
.sw-album-nombre, .sw-album-lista span {
  font-family: 'JetBrains Mono', monospace; font-weight: 700; font-size: 11px;
  letter-spacing: .04em; white-space: nowrap; color: var(--sw-acento, var(--sw-accent));
}
.sw-album-flecha { color: var(--sw-acento, var(--sw-accent)); transition: transform .2s ease; }
.sw-album-menu[open] > summary .sw-album-flecha { transform: rotate(180deg); }
.sw-album-lista {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 80;
  display: flex; flex-direction: column; gap: 2px; padding: 6px;
  border-radius: 14px; background: var(--sw-paper); border: 1px solid var(--sw-line-strong);
  box-shadow: 0 8px 24px rgba(23,22,15,.18);
}
.sw-album-lista button {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 6px 10px 6px 6px; border: 0; border-radius: 999px; background: none; cursor: pointer;
}
.sw-album-lista button:hover { background: color-mix(in srgb, var(--sw-cielo, var(--sw-accent)) 52%, transparent); }
.sw-album-lista button[data-active="true"] span { text-decoration: underline; text-underline-offset: 3px; }

/* ---- acordeón de canciones (§8): el de escenas de Studio ---- */
/* La obra fuera del carrusel: solo la usa el movil, donde la lista se desplaza y la pieza
   grande no puede desplazarse con ella. En escritorio manda el acordeon. */
.sw-ficha-fija { display: none; }
.sw-scene-accordion { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; padding: 0 28px; container-type: inline-size; }
.sw-scene-row {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; flex: none;
  height: min(100%, calc((100cqw - var(--sw-huecos, 0px))
                         / (var(--sw-activa, 16 / 9) + var(--sw-tira-n, 0) * var(--sw-capsula))));
}
.sw-scene-card {
  position: relative; flex: 0 1 auto; aspect-ratio: var(--sw-capsula); min-width: var(--sw-tira-min); height: 100%; border-radius: 40px; overflow: hidden;
  cursor: pointer; background-size: cover; background-position: center; border: 0; padding: 0;
  transition: flex-basis .4s cubic-bezier(.4,0,.2,1), border-radius .4s cubic-bezier(.4,0,.2,1), filter .3s ease;
  box-shadow: 0 1px 2px rgba(23,22,15,.08);
  container-type: size;
}
.sw-scene-card[data-active="true"] { flex: 0 0 auto; height: 100%; aspect-ratio: 16/9; border-radius: 40px; background-size: contain; background-repeat: no-repeat; background-color: #0B0F14; cursor: pointer; }
.sw-scene-card::after { content: ''; position: absolute; inset: 0; background: linear-gradient(0deg, rgba(0,0,0,.62) 0%, transparent 42%); opacity: 0; transition: opacity .2s ease; }
.sw-scene-card[data-active="true"]::after, .sw-scene-card:hover::after { opacity: 1; }
/* Una canción todavía no publicada llega con su ilustración DESATURADA —no en grises: el color
   sigue ahí, muy suave—, su número y su estado (Alex, 2026-08-26). Toda la lectura del sistema
   cabe en una frase: a color = ya publicado, apagada = todavía por salir.
   La desaturación viene ya hecha del generador — aquí no hay `filter`, y no es un detalle: con
   el filtro el navegador recibiría la imagen a plena saturación y bastaría un clic para verla. */
.sw-scene-card--bloqueada {
  flex: 0 1 auto; aspect-ratio: var(--sw-capsula); min-width: var(--sw-tira-min); height: 100%;
  border-radius: 40px; overflow: hidden; cursor: default;
  background-size: cover; background-position: center; background-color: transparent;
  position: relative; container-type: size;
  box-shadow: 0 1px 2px rgba(23,22,15,.08);
}
/* Sin ilustración vuelve el hueco de Studio (`.sw-scene-add`), sin el «+». */
.sw-scene-card--bloqueada:not([style*="url"]) { border: 1px dashed var(--sw-line-strong); }
/* El velo que hace legibles número y rótulo sobre la obra. Uniforme y no en degradado desde
   abajo como en las publicadas: aquí el rótulo va centrado, y un degradado que nace en el
   borde inferior no lo cubriría. Suave a propósito — el punto de esto es que se vea el color
   atenuado, no taparlo. */
.sw-scene-card--bloqueada::after {
  content: ''; position: absolute; inset: 0; background: rgba(11,15,20,.24);
}
.sw-scene-card-num { position: absolute; left: 50%; top: 40px; z-index: 3; transform: translate(-50%, -50%); font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: rgba(245,239,230,.7); opacity: .85; }
.sw-scene-card--bloqueada:not([style*="url"]) .sw-scene-card-num { color: var(--sw-muted); }
/* El estado, en la vertical del título de las publicadas y en la mono de los datos técnicos:
   es un dato, no una voz editorial. */
.sw-scene-card-estado {
  /* El texto arranca donde el extremo de la píldora tiene el centro de su semicírculo: el
     radio es 40px, así que ese punto está a 40px del borde inferior. Ahí empieza y crece hacia
     arriba — la línea de texto y la curva de la cápsula comparten origen.
     El giro va DENTRO de `transform`, no en la propiedad `rotate` suelta: `rotate` se aplica
     antes que `transform`, así que un `translate` se calcularía sobre el elemento ya girado y
     lo mandaría al lado contrario. */
  position: absolute; left: 50%; bottom: 40px; z-index: 3;
  transform: translateX(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  max-height: calc(100cqh - 100px); overflow: hidden; white-space: nowrap;
  font-family: 'JetBrains Mono', monospace; font-size: 13px; letter-spacing: .02em;
  color: rgba(245,239,230,.9); text-shadow: 0 1px 3px rgba(0,0,0,.75);
}
.sw-scene-card--bloqueada:not([style*="url"]) .sw-scene-card-estado { color: var(--sw-muted); text-shadow: none; }

/* LA PROXIMA (Alex, 26 ago). El sistema tiene tres estados y no dos, y se deducen solos de la
   fecha: publicada, proxima —una sola, la mas cercana— y anunciada. La proxima es lo unico
   sobre lo que un visitante que llega hoy puede hacer algo, asi que deja de ser una espera:
   sale a color desde el generador, su velo se aclara y su rotulo va en el acento del album con
   la cuenta atras. Las otras once se quedan con su fecha y nada mas. */
.sw-scene-card--bloqueada[data-proxima="true"]::after {
  background: linear-gradient(0deg, rgba(0,0,0,.42) 0%, transparent 52%);
}
.sw-scene-card--bloqueada[data-proxima="true"] .sw-scene-card-estado {
  color: #FFF3E2; font-weight: 700;
}
.sw-scene-card--bloqueada[data-proxima="true"] .sw-scene-card-num { color: rgba(255,243,226,.9); }
/* La proxima NO lleva marco (Alex, 28 ago). Lo llevo dos dias: un anillo de 2px en el acento
   del album, que en VAL D'ARAN es el azul #1A63AD. Se retira entero — tambien el suyo de la
   version movil, que iba hacia dentro— y la tarjeta hereda la sombra base de las demas.
   Sigue distinguiendose de las otras once por tres cosas, que bastan: el velo se le aclara, el
   rotulo va en claro y en negrita con la cuenta atras, y el numero se le sube de tono. */

/* Las bloqueadas no responden al clic — eso es correcto — pero el cursor las hacia parecer
   pulsables. Ahora lo dicen tambien con la forma del puntero, no solo con el title. */
.sw-scene-card--bloqueada { cursor: default; }
.sw-scene-card-song { position: absolute; left: 50%; bottom: 60px; transform: translateX(-50%); z-index: 2; pointer-events: none; opacity: 0; transition: opacity .2s ease; }
.sw-scene-card:not([data-active="true"]):hover .sw-scene-card-song { opacity: 1; }
.sw-scene-card-song-text { display: block; margin: 0; writing-mode: vertical-rl; transform: rotate(180deg); max-height: calc(100cqh - 130px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: 'Fraunces', serif; font-weight: 600; font-size: 15px; line-height: 1.15; color: rgba(245,239,226,.8); text-shadow: 0 1px 3px rgba(0,0,0,.7); }

/* ---- lo que va sobre la imagen: marca, título, lugar·hora y código ---- */
/* En Studio el marco se calcula en JS porque la foto puede no ser 16:9. Aquí todo es 16:9
   por definición del formato, así que el marco ES la tarjeta. */
.sw-photo-overlay-frame { position: absolute; inset: 0; overflow: hidden; pointer-events: none; container-type: size; }
.sw-photo-brand { position: absolute; inset: 0; width: 100%; height: 100%; filter: drop-shadow(0 1px 4px rgba(0,0,0,.4)) drop-shadow(0 0 10px rgba(0,0,0,.18)); pointer-events: none; }
/* Colores SOLIDOS, sin alfa (Alex, 26 ago). Iban a rgba(...,.8), y con alfa el color que
   llega al ojo depende de lo que haya debajo: en pantalla completa es el negro #070B10 limpio,
   pero en la card el gradiente solo oscurece un 62 % en la base y se desvanece, asi que el
   texto se contaminaba con la foto y cambiaba de color segun la imagen.
   Estos tres valores son exactamente los que resultaban en pantalla completa, ya compuestos.
   Se ven igual alli y dejan de bailar aqui. */
.sw-photo-song-title {
  position: absolute; left: 4.1667cqw; bottom: 10.75cqh; max-width: calc(100% - 8.3334cqw); margin: 0;
  font-family: 'Fraunces', serif; font-weight: 600; font-size: clamp(19px, 1.875cqw, 72px); line-height: 1.15;
  color: #C5C1B8; text-shadow: 0 1px 3px rgba(0,0,0,.7);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sw-photo-place-time {
  position: absolute; left: 4.1667cqw; bottom: 7.407cqh; max-width: calc(100% - 8.3334cqw);
  font-family: 'JetBrains Mono', monospace; font-weight: 500; font-size: clamp(14px, 1.432cqw, 55px); line-height: 1.2;
  color: #B1BCB8; text-shadow: 0 1px 3px rgba(0,0,0,.7);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* El estado y la fecha de la canción que SÍ ha salido (Alex, 26 ago). Las que no han salido lo
   dicen en su cápsula, y a esta le faltaba.
   Va DEBAJO del código de escena y alineado con él a la derecha: los dos son datos de archivo,
   y juntos forman esa columna. A la izquierda vive lo que nombra la obra —título, lugar, hora—
   y no es lo mismo. Más apagado y más pequeño que ellos, a propósito. */
.sw-photo-estado {
  position: absolute; right: 24px; bottom: 7.407cqh; text-align: right;
  /* MISMO cuerpo y misma línea que `lugar · hora`, con el que comparte renglón: con cuerpos
     distintos las cajas se alinean por abajo pero las líneas base no caen en el mismo sitio, y
     el ojo lo ve torcido. La discreción la pone el color, no el tamaño. */
  font-family: 'JetBrains Mono', monospace; font-weight: 500; font-size: clamp(14px, 1.432cqw, 55px); line-height: 1.2;
  color: #8B9492; text-shadow: 0 1px 3px rgba(0,0,0,.7);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sw-photo-scene-code {
  position: absolute; right: 24px; bottom: 11.3cqh;
  font-family: 'JetBrains Mono', monospace; font-weight: 500; font-size: clamp(14px, 1.432cqw, 55px); line-height: 1.2;
  color: #B1BCB8; text-shadow: 0 1px 3px rgba(0,0,0,.7); white-space: nowrap;
}


/* ---- barra de reproducción: `.sw-player-bar` de Studio ---- */
/* Vive FUERA de lo que se repinta (index.html) porque rehacer un iframe corta la música. */
#reproductor:empty { display: none; }
#reproductor {
  position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 70;
  display: flex; flex-direction: column; align-items: stretch;
  width: min(680px, calc(100% - 56px));
  /* Mas estilizada (Alex, 26 ago): el alto lo marcaba el circulo de 44px del icono, que era
     la medida de un boton con rotulo al lado. Sin rotulo no hace falta: 32px de circulo y
     4px de aire dejan la pildora en 40. Estrecha y ancha, como una barra de reproduccion. */
  padding: 4px 16px 4px 4px; border-radius: 999px;
  background: #FCEFC8; color: #06202C;
  box-shadow: 0 6px 18px rgba(23,22,15,.14);
}
/* El <audio> no se ve: los controles son los de esta misma pildora, que son los del sistema
   visual. `display: none` no le quita ni una capacidad — un elemento oculto reproduce igual.
   Lo que NO se puede es sacarlo del DOM, y por eso el reproductor no se repinta nunca. */
#reproductor audio.sw-audio { display: none; }

/* ---- los controles: dos filas que en escritorio son una ---- */
/* Aqui vive TODO (Alex, 28 ago): play, tiempo, Spotify, las cuatro capas, el video, el limpio
   y el cerrar. Antes estaban repartidos en tres sitios y ahora hay una sola barra.
   El marcado es el MISMO en escritorio y en movil — cambia solo esta hoja. */
.sw-controles { display: flex; align-items: center; gap: 6px; min-width: 0; }
/* `display: contents` disuelve las filas: sus botones pasan a ser hijos directos de
   `.sw-controles` y todo cae en una linea. Es lo que permite un unico marcado para las dos
   formas, sin que el JavaScript mida la ventana ni una sola vez. */
.sw-fila { display: contents; }
.sw-fila-1, .sw-fila-2 { align-items: center; gap: 2px; }
/* El boton de `Mas` solo existe en movil: aqui las dos filas ya estan a la vista. Lleva el
   padre delante a proposito — `.sw-capa-btn` se declara mas abajo y con una sola clase le
   ganaba, y `Mas` aparecia tambien en escritorio. */
.sw-controles .sw-mas-btn { display: none; }

/* El separador entre grupos: un punto, como el que ya separa lugar y hora sobre la obra
   (Alex, 28 ago). No una linea — la web casi no tiene. */
.sw-sep {
  flex: none; width: 3px; height: 3px; border-radius: 50%;
  background: currentColor; opacity: .28; margin: 0 5px;
}
/* Nada se descarga hasta que se pulsa: esto es lo que hay antes. */
.pedir {
  /* Sin `width: 100%`: se comia la barra entera y la dejaba en su minimo de 60px. Ahora
     ocupa lo suyo y el resto es para el tiempo y el progreso. */
  /* Solo el icono: ni rótulo ni nota (Alex, 26 ago). El texto sigue en `title` y en
     `aria-label` para quien no ve el icono. */
  display: flex; align-items: center; flex: none; cursor: pointer;
  padding: 0; border-radius: 999px; font: inherit;
  background: none; color: inherit; border: 0;
}
/* Sin sombreado en el boton entero: el unico circulo que se tine es el del icono. Teniendo
   los dos, la barra mostraba una pildora clara enorme detras del control (Alex, 26 ago). */
.pedir .play {
  flex: none; display: grid; place-items: center; width: 32px; height: 32px;
  /* Circular, no cuadrado con esquinas: el sombreado de reproduccion es un circulo, el mismo
     gesto que el del idioma en la cabecera. */
  border-radius: 50%; border: 0; background: none;
  color: var(--sw-acento, var(--sw-accent));
  transition: background-color .2s ease;
  position: relative;
}
/* Mientras suena, el circulo se llena del cielo de la insignia. Y "mientras suena" es de
   verdad: lo dice el propio elemento de audio —sus eventos play y pause—, no una suposicion
   nuestra. Si el visitante pausa desde los auriculares o desde el sistema, el circulo se apaga. */
.pedir[data-sonando="true"] .play {
  background: color-mix(in srgb, var(--sw-cielo, var(--sw-accent)) 52%, transparent);
}
.pedir .play svg { display: block; }

/* El tiempo y la barra (Alex, 26 ago). Los números en la mono de los datos técnicos y con
   `tabular-nums`: sin eso, la cifra baila de ancho a cada segundo y el texto tiembla.
   La barra toma los dos tonos del álbum, como todo lo demás: el surco en cielo, lo recorrido
   en el azul del marco. */
.sw-tiempo { flex: 1 1 auto; display: flex; align-items: center; gap: 12px; min-width: 0; }
.sw-tiempo span {
  flex: none; font-family: 'JetBrains Mono', monospace; font-size: 11px;
  font-variant-numeric: tabular-nums; color: var(--sw-muted);
}
.sw-barra {
  flex: 1 1 auto; height: 4px; border-radius: 999px; cursor: pointer; min-width: 60px;
  background: color-mix(in srgb, var(--sw-cielo, var(--sw-accent)) 52%, transparent);
}
/* El área de pulsación va más allá de los 4 px que se ven: acertar en una línea de 4 px con el
   ratón es incómodo, y con el dedo imposible. */
.sw-barra::before { content: ''; position: absolute; inset: -10px 0; }
.sw-barra { position: relative; }
.sw-barra-hecho {
  height: 100%; border-radius: 999px; width: 0;
  background: var(--sw-acento, var(--sw-accent));
  /* Sin transicion: la mueve requestAnimationFrame fotograma a fotograma, y una transicion
     encima solo anadiria retardo y rebote. */
}
/* El enlace a Spotify: mismo gesto que el icono de idioma — circulo que se tine al pasar por
   encima. Ya no es el reproductor —eso lo hace ahora el archivo propio— pero se queda como
   atribucion y como puerta a la biblioteca de quien escucha alli (Alex, 28 ago). */
.sw-spotify {
  flex: none; display: grid; place-items: center; width: 32px; height: 32px;
  border-radius: 50%; color: var(--sw-acento, var(--sw-accent));
  transition: background-color .2s ease;
}
.sw-spotify:hover { background: color-mix(in srgb, var(--sw-cielo, var(--sw-accent)) 52%, transparent); }
.sw-spotify svg { display: block; }

.sw-barra:focus-visible { outline: 2px solid var(--sw-acento, var(--sw-accent)); outline-offset: 4px; }

/* La letra sobre la obra: copiada de `PhotoViewer` de Studio, misma posicion y mismos valores.
   Se ve el grupo ENTERO — lo ya cantado en claro y lo que falta apagado —, que es lo que da la
   sensacion de que acompana. No es karaoke: no hay palabra por palabra ni color que avance. */
.sw-photo-lyrics-group {
  position: absolute; left: 4.1667cqw; bottom: 24cqh;
  max-width: calc(58% - 8.3334cqw);
  display: flex; flex-direction: column; gap: .2em; z-index: 4;
}
.sw-photo-lyrics-line {
  margin: 0; font-family: 'Fraunces', serif; font-weight: 300;
  /* Minimo de 14 a 20: en la tarjeta del album el contenedor es pequeno y el texto caia
     siempre al minimo, quedandose diminuto. A pantalla completa no cambia nada — alli manda
     el 1,875cqw, que ya da 24px. */
  font-size: clamp(20px, 1.875cqw, 72px); line-height: 1.3;
  color: rgba(245,239,226,.45); text-shadow: 0 1px 3px rgba(0,0,0,.7);
  transition: color 220ms ease, font-weight 220ms ease;
}
.sw-photo-lyrics-line[data-active=true] { font-weight: 500; color: rgba(255,255,255,.98); }
@media (prefers-reduced-motion: reduce) { .sw-photo-lyrics-line { transition: none; } }


/* ── Pantalla 2 · la canción (§12 + §13, ahora la misma) ─────────────────── */
/* Decisión de Alex (25 ago): la pantalla completa y la ficha son LA MISMA pantalla. La
   ilustración es la base; los iconos no la adornan, la estructuran. Para la v1 el panel es
   siempre el mismo oscuro translúcido con desenfoque: NO se porta todavía el sistema de
   contraste medido de Studio. */
body[data-vista="cancion"] { overflow: hidden; }
body[data-vista="cancion"] #sitio { height: 100%; }

.sw-cancion { position: fixed; inset: 0; z-index: 60; background: #070B10; display: grid; place-items: center; }
/* El rótulo se ancla al rectángulo REAL de la obra, no a la ventana: como la obra siempre es
   16:9, basta con que lo sea el escenario. Studio lo mide en JS; aquí no hace falta. */
.sw-cancion .sw-photo-stage { position: relative; aspect-ratio: 16 / 9; width: min(100%, calc((100vh - var(--sw-player-space)) * 16 / 9)); }
.sw-cancion img.sw-photo-image { width: 100%; height: 100%; object-fit: contain; display: block; }
/* El vídeo ocupa el mismo rectángulo que la ilustración: es la misma obra en movimiento. */
.sw-cancion iframe.sw-photo-image { width: 100%; height: 100%; border: 0; display: block; background: #000; }
/* «Solo la obra»: se apaga el rótulo, no los controles. */
.sw-cancion[data-limpio="true"] .sw-photo-brand,
.sw-cancion[data-limpio="true"] .sw-photo-song-title,
.sw-cancion[data-limpio="true"] .sw-photo-place-time,
.sw-cancion[data-limpio="true"] .sw-photo-estado,
.sw-cancion[data-limpio="true"] .sw-photo-scene-code { opacity: 0; transition: opacity .25s ease; }

.sw-capa-btn {
  position: relative; flex: none; display: grid; place-items: center;
  width: 32px; height: 32px; border-radius: 50%;
  border: 0; background: none; color: #06202C; cursor: pointer; opacity: .55;
  transition: opacity .15s ease, background-color .15s ease;
}
.sw-capa-btn svg { display: block; }
.sw-capa-btn:hover:not(:disabled) { opacity: .9; background: rgba(23,22,15,.07); }
.sw-capa-btn[data-viendo="true"] {
  opacity: 1; color: var(--sw-acento, var(--sw-accent));
  background: color-mix(in srgb, var(--sw-cielo, var(--sw-accent)) 52%, transparent);
}
/* Un icono que no puede enseñar nada no finge que sí. */
.sw-capa-btn:disabled { opacity: .2; cursor: default; }
/* El superíndice del micro dice qué letra se está leyendo, igual que en Studio. */
.sw-capa-btn sup {
  position: absolute; top: 2px; right: 0;
  font-family: 'JetBrains Mono', monospace; font-size: 8px; line-height: 1; letter-spacing: .3px;
}

/* ---- ORIGEN: la fotografia de la que nacio la obra ---- */
/* Vive al final de Narrativa, despues de las sensaciones (Alex, 29 ago). La ilustracion sigue
   siendo LA OBRA y esto es el ORIGEN: no hay conmutador foto/ilustracion, ni comparador, ni
   nada que cambie solo. Se ve despues de conocer la escena, para revelar de donde nacio.
   De ahi que sea deliberadamente secundaria: mas pequena que el ancho del panel, con el pie en
   la mono de los datos tecnicos y sin nada que llame la atencion antes de tiempo. */
.sw-origen {
  display: block; width: 100%; padding: 0; margin-top: 4px;
  border: 0; background: none; cursor: zoom-in; text-align: left;
  color: inherit; font: inherit;
}
.sw-origen img {
  display: block; width: 100%; max-width: 260px; border-radius: 8px;
  border: 1px solid rgba(245,239,226,.14);
  transition: border-color .2s ease, transform .2s ease;
}
.sw-origen:hover img { border-color: rgba(245,239,226,.34); }
.sw-origen-pie {
  display: block; margin-top: 7px; max-width: 260px;
  font-family: 'JetBrains Mono', monospace; font-size: 10.5px; line-height: 1.4;
  color: rgba(245,239,226,.52);
}

/* La fotografia ampliada. Cubre la ventana entera —tambien el reproductor, que es lo unico
   que vive por encima de la ficha— asi que su z-index va por delante de los 70 de aquel.
   `contain` y no `cover`: se ve ENTERA y con su proporcion, sea cual sea. */
.sw-foto-lightbox {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center; padding: 40px;
  background: rgba(7,11,16,.94); backdrop-filter: blur(6px);
  cursor: zoom-out;
}
.sw-foto-lightbox img {
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  object-fit: contain; display: block; border-radius: 6px;
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
  /* El cursor de cerrar es del fondo, no de la obra: sobre la foto no se cierra. */
  cursor: default;
}
.sw-foto-cerrar {
  position: absolute; top: 20px; right: 20px;
  display: grid; place-items: center; width: 40px; height: 40px;
  border: 0; border-radius: 50%; background: rgba(242,238,228,.1);
  color: var(--sw-paper); cursor: pointer;
  transition: background-color .2s ease;
}
.sw-foto-cerrar:hover { background: rgba(242,238,228,.22); }
.sw-foto-cerrar svg { display: block; }

/* ---- el panel de lectura ---- */
/* Dos anchos, que pidió Alex: corto para Story/Score/Legacy, ancho para la letra. */
.sw-capa {
  position: absolute; z-index: 5; pointer-events: auto;
  /* Abajo se para antes de la tira de iconos y del reproductor: si pasara por debajo,
     el final del texto quedaria tapado justo donde se esta leyendo. */
  /* Sin scroll (Alex, 26 ago): sobraban 37px arriba y 62 entre el panel y la tira de iconos.
     Se recuperan casi todos y se deja solo el aire justo. */
  top: 2.6cqh; bottom: 15.4cqh; right: 4.1667cqw;
  display: flex; flex-direction: column;
  border-radius: 22px; border: 1px solid rgba(245,239,226,.16);
  background: rgba(7,11,16,.72); backdrop-filter: blur(14px);
  color: rgba(245,239,226,.86); box-shadow: 0 12px 40px rgba(0,0,0,.42);
}
.sw-capa[data-ancho="corto"] { width: min(400px, 40cqw); }
/* La letra ocupa casi todo el escenario: es el unico contenido que no cabe de otra forma, y
   cuantas mas columnas quepan, menos alto necesita. */
.sw-capa[data-ancho="ancho"] { width: min(1180px, 92cqw); left: 50%; right: auto; transform: translateX(-50%); }
.sw-capa-cabeza {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 16px 22px 12px; border-bottom: 1px solid rgba(245,239,226,.14);
}
/* El icono de la capa abierta, el MISMO que su boton de la barra inferior y en el mismo
   naranja con que ese boton se marca encendido: es lo que ata el control con lo que abre.
   Sin circulo, sin fondo, sin insignia — el icono y ya. */
.sw-capa-icono { flex: none; display: flex; color: var(--sw-acento, var(--sw-accent)); }
.sw-capa-icono svg { display: block; }
/* El titulo se lleva el hueco que queda, para que el codigo siga pegado a la derecha. */
.sw-capa-cabeza strong { margin-right: auto; }
.sw-capa-cabeza strong { font-family: Fraunces, serif; font-weight: 600; font-size: var(--h); letter-spacing: .4px; text-transform: uppercase; }
.sw-capa-cabeza .codigo { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: rgba(245,239,226,.55); }
/* El scroll lo hace el panel por dentro: la página no se mueve nunca. */
.sw-capa-cuerpo { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 22px 22px; overscroll-behavior: contain; }
.sw-capa-cuerpo::-webkit-scrollbar { width: 6px; }
.sw-capa-cuerpo::-webkit-scrollbar-thumb { background: rgba(245,239,226,.22); border-radius: 3px; }
.sw-capa-cuerpo p + p { margin-top: 10px; }
.sw-capa-cuerpo h3 { font-family: Fraunces, serif; font-weight: 600; font-size: var(--h); letter-spacing: .4px; text-transform: uppercase; margin: 18px 0 8px; }
.sw-capa-cuerpo h3:first-child { margin-top: 0; }

/* ── sistema compartido de las capas ─────────────────────────────────────────
   Cuatro capas, una sola familia. Lo que cambia entre ellas es el RITMO, no las piezas:
   Story respira en prosa, Lyrics se compone como libreto, Score es tabular, Legacy va en dos
   modulos rotulados. Estetica de libreto y de ficha de archivo, no de panel de aplicacion.

   LA REGLA DE ARCHIVO. Un filete con su etiqueta encima, que es como se separan las secciones
   de una ficha de museo. Sustituye a los titulares sueltos: el titular pesaba tanto como el
   texto y partia la lectura en dos. */
.regla { display: flex; align-items: center; gap: 12px; margin: 15px 0 9px; }
.regla:first-child { margin-top: 0; }
.regla::after { content: ''; flex: 1; height: 1px; background: rgba(245,239,226,.16); }
.regla span {
  flex: none; font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 500;
  letter-spacing: 1.4px; text-transform: uppercase; color: rgba(245,239,226,.52);
}

/* LOS CHIPS. Misma forma en las dos capas que los usan, distinto color: las sensaciones son
   del cielo del album y los generos de su marco. Asi se distinguen sin leerlos. */
.chips { display: flex; gap: 7px; flex-wrap: wrap; list-style: none; }
.chips li {
  border-radius: 999px; padding: 3px 12px;
  font-family: 'JetBrains Mono', monospace; font-size: calc(var(--t) * .78); letter-spacing: .3px;
}
.chips--cielo li {
  border: 1px solid color-mix(in srgb, var(--sw-cielo, var(--sw-accent)) 46%, transparent);
  background: color-mix(in srgb, var(--sw-cielo, var(--sw-accent)) 12%, transparent);
  color: color-mix(in srgb, var(--sw-cielo, var(--sw-accent)) 84%, white);
}
.chips--marco li {
  border: 1px solid color-mix(in srgb, var(--sw-acento, var(--sw-accent)) 52%, transparent);
  background: color-mix(in srgb, var(--sw-acento, var(--sw-accent)) 16%, transparent);
  color: rgba(245,239,226,.82);
}

/* ── STORY ─────────────────────────────────────────────────────────────────
   La entradilla es el primer parrafo del resumen, que es el que enuncia la idea. Va en la
   serif y a mayor cuerpo; los otros dos quedan de cuerpo de texto. No es un adorno: marca
   cual es la frase que hay que leer si solo se lee una. */
.idea {
  font-family: Fraunces, serif; font-weight: 500;
  font-size: calc(var(--t) * 1.24); line-height: 1.45;
  color: rgba(245,239,226,.94);
}
/* La frase central abre y la entradilla viene detras: dos piezas en la serif seguidas
   necesitan aire entre ellas, o se leen como un solo bloque. */
.frase-central + .idea { margin-top: 16px; }
.cuerpo-story { margin-top: 14px; color: rgba(245,239,226,.78); }
/* La frase central: lo unico del concepto que se publica literal, y por eso se compone como
   una cita y no como un parrafo mas — filete al margen y serif, el mismo gesto con el que el
   estribillo se distingue de las estrofas en Lyrics. Una pieza, no dos lenguajes. */
.frase-central {
  font-family: Fraunces, serif; font-weight: 500; font-size: calc(var(--t) * 1.12);
  line-height: 1.45; color: rgba(245,239,226,.92);
  border-left: 2px solid var(--sw-acento, var(--sw-accent)); padding-left: 14px;
}

/* ── LYRICS ────────────────────────────────────────────────────────────────
   Libreto: cada estrofa es su propio bloque y no se parte entre columnas. El estribillo se
   marca con un filete al margen y la serif — es el bloque que se repite, no una eleccion. */
/* Columnas por ANCHO y no por numero: el navegador pone las que quepan segun el escenario, y
   asi en una pantalla grande la letra entera cabe sin scroll y en una pequena no se estrecha
   hasta romper los versos. */
.letra { column-gap: 40px; }
.sw-capa[data-ancho="ancho"] .letra { columns: 250px; }
/* El panel de la letra: estrecho y centrado, no ancho. Ya no hay columnas que llenar. */
.sw-capa[data-ancho="medio"] { width: min(560px, 52cqw); left: 50%; right: auto; transform: translateX(-50%); }
.estrofa {
  white-space: pre-wrap; break-inside: avoid; margin: 0 0 14px;
  line-height: 1.62; color: rgba(245,239,226,.82);
}
.estrofa[data-estribillo="true"] {
  font-family: Fraunces, serif; font-size: calc(var(--t) * 1.08);
  color: rgba(245,239,226,.96);
  border-left: 2px solid var(--sw-acento, var(--sw-accent)); padding-left: 14px;
}

/* ── SCORE ─────────────────────────────────────────────────────────────────
   Tres alturas: la nota global con su anillo, las dos parciales con medidor, y los generos
   como chips. */
.score-cabeza { display: flex; align-items: center; gap: 18px; margin-bottom: 4px; }
.anillo { position: relative; flex: none; width: 82px; aspect-ratio: 1; }
.anillo svg { width: 100%; height: 100%; display: block; }
.anillo b { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-family: Fraunces, serif; font-weight: 600; font-size: 25px; }
.score-nombre { font-family: Fraunces, serif; font-weight: 600; letter-spacing: .4px; }
.score-puesto { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; letter-spacing: 1.2px; color: rgba(245,239,226,.6); }
/* Se dice lo que es: una valoracion del propio archivo, no una critica. */
.score-aviso { margin-top: 4px; font-size: calc(var(--t) * .82); color: rgba(245,239,226,.5); }

.nota + .nota { margin-top: 13px; }
.nota-cabeza { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.nota-nombre { font-family: Fraunces, serif; font-weight: 600; font-size: var(--h); letter-spacing: .4px; }
.nota-cifra { font-family: Fraunces, serif; font-weight: 600; font-size: calc(var(--h) * 1.15); font-variant-numeric: tabular-nums; }

/* ---- el reproductor, cuando no caben los doce en una fila ---- */
/* El corte va por ANCHO, y esto es una correccion (Alex, 28 ago: «ha dejado de ser
   responsive»). Estas reglas nacieron dentro de `(max-width: 1040px) and
   (max-aspect-ratio: 1/1)`, que es donde vivia la vieja tira de iconos, y alli tenian
   sentido: la tira era una capsula aparte y podia irse a la esquina. Ahora que TODO esta en
   la pildora, depender de la proporcion es un error — una ventana estrecha pero APAISADA,
   que es lo que sale al reducir el navegador en un portatil, no cumplia `max-aspect-ratio`
   y nunca pasaba a dos filas.
   Medido en produccion antes de arreglarlo, con la ficha abierta: a 1440x900 la barra de
   progreso media 203px; a 640x480, 107; y a 480x420, SESENTA. Los nueve iconos ocupan 288px
   fijos y se comian el timeline entero.
   Los 700px salen de la cuenta: 9 iconos x 32 = 288, mas los dos puntos y los huecos son
   ~380px de controles que no se encogen, mas 52 de los dos relojes. Para que a la barra le
   queden 150px dignos hace falta una pildora de ~590, y la pildora es `min(680, 100vw - 56)`:
   590 + 56 = 646. Se redondea a 700 para no ir al limite. */
@media (max-width: 700px) {
  /* La miniatura del ORIGEN, algo mas ancha para que se lea (Alex, 29 ago) — pero sigue
     siendo secundaria: no llega al ancho del panel ni se pone al nivel de la obra. */
  .sw-origen img, .sw-origen-pie { max-width: 340px; }
  /* Y la ampliada se acerca a los bordes: en 390 px, 40 de margen a cada lado se comian una
     quinta parte de la foto. */
  .sw-foto-lightbox { padding: 16px; }
  .sw-foto-cerrar { top: 12px; right: 12px; }

  /* El reproductor movil tiene DOS estados (Alex, 28 ago):
       normal      play · tiempo · progreso · duracion · Spotify · letra · Mas
       desplegado  se abre una segunda linea ENCIMA, con narrativa, nota, legado, video,
                   limpio y cerrar.
     Aqui las filas dejan de ser `display: contents` y vuelven a ser filas. El
     `column-reverse` es lo que hace que la segunda crezca hacia ARRIBA: la pildora esta
     anclada por abajo, asi que lo que se anade empuja el borde superior. */
  .sw-controles { flex-direction: column-reverse; align-items: stretch; gap: 6px; width: 100%; }
  .sw-fila { display: flex; }
  .sw-fila-1 { gap: 4px; }
  /* La segunda linea reparte a lo ancho: seis botones y nada que compita por el sitio. */
  .sw-fila-2 { gap: 4px; justify-content: space-around; padding: 2px 4px 0; }
  .sw-controles:not([data-desplegado="true"]) .sw-fila-2 { display: none; }
  /* Aqui si existe: es lo que abre la segunda linea. */
  .sw-controles .sw-mas-btn { display: grid; margin-left: auto; }
  /* Los puntos separadores sobran cuando las filas ya separan los grupos. */
  .sw-fila .sw-sep { display: none; }
  /* Desplegada deja de ser una capsula: dos filas dentro de un radio de 999px dejarian las
     esquinas comiendose los iconos de arriba. */
  #reproductor:has(.sw-controles[data-desplegado="true"]) { border-radius: 24px; padding-top: 8px; }
  /* Y el rotulo de la obra se retira mientras esta abierta. En movil vive pegado al borde de
     abajo, asi que la segunda linea le pasaba por encima y le cortaba el titulo — medido con
     la barra a 84px de alto contra los 40 de siempre. Se apagan los mismos elementos que apaga
     el modo limpio: es la misma idea, dejar la obra sola. */
  body[data-desplegado="true"] .sw-cancion .sw-photo-song-title,
  body[data-desplegado="true"] .sw-cancion .sw-photo-place-time,
  body[data-desplegado="true"] .sw-cancion .sw-photo-estado,
  body[data-desplegado="true"] .sw-cancion .sw-photo-scene-code { opacity: 0; transition: opacity .25s ease; }
}

/* El medidor: la misma barra fina del reproductor. Un gesto que ya existe en la pantalla no
   se reinventa con otra forma. */
.nota-medidor { height: 3px; border-radius: 999px; background: rgba(245,239,226,.14); margin: 6px 0 7px; overflow: hidden; }
.nota-medidor i { display: block; height: 100%; border-radius: 999px; }
.nota p { color: rgba(245,239,226,.74); font-size: calc(var(--t) * .9); line-height: 1.5; }

@media (max-width: 860px) {
  :root { --t: 13px; --h: 17px; }
  .sw-capa, .sw-capa[data-ancho="corto"], .sw-capa[data-ancho="ancho"] {
    width: auto; left: 4.1667cqw; right: 4.1667cqw; transform: none;
  }
  .sw-capa[data-ancho="ancho"] .letra { column-count: 1; }
  .generos { grid-template-columns: 1fr; }
}

/* ---- por debajo de ~1040px el acordeón se gira (§18) ----
   Medido el 26 de agosto: a 390px la fila pedía 509 de ancho y tenía 334, y como va centrada
   lo que sobra se sale por los DOS lados — la escena publicada acababa en x = −147, fuera de
   la pantalla. La causa no es el ancho de la página: es que doce cápsulas con su ancho mínimo
   de 44px no caben, y el mínimo gana siempre a la aritmética del alto.
   Se gira el mismo objeto en vez de inventar otro (Alex, 26 ago): carrusel vertical, cápsulas
   tumbadas, la publicada fija arriba. Y ojo con una tentación: rotar NO hace que quepan —la
   misma cuenta en el otro eje da una tarjeta de 143px—, así que aquí sí se desplaza. Pero
   dentro de su propia caja: la página no se mueve. */
@media (max-width: 1040px) and (max-aspect-ratio: 1/1) {
  /* Fuera el logotipo grande y la pagina empieza por la obra (Alex, 26 ago). Medía 190px en
     una pantalla de 390 —la mitad— y la insignia se le montaba encima 56px. Lo primero que
     se lee pasa a ser «For one night», que es de lo que va la pagina. */
  /* La franja lleva las tres cosas: logotipo, album e idioma. El logotipo vuelve —pero a 96px,
     no a 190: en una pantalla de 390 aquello era la mitad del ancho— y la insignia grande se
     va, porque su trabajo lo hace ahora el desplegable (Alex, 26 ago). */
  .sw-header-logo { width: 96px; }
  .sw-header { min-height: 0; padding: 10px 16px 0; gap: 8px; }
  .sw-album-menu { display: block; margin-left: auto; }
  .sw-lang-btn { margin-left: 0; }
  .sw-badge-coverflow { display: none; }
  /* La insignia se sale del flujo y se posa en la esquina de la ficha. Sigue siendo el
     selector de album, no un adorno: se pulsa igual. */
  .sw-content-group { position: relative; gap: 0; }
  .sw-badge-track { width: 100%; }
  /* PANTALLA COMPLETA DE VERDAD (Alex, 26 ago). En PC la obra se encaja entera y sobra fondo
     arriba y abajo; aqui eso dejaba una tira de 219px en una pantalla de 844 —el 26 %— y el
     resto negro. Se hace al reves: manda el alto de la pantalla y se recortan los laterales.
     `dvh` y no `vh`: en el movil la barra del navegador aparece y desaparece, y con `vh` la
     obra se queda con un corte por debajo del pliegue. */
  .sw-cancion .sw-photo-stage { width: 100%; height: 100vh; height: 100dvh; aspect-ratio: auto; }
  /* Y se recorta POR DONDE DIGA LA OBRA, no siempre por el centro (Alex, 28 ago). De una
     16:9 a 390x844 se ve el 26 % central —416 px de 1600—, asi que una obra con el acento en
     un lateral lo perdia entero: en SW-0001 la luna se quedaba fuera por 112 px.
     `--sw-foco` lo pone la ficha de cada escena y sale del `foco_movil` de su scene.md. Sin
     el, 50 % — el centro, que es lo que hacia el navegador por su cuenta. */
  .sw-cancion img.sw-photo-image { object-fit: cover; object-position: var(--sw-foco, 50%) center; }
  /* Los rotulos, con la misma estructura que en PC —titulo y lugar·hora a la izquierda, codigo
     y fecha a la derecha— pero al cuerpo compacto y subidos por encima de la tira de iconos.
     Antes iban a 10,75cqh del suelo del escenario, que con la obra encajada eran 24px sobre su
     borde; ahora el escenario es la pantalla entera y esos mismos 10,75cqh caian a 90px del
     suelo, justo donde vive la tira. Se pisaban los tres.
     El pie son 140px: la tira empieza a 124 del suelo, asi que quedan 16 de aire. */
  /* Las dos medidas viven en `.sw-cancion` y no en el marco del rotulo: asi el panel de
     lectura, que es hermano y no hijo, puede pararse justo donde empiezan los rotulos.
     El pie baja de 140 a 70: los rotulos se posan justo encima del reproductor (Alex, 26 ago),
     que puede hacerse porque la tira de iconos se ha ido arriba y ya no ocupa esa banda. */
  .sw-cancion { --sw-dato: 11.6px; --sw-pie: 70px; }
  /* El logotipo, a la esquina de arriba a la izquierda. El SVG es un lienzo 16:9 completo con
     la firma dibujada en su sitio; con el escenario a 390x844 se encajaba centrado y la firma
     caia a media altura. Anclando el lienzo arriba, la firma cae donde tiene que caer. */
  .sw-cancion .sw-photo-brand {
    inset: auto; top: 0; left: 0; width: 100%; height: auto; aspect-ratio: 16 / 9;
  }
  .sw-cancion .sw-photo-song-title {
    font-size: 15px; left: 16px; max-width: calc(100% - 32px);
    bottom: calc(var(--sw-pie) + var(--sw-dato) * 1.45);
  }
  .sw-cancion .sw-photo-place-time { font-size: var(--sw-dato); bottom: var(--sw-pie); left: 16px; max-width: 44%; }
  .sw-cancion .sw-photo-estado { font-size: var(--sw-dato); bottom: var(--sw-pie); right: 16px; max-width: 52%; }
  .sw-cancion .sw-photo-scene-code {
    font-size: var(--sw-dato); right: 16px;
    bottom: calc(var(--sw-pie) + var(--sw-dato) * 1.45);
  }
  /* El panel se para por encima del titulo. En PC no hace falta —es estrecho y vive a la
     derecha, mientras los rotulos ocupan la esquina de abajo a la izquierda—, pero aqui va a
     todo el ancho y se los comia. Se calcula de las mismas dos medidas que ellos, no de una
     cifra suelta: si manana cambia el cuerpo del rotulo, el panel se aparta solo. */
  .sw-cancion .sw-capa {
    bottom: calc(var(--sw-pie) + var(--sw-dato) * 1.45 + 22px + 10px);
  }
  .sw-scene-accordion { padding: 0 16px; align-items: stretch; flex-direction: column; gap: 8px; }
  .sw-ficha-fija { display: block; flex: none; }
  /* `relative`, no `static`: el rotulo va dentro en absoluto y con `static` se anclaba al
     contenedor de la pagina — «For one night» aparecia suelto en mitad del fondo. */
  .sw-ficha-fija .sw-scene-card { position: relative; width: 100%; height: auto; aspect-ratio: 16 / 9; border-radius: 20px; }
  /* El reproductor, a plomo con las pills. Iba a 28px por lado y ellas a 16: doce pildoras
     alineadas y una decimotercera metida hacia dentro se ve enseguida.
     Y el hueco reservado baja de 88 a 68: la barra ocupa 40 mas los 20 del borde, asi que
     sobraban 28px de aire muerto entre la ultima pill y ella. */
  :root { --sw-player-space: 68px; }
  #reproductor { width: calc(100% - 32px); }
  .sw-scene-row {
    flex-direction: column; justify-content: flex-start;
    flex: 1 1 auto; height: auto; min-height: 0; gap: 8px;
    overflow-y: auto; overscroll-behavior: contain; scroll-snap-type: y proximity;
    scrollbar-width: none;
  }
  .sw-scene-row::-webkit-scrollbar { display: none; }
  .sw-scene-row > * { flex: 0 0 auto; width: 100%; scroll-snap-align: start; }
  /* La misma proporción de cápsula, del revés. */
  /* El radio, a la mitad (Alex, 26 ago): 40px en una capsula de 68px de alto la convertian
     en un ovalo. 20 mantiene la forma sin redondearla entera. */
  .sw-scene-card, .sw-scene-card--bloqueada {
    /* Alto fijo de 40px, no proporcion (Alex, 26 ago): tumbada a 358 de ancho, la proporcion
       de capsula daba 68 y la lista respiraba de mas. Con 40 caben trece en la misma caja.
       El `min-height` de 44 tiene que irse o gana el, que para eso es un minimo. */
    aspect-ratio: auto; min-width: 0; height: 40px; min-height: 0;
    border-radius: 20px;
  }
  /* Dentro de la lista, la que suena es una pildora mas y se queda en su puesto: la decima
     sigue siendo la decima. Lo que la nombra ahi es su titulo, no el rotulo sobre la obra
     —ese vive arriba, en la ficha fija, y aqui no cabria—. */
  .sw-scene-row .sw-scene-card[data-active="true"] {
    position: relative; aspect-ratio: auto; height: 40px; min-height: 0; border-radius: 20px;
  }
  .sw-scene-row .sw-scene-card[data-active="true"] .sw-photo-overlay-frame { display: none; }
  /* Y se comporta como las demas: la obra recortada, no encajada sobre fondo oscuro. Encajar
     una imagen 16:9 en una pildora de 40 dejaba una miniatura en medio de una franja negra. */
  .sw-scene-row .sw-scene-card[data-active="true"] {
    background-size: cover; background-color: transparent;
  }
}

/* Tumbada la cápsula, su rótulo ya no puede ir escrito de abajo arriba: el número y el estado
   caían los dos en el centro, uno encima del otro (medido: el estado quedaba en 21px de ancho).
   Se enderezan y se reparten el renglón — número a la izquierda, estado a la derecha— que es
   como se lee una pieza tumbada. */
@media (max-width: 1040px) and (max-aspect-ratio: 1/1) {
  .sw-scene-card-num {
    left: 24px; top: 50%; transform: translateY(-50%);
  }
  .sw-scene-card-estado {
    left: auto; right: 24px; bottom: 50%; transform: translateY(50%);
    writing-mode: horizontal-tb; max-height: none;
  }
  /* El título al vuelo de las publicadas: mismo sitio, sin girar. */
  .sw-scene-card-song { left: 56px; bottom: 50%; transform: translateY(50%); }
  .sw-scene-card-song-text { writing-mode: horizontal-tb; transform: none; max-height: none; max-width: 52cqw; }
  /* En una pantalla táctil no hay hover: si el nombre solo sale al pasar por encima, no sale
     nunca. Aquí se queda puesto. */
  .sw-scene-row .sw-scene-card .sw-scene-card-song { opacity: 1; }
}

/* Estrecho pero APAISADO —una tablet de 1024x768 tumbada, un movil de lado— no entra en el
   carrusel vertical: sin alto, la tarjeta se comia la caja entera y no quedaba ni una capsula
   a la vista. Peor que el problema que arregla. Ahi se queda en horizontal, y lo que falla se
   arregla en su origen: el suelo de 44px por capsula. Era el que rompia la aritmetica —a 1024
   la fila pedia 972 y tenia 968—, y no hacia falta: con 32 la propia formula da capsulas de
   43px y el minimo deja de mandar. */
@media (max-width: 1040px) and (min-aspect-ratio: 1/1) {
  :root { --sw-tira-min: 32px; }
}


/* Esto NO es cosa solo del carrusel vertical: la tarjeta es pequena en las dos ramas, y con
   ella se apretaba el rotulo. Por eso va suelto, sin condicion de orientacion. */
@media (max-width: 1040px) {
  /* La insignia se come el alto en pantalla estrecha: 174px de 844 (Alex, 26 ago). Toda la
     pieza cuelga de esta variable, asi que basta bajarla — no hay que tocar el carrusel. */
  :root { --sw-insignia-escala: .5; }
  /* Lo que va SOBRE la obra. El cuerpo lo fijaba el suelo del `clamp` —19px y 14px—, pensado
     para una tarjeta de 561px; en una de 358 los tres textos del renglón de abajo piden 403px
     y se montan unos sobre otros. Se baja el suelo y se pasan los desplazamientos a píxeles:
     el `cqh` de una tarjeta de 201px de alto da 15 y 22px, y con eso el título se comía la
     línea del lugar. Misma composición, a la escala que de verdad hay. */
  /* El renglon de arriba se separa por la ALTURA DEL DE ABAJO, no por una cifra fija: con 34px
     clavados el titulo rozaba `lugar · hora` en cuanto la tarjeta crecia a 768. */
  /* Solo la tarjeta del carrusel. La ficha a pantalla completa NO entra aqui: alli el rotulo ya
     estaba bien (Alex, 25 ago) y estas reglas se lo llevaban de 19 a 34px. */
  /* El titulo, al mismo cuerpo que el «For one night» de las pills: 15px FIJOS (Alex, 26 ago).
     Fijos y no un `clamp`, que es donde estaba la trampa: con `clamp(15px, 4.13cqw, ...)` los
     15 solo salian en una pantalla de 390 —donde yo lo comprobaba— y en una de 500 el titulo
     ya iba a 19,3. El de la pill no escala, asi que este tampoco.
     Los datos, en la proporcion que ya tenian entre ellos: 0,7724 del titulo, o sea 11,6. */
  .sw-scene-card .sw-photo-overlay-frame { --sw-dato: 11.6px; --sw-pie: 14px; }
  .sw-scene-card .sw-photo-song-title { font-size: 15px; left: 16px; max-width: calc(100% - 32px);
    bottom: calc(var(--sw-pie) + var(--sw-dato) * 1.45); }
  .sw-scene-card .sw-photo-place-time { font-size: var(--sw-dato); bottom: var(--sw-pie); left: 16px; max-width: 44%; }
  .sw-scene-card .sw-photo-estado { font-size: var(--sw-dato); bottom: var(--sw-pie); right: 16px; max-width: 52%; }
  .sw-scene-card .sw-photo-scene-code { font-size: var(--sw-dato); right: 16px;
    bottom: calc(var(--sw-pie) + var(--sw-dato) * 1.45); }
}
/* ── «Qué es Sunward» ──────────────────────────────────────────────────────────────────────
   No es una página nueva: es una escena más. Misma anatomía que la ficha —logotipo arriba a
   la izquierda, texto flotando encima de la obra, un bloque abajo a la izquierda y otro abajo
   a la derecha, todo en una pantalla y sin desplazar— salvo que en el sitio de la ilustración
   están la fotografía y la ilustración a la vez, separadas por una frontera que se mueve.
   Encargo de LINE del 4 de septiembre de 2026, aprobado por Alex; maqueta v7 llevada aquí.

   Las medidas vienen de la maqueta. Lo que NO viene de la maqueta son los colores y las
   familias tipográficas: ahí manda esta hoja, con los tokens que ya existen. */

.sw-quees {
  position: fixed; inset: 0; z-index: 40; overflow: hidden;
  background: #DEDACE;                 /* el papel de debajo mientras cargan las dos imágenes */
  color: #fff; font-family: Fraunces, Georgia, serif;
  touch-action: none;                  /* el arrastre es nuestro, no del navegador */
  cursor: ew-resize; user-select: none;
  --sw-quees-x: 50%;
  --sw-quees-pad: clamp(22px, 3.4vw, 54px);
  /* Lo mide el JS: es el alto real de la barra de reproducción, que vive FUERA de #sitio y
     sigue puesta aquí porque la música no se corta al entrar. Sin esto, el bloque de abajo a
     la derecha quedaba debajo de la barra en cuanto sonaba algo. */
  --sw-quees-pie: 0px;
}
.sw-quees:focus { outline: none; }
.sw-quees:focus-visible { outline: 2px solid rgba(255, 255, 255, .8); outline-offset: -4px; }

.sw-quees-capa { position: absolute; inset: 0; background-size: cover; background-position: center; }
.sw-quees-capa--foto { background-image: var(--sw-quees-foto); }
.sw-quees-capa--ilu { background-image: var(--sw-quees-ilu); clip-path: inset(0 0 0 var(--sw-quees-x)); }

/* Los mismos dos velos que lleva la ficha: sin ellos el texto blanco no se lee sobre un cielo. */
.sw-quees-velo {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(10, 9, 6, .54) 0%, rgba(10, 9, 6, .12) 22%, rgba(10, 9, 6, 0) 34%),
    linear-gradient(0deg, rgba(10, 9, 6, .62) 0%, rgba(10, 9, 6, 0) 42%);
}

.sw-quees-bar {
  position: absolute; top: 0; bottom: 0; left: var(--sw-quees-x); width: 1px; z-index: 4;
  background: rgba(255, 255, 255, .9); box-shadow: 0 0 0 1px rgba(0, 0, 0, .14);
}
.sw-quees-knob {
  position: absolute; top: 50%; left: var(--sw-quees-x); transform: translate(-50%, -50%); z-index: 6;
  width: clamp(40px, 3.4vw, 50px); aspect-ratio: 1; border-radius: 50%;
  background: rgba(242, 238, 228, .95); box-shadow: 0 2px 14px rgba(0, 0, 0, .3);
  display: flex; align-items: center; justify-content: center;
  font-family: "JetBrains Mono", ui-monospace, Menlo, monospace; font-size: 12px;
  color: var(--sw-ink); letter-spacing: -.06em;
}

.sw-quees-tag {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 5;
  font-family: "JetBrains Mono", ui-monospace, Menlo, monospace;
  font-size: clamp(8.5px, .72vw, 10px); letter-spacing: .2em;
  color: rgba(255, 255, 255, .92); text-shadow: 0 1px 6px rgba(0, 0, 0, .75);
}
.sw-quees-tag--l { left: var(--sw-quees-pad); }
.sw-quees-tag--r { right: var(--sw-quees-pad); }

.sw-quees-hdr {
  position: absolute; top: 0; left: 0; right: 0; z-index: 7;
  display: flex; align-items: center; gap: 14px;
  padding: clamp(16px, 2.4vh, 28px) var(--sw-quees-pad) 0;
}
.sw-quees-logo { width: clamp(112px, 11vw, 150px); filter: brightness(0) invert(1); opacity: .94; }

/* El enlace de la cabecera del álbum: mismo lenguaje que ES —mono, versalitas, subrayado fino—
   y el color de acento del álbum, como pidió Alex. Vive sólo en el álbum: dentro de la sección
   no hay rótulo de navegación, porque allí sería un enlace a donde ya estás. */
/* El `margin-left: auto` va aquí y NO en el botón de idioma, que ya lo trae de serie
   (`.sw-lang-btn`, arriba). Con los dos puestos, flexbox reparte el hueco libre ENTRE LOS DOS:
   el rótulo se quedaba flotando en mitad de la cabecera, pegado a la insignia, y el idioma se
   iba al extremo. Se ve en la captura de Alex del 6 de septiembre a las 00:24. Aquí se anula
   el del idioma **solo cuando va detrás de este rótulo**, para no tocar las demás cabeceras. */
.sw-quees-link + .sw-lang-btn { margin-left: 14px; }
.sw-quees-link {
  margin-left: auto; color: var(--sw-acento, var(--sw-accent));
  font-family: "JetBrains Mono", ui-monospace, Menlo, monospace;
  font-size: clamp(8.5px, .72vw, 10px); letter-spacing: .16em; text-transform: uppercase;
  background: none; border: 0; cursor: pointer; padding: 0 0 2px;
  border-bottom: 1px solid currentColor; line-height: 1.2;
  white-space: nowrap;
}
@media (max-width: 760px) {
  /* Aquí SÍ se parte en dos líneas, y es a propósito. Con `nowrap` la cabecera pedía 401 px
     en una pantalla de 390 y el sitio entero se desplazaba en horizontal —medido: 401/390 y
     401/360, y sin este enlace eran 390/390 y 360/360, así que el desbordamiento era de este
     rótulo y de nadie más—. Un sitio que se arrastra de lado en el móvil es peor defecto que
     un rótulo de dos líneas, así que el rótulo cede. El interlineado apretado y el centrado
     evitan que al partirse empuje el alto de la franja. */
  .sw-quees-link {
    white-space: normal; text-align: center; line-height: 1.1;
    letter-spacing: .1em; font-size: 8.5px;
  }
}
/* Por debajo de 400 px —un Galaxy S8 son 360— ni con dos líneas cabía: se pasaba 6 px y el
   sitio volvía a arrastrarse de lado. El rótulo cede espaciado y medio punto de cuerpo, que
   es lo único que sobra ahí. Medido a 360: 366/360 antes, 360/360 después. */
@media (max-width: 400px) {
  .sw-quees-link { letter-spacing: .04em; font-size: 8px; }
}

/* El botón de idioma es el del sitio, y aquí va sobre una fotografía: hereda el blanco. Y sin
   el rótulo de al lado, es él quien se separa del logotipo. */
.sw-quees .sw-lang-btn {
  margin-left: auto; color: rgba(255, 255, 255, .92);
  filter: drop-shadow(0 1px 5px rgba(0, 0, 0, .6));
}

/* Donde flotan los versos en la ficha. */
.sw-quees-titular {
  position: absolute; z-index: 7; left: var(--sw-quees-pad); top: clamp(96px, 17vh, 190px);
  max-width: min(52ch, 60vw); font-weight: 300; font-size: clamp(20px, 2.55vw, 40px);
  line-height: 1.14; letter-spacing: -.015em; text-shadow: 0 1px 14px rgba(0, 0, 0, .5);
}
.sw-quees-titular em { font-style: normal; color: rgba(255, 255, 255, .78); }

/* Abajo a la izquierda: donde va el título de la canción. */
.sw-quees-cartel {
  position: absolute; z-index: 7; left: var(--sw-quees-pad);
  bottom: calc(clamp(24px, 4.2vh, 46px) + var(--sw-quees-pie)); max-width: min(46ch, 58vw);
}
.sw-quees-cita {
  font-style: italic; font-weight: 300; font-size: clamp(16px, 1.75vw, 27px); line-height: 1.28;
  text-shadow: 0 1px 12px rgba(0, 0, 0, .55);
}
.sw-quees-ref {
  margin-top: clamp(9px, 1.4vh, 15px); font-family: "JetBrains Mono", ui-monospace, Menlo, monospace;
  font-size: clamp(8.5px, .7vw, 10px); letter-spacing: .16em; color: rgba(255, 255, 255, .72);
  text-shadow: 0 1px 6px rgba(0, 0, 0, .7);
}
.sw-quees-luego {
  margin-top: clamp(11px, 1.7vh, 19px); font-weight: 300;
  font-size: clamp(12.5px, 1.08vw, 16.5px); line-height: 1.4; color: rgba(255, 255, 255, .76);
  text-shadow: 0 1px 10px rgba(0, 0, 0, .6);
}

/* Abajo a la derecha: donde va el estado en la ficha. */
.sw-quees-fin {
  position: absolute; z-index: 7; right: var(--sw-quees-pad);
  bottom: calc(clamp(24px, 4.2vh, 46px) + var(--sw-quees-pie)); text-align: right;
  max-width: min(34ch, 42vw);
}
.sw-quees-fin p {
  font-weight: 300; font-size: clamp(14px, 1.32vw, 21px); line-height: 1.4;
  text-shadow: 0 1px 12px rgba(0, 0, 0, .55);
}
.sw-quees-ir {
  display: inline-block; margin-top: clamp(10px, 1.6vh, 18px);
  font-family: "JetBrains Mono", ui-monospace, Menlo, monospace;
  font-size: clamp(8.5px, .7vw, 10px); letter-spacing: .17em; text-transform: uppercase;
  color: rgba(255, 255, 255, .92); background: none; border: 0; cursor: pointer;
  border-bottom: 1px solid rgba(255, 255, 255, .4); padding: 0 0 3px;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .7);
}

/* En esta vista la página no se desplaza: cabe entera y el único gesto es horizontal.
   `overscroll-behavior` es lo que evita que el arrastre pelee con el gesto de volver atrás
   del navegador en móvil, junto con que la frontera nunca llegue al borde (3 % / 97 %). */
body[data-vista="quees"] { overflow: hidden; overscroll-behavior: none; }

@media (max-width: 760px) {
  .sw-quees-titular {
    top: clamp(84px, 14vh, 140px); max-width: none; right: var(--sw-quees-pad);
    font-size: clamp(19px, 5.4vw, 28px);
  }
  .sw-quees-cartel {
    max-width: none; right: var(--sw-quees-pad);
    bottom: calc(clamp(104px, 18.5vh, 168px) + var(--sw-quees-pie));
  }
  .sw-quees-cita { font-size: clamp(15px, 4.3vw, 21px); }
  .sw-quees-fin {
    left: var(--sw-quees-pad); right: var(--sw-quees-pad); text-align: left;
    bottom: calc(clamp(22px, 4vh, 34px) + var(--sw-quees-pie)); max-width: none;
  }
  .sw-quees-fin p { font-size: clamp(13px, 3.6vw, 18px); }
  .sw-quees-tag {
    top: calc(50% + clamp(34px, 6vh, 50px)); bottom: auto; transform: none;
    font-size: 8px; letter-spacing: .16em;
  }
}
