/* Receptor de Life Music: el modo ambiente en el TV.
   Todo en negro con luz de la caratula; tipografia de sala (se lee a tres
   metros); zona segura del 4 % por si el TV recorta el borde (overscan).
   Las transiciones son de opacidad y transform a proposito: son las unicas
   que un Chromecast viejo anima sin tirones. */

@font-face { font-family: "Geist"; font-style: normal; font-weight: 300 700; font-display: swap; src: url("/fuentes/geist.woff2") format("woff2"); }

:root {
  --texto: #F2F5F3;
  --texto-2: rgba(242, 245, 243, 0.62);
  --texto-3: rgba(242, 245, 243, 0.34);
  --verde: #34D399;
  --seguro: 4vmin;
  --display: "Google Sans", "Product Sans", "Segoe UI", Roboto, system-ui, sans-serif;
  --suave: cubic-bezier(0.2, 0.8, 0.2, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { width: 100%; height: 100%; overflow: hidden; background: #000; }
body { font-family: var(--display); color: var(--texto); -webkit-font-smoothing: antialiased; }

/* El reproductor de CAF tiene que existir para que el TV reproduzca, pero no se ve. */
cast-media-player { display: none; }

/* Fondo: un lienzo pequeno escalado a toda la pantalla. Sin filtros CSS a
   proposito: un blur de pantalla completa por fotograma era lo mas caro de la
   pagina en un TV flojo, y las luces ya son degradados suaves. */
#fondo {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0; width: 100vw; height: 100vh;
  image-rendering: auto;
}

#escena { position: fixed; top: 0; right: 0; bottom: 0; left: 0; padding: var(--seguro); }

.marca {
  position: absolute; top: var(--seguro); right: var(--seguro); z-index: 3;
  display: flex; align-items: center;
  font-size: 2.1vmin; font-weight: 600; letter-spacing: 0.02em; color: var(--texto-2);
}
.marca svg { height: 2.96vmin; width: 15.75vmin; overflow: visible; }

/* ── Bienvenida (sin cancion) ─────────────────────────────────────────── */
/* Identidad Pulso (maqueta aprobada por CG el 22-10-2026): carbon, Geist, Nova grande que espera contigo,
   el saludo por hora y «Listo para sonar» a 128 px; el estado abajo a la izquierda, con palabras. */
#bienvenida {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column;
  padding: 5vmin 8.9vmin;
  font-family: "Geist", "Segoe UI", Roboto, sans-serif; color: #F2F2EF; background: #0E0E0E;
  transition: opacity 700ms var(--suave), transform 700ms var(--suave), visibility 0s linear 700ms;
}
#escena.con-cancion #bienvenida { opacity: 0; transform: scale(1.06); visibility: hidden; }
#escena.vacia #bienvenida { opacity: 1; transform: none; visibility: visible; transition-delay: 0s; }
#escena.vacia > .marca { visibility: hidden; }
.bv-escena { -webkit-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; padding-bottom: 3.7vmin; }
.bv-escena .nova-tv { -webkit-flex: none; flex: none; width: 35.2vmin; height: 35.2vmin; margin: 0 5.9vmin 0 -2.8vmin; -webkit-animation: aparece 900ms var(--suave) both; animation: aparece 900ms var(--suave) both; }
#bienvenida .saludo { font-size: 4.26vmin; font-weight: 500; letter-spacing: -0.015em; animation: sube 700ms var(--suave) 250ms both; }
#bienvenida h1 { margin-top: 0.55vmin; font-size: 11.85vmin; line-height: 1; font-weight: 600; letter-spacing: -0.045em; animation: sube 700ms var(--suave) 380ms both; }
#bienvenida .saludo-estado { font-size: 2.96vmin; color: #A1A19D; transition: color 400ms; }
#bienvenida .saludo-estado.listo { color: #F2F2EF; }
/* Estado del arranque de Cast: para leerlo mirando el TV si algo falla; chico y tenue, abajo a la derecha. */
#bienvenida .estado { position: absolute; right: 8.9vmin; bottom: 5vmin; max-width: 50vw; text-align: right; font-size: 1.4vmin; color: #6E6E6A; word-break: break-word; }

@keyframes aparece { from { opacity: 0; transform: scale(0.6); } to { opacity: 1; transform: none; } }
@keyframes sube { from { opacity: 0; transform: translateY(2.4vmin); } to { opacity: 1; transform: none; } }
@keyframes respira { 0%, 100% { transform: scale(0.9); opacity: 0.7; } 50% { transform: scale(1.15); opacity: 1; } }

/* ── Ambiente (con cancion) ───────────────────────────────────────────── */
#ambiente {
  position: absolute; top: var(--seguro); right: var(--seguro); bottom: var(--seguro); left: var(--seguro);
  display: grid; grid-template-columns: 40fr 60fr; grid-gap: 6vmin; gap: 6vmin; align-items: center;
  transition: opacity 800ms var(--suave) 150ms, transform 800ms var(--suave) 150ms, visibility 0s linear 950ms;
}
#escena.vacia #ambiente { opacity: 0; transform: scale(0.96); visibility: hidden; }
#escena.con-cancion #ambiente { opacity: 1; transform: none; visibility: visible; }
#escena.sin-letra #ambiente { grid-template-columns: 1fr; justify-items: center; }
#escena.sin-letra #derecha { display: none; }

#izquierda { display: flex; flex-direction: column; align-items: flex-start; gap: 1.6vmin; min-width: 0; }
#escena.sin-letra #izquierda { align-items: center; text-align: center; }

#caratula-marco {
  position: relative; width: 52vmin; height: 52vmin; border-radius: 3vmin; overflow: hidden;
  background: #111; box-shadow: 0 3vmin 9vmin rgba(0,0,0,0.65);
  transition: transform 220ms ease-out;
}
/* Cada caratula nueva entra encima de la anterior y se funde; la vieja se retira despues. */
#caratula-marco .caratula {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; object-fit: cover; display: block;
  opacity: 1; transform: none;
  transition: opacity 800ms var(--suave), transform 800ms var(--suave);
}
#caratula-marco .caratula.entra { opacity: 0; transform: scale(1.06); }
#canvas { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 600ms; pointer-events: none; }
#caratula-marco.con-canvas #canvas { opacity: 1; }
#escena.pausa #caratula-marco { transform: scale(0.96); }

#titulo {
  font-size: 4.2vmin; font-weight: 700; letter-spacing: -0.02em; line-height: 1.1;
  max-width: 52vmin; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-top: 1vmin;
}
#artista { font-size: 2.6vmin; color: var(--texto-2); max-width: 52vmin; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Texto que cambia: sale hacia arriba, entra desde abajo (ponerTexto en receptor.js). */
#titulo, #artista { transition: opacity 240ms ease, transform 420ms var(--suave); }
#titulo.sale, #artista.sale { opacity: 0; transform: translateY(-0.8vmin); }
#titulo.entra, #artista.entra { opacity: 0; transform: translateY(1.2vmin); transition: none; }

#progreso { width: 52vmin; height: 0.5vmin; border-radius: 1vmin; background: rgba(255,255,255,0.16); overflow: hidden; margin-top: 0.6vmin; }
#progreso-barra { width: 0; height: 100%; background: var(--texto); border-radius: 1vmin; transition: width 400ms linear; }

/* Letra: la linea viva al centro, las demas se desvanecen hacia arriba y abajo. */
#derecha { position: relative; height: 84vh; min-width: 0; }
#letra-ventana { position: absolute; top: 0; right: 0; bottom: 0; left: 0; overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 22%, #000 78%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 22%, #000 78%, transparent 100%); }
/* Los paneles de vidrio solo existen en el tema Cristal. */
.vidrio { display: none; }
#letra { position: absolute; left: 0; right: 0; top: 50%; opacity: 1;
  transition: transform 420ms var(--suave), opacity 320ms ease; will-change: transform; }
#letra.oculta { opacity: 0; }
#letra .linea {
  font-size: 4.6vmin; font-weight: 700; line-height: 1.25; letter-spacing: -0.015em;
  color: var(--texto-3); padding: 1.2vmin 0;
  transition: color 300ms ease, transform 300ms ease, opacity 300ms ease;
  transform-origin: left center;
}
#letra .linea.viva { color: var(--texto); transform: scale(1.04); }
#letra .linea.pasada { color: var(--texto-3); }
#letra .linea .p { transition: color 120ms linear; }
#letra .linea.viva .p { color: rgba(242, 245, 243, 0.45); }
#letra .linea.viva .p.dicha { color: var(--texto); }
#sin-letra { display: none; font-size: 2.6vmin; color: var(--texto-3); }

/* TV vertical o pantallas raras: apilar. */
@media (orientation: portrait) {
  #ambiente { grid-template-columns: 1fr; grid-template-rows: auto 1fr; align-items: start; }
  #izquierda { align-items: center; text-align: center; }
  #derecha { height: 46vh; }
  #caratula-marco { width: 40vmin; height: 40vmin; }
}

/* ── Saludo de entrada (el de la app, al conectar el telefono) ─────────── */
/* Identidad Pulso (22-10): Nova habla con sus anillos junto al saludo por hora, y la frase del telefono en grande. */
#saludo-pantalla {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 5;
  display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column;
  padding: 5vmin 8.9vmin;
  font-family: "Geist", "Segoe UI", Roboto, sans-serif; color: #F2F2EF; background: #0E0E0E;
  opacity: 0; visibility: hidden;
  transition: opacity 500ms var(--suave), visibility 0s linear 500ms;
}
#saludo-pantalla.visible { opacity: 1; visibility: visible; transition-delay: 0s; }
.sp-escena { -webkit-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-justify-content: center; justify-content: center; padding-bottom: 5.6vmin; }
.sp-quien { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; margin-left: -2vmin; }
.sp-quien .nova-tv { -webkit-flex: none; flex: none; width: 17.6vmin; height: 17.6vmin; margin-right: 2.6vmin; }
#saludo-cabecera {
  font-size: 4.07vmin; font-weight: 500; letter-spacing: -0.01em; color: #A1A19D;
  transform: translateY(1.6vmin); transition: transform 520ms var(--suave);
}
#saludo-frase {
  margin-top: 2.6vmin; max-width: 144vmin; font-size: 12.6vmin; font-weight: 600; line-height: 1.02; letter-spacing: -0.045em;
  transform: translateY(1.6vmin); transition: transform 640ms var(--suave);
}
#saludo-pantalla.visible #saludo-cabecera, #saludo-pantalla.visible #saludo-frase { transform: none; }

/* ══ Temas ═══════════════════════════════════════════════════════════════
   El tema es una clase en <body>: tema-ambiente (el de siempre),
   tema-cristal y tema-escenario. Al cambiar, la escena se funde a negro y
   vuelve con el tema nuevo (receptor.js, ponerTema). */
#escena { transition: opacity 380ms var(--suave); }
#escena.cambiando-tema { opacity: 0; }

/* ── Cristal liquido ─────────────────────────────────────────────────────
   La receta del cristal de la app (la de Kyant): el fondo refractado por
   una lente, mas vivo que alrededor, con un tinte, el borde que brilla y un
   hilo de color en las orillas. El fondo refractado no es backdrop-filter
   (carisimo en un Chromecast): lo pinta receptor.js en el <canvas.vidrio>
   de cada panel a partir del lienzo del fondo, que es nuestro. */
body.tema-cristal #ambiente { grid-gap: 4vmin; gap: 4vmin; }
body.tema-cristal #izquierda,
body.tema-cristal #derecha {
  --radio-vidrio: 4.2vmin;
  position: relative;
  border-radius: var(--radio-vidrio);
  box-shadow:
    0 2.4vmin 7vmin rgba(0, 0, 0, 0.38),        /* profundidad */
    inset 0 0 0 1px rgba(255, 255, 255, 0.16),  /* canto */
    inset 0 1.5px 0 rgba(255, 255, 255, 0.42),  /* brillo de arriba */
    inset 0 -1px 0 rgba(255, 255, 255, 0.07);
  isolation: isolate;
}
body.tema-cristal .vidrio {
  display: block; position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%;
  border-radius: var(--radio-vidrio); z-index: -1;
}
/* El canto de luz: un borde que brilla fuerte en la esquina de arriba a la
   izquierda y en la de abajo a la derecha, y casi nada en medio, como el
   cristal de la app (un degradado recortado a un anillo de 1,5 px). El
   reflejo difuso de la superficie lo pinta receptor.js dentro del vidrio. */
body.tema-cristal #izquierda::before,
body.tema-cristal #derecha::before {
  content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0; border-radius: var(--radio-vidrio); pointer-events: none;
  padding: 1.5px;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.75) 0%, rgba(255, 255, 255, 0.10) 28%, rgba(255, 255, 255, 0.04) 55%, rgba(255, 255, 255, 0.38) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
/* Aberracion cromatica: rojo y cian desplazados en las orillas, muy sutil. */
body.tema-cristal.aberracion #izquierda::after,
body.tema-cristal.aberracion #derecha::after {
  content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0; border-radius: var(--radio-vidrio); pointer-events: none;
  box-shadow: inset 2px 1px 1px -1px rgba(255, 90, 110, 0.45), inset -2px -1px 1px -1px rgba(80, 210, 255, 0.45);
}
body.tema-cristal.sin-profundidad #izquierda,
body.tema-cristal.sin-profundidad #derecha {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16), inset 0 1.5px 0 rgba(255, 255, 255, 0.42);
}
body.tema-cristal #izquierda { padding: 3.2vmin; }
body.tema-cristal #caratula-marco { width: 46vmin; height: 46vmin; border-radius: 2.6vmin; box-shadow: 0 1.6vmin 4vmin rgba(0, 0, 0, 0.35); }
body.tema-cristal #titulo, body.tema-cristal #artista, body.tema-cristal #progreso { max-width: 46vmin; }
body.tema-cristal #progreso { width: 46vmin; }
body.tema-cristal #letra-ventana { top: 2vmin; right: 3.6vmin; bottom: 2vmin; left: 3.6vmin; }
body.tema-cristal #letra .linea { text-shadow: 0 0.2vmin 1.2vmin rgba(0, 0, 0, 0.25); }

/* ── Escenario ───────────────────────────────────────────────────────────
   Para fiestas: una sola linea, enorme, al centro, palabra a palabra; la
   siguiente, pequena debajo; la cancion en una esquina. El fondo golpea
   mas fuerte y hay un destello en cada beat (receptor.js). */
#escenario {
  position: absolute; top: var(--seguro); right: var(--seguro); bottom: var(--seguro); left: var(--seguro); display: none;
  flex-direction: column; align-items: center; justify-content: center; text-align: center;
  transition: opacity 800ms var(--suave) 150ms, transform 800ms var(--suave) 150ms, visibility 0s linear 950ms;
}
body.tema-escenario #ambiente { display: none; }
body.tema-escenario #escenario { display: flex; }
#escena.vacia #escenario { opacity: 0; transform: scale(0.96); visibility: hidden; }
#escena.con-cancion #escenario { opacity: 1; transform: none; visibility: visible; }

#esc-letra { position: relative; width: 88vw; height: 36vh; will-change: transform; }
.esc-linea {
  position: absolute; left: 0; right: 0; top: 50%;
  font-size: 8.6vmin; font-weight: 800; line-height: 1.12; letter-spacing: -0.025em;
  transform: translateY(-50%); opacity: 1;
  transition: transform 560ms var(--suave), opacity 420ms ease;
}
.esc-linea.entra { transform: translateY(-20%) scale(0.94); opacity: 0; transition: none; }
.esc-linea.sale { transform: translateY(-110%) scale(0.96); opacity: 0; }
.esc-linea .p { color: rgba(242, 245, 243, 0.30); transition: color 110ms linear, text-shadow 160ms linear; }
.esc-linea .p.dicha { color: var(--texto); text-shadow: 0 0 3.2vmin rgba(var(--acento, 52, 211, 153), 0.65); }
.esc-linea.sin-palabras { color: var(--texto); text-shadow: 0 0 3.2vmin rgba(var(--acento, 52, 211, 153), 0.5); }
.esc-linea.titulo { font-size: 9.6vmin; }
#esc-siguiente {
  margin-top: 2vmin; max-width: 80vw; min-height: 4vmin;
  font-size: 3.4vmin; font-weight: 600; color: var(--texto-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: opacity 300ms ease;
}
#esc-info {
  position: absolute; left: 0; bottom: 0;
  display: flex; align-items: center; max-width: 46vw;
  padding: 1.4vmin 2.4vmin 1.4vmin 1.4vmin; border-radius: 2.6vmin; text-align: left;
  background: rgba(0, 0, 0, 0.28); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.10);
}
#esc-caratula { margin-right: 2vmin; width: 10vmin; height: 10vmin; border-radius: 1.6vmin; object-fit: cover; background: #111; flex: none; }
#esc-textos { min-width: 0; }
#esc-titulo { font-size: 2.8vmin; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#esc-artista { font-size: 2.2vmin; color: var(--texto-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#esc-progreso { margin-top: 1vmin; width: 26vmin; height: 0.4vmin; border-radius: 1vmin; background: rgba(255, 255, 255, 0.16); overflow: hidden; }
#esc-barra { width: 0; height: 100%; background: var(--texto); transition: width 400ms linear; }

#destello {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(ellipse at 50% 45%, rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0) 65%);
}
body:not(.tema-escenario) #destello { display: none; }

/* Modo ligero (TV flojo): sin sombras de brillo en el texto. */
body.ligero .esc-linea .p.dicha, body.ligero .esc-linea.sin-palabras, body.ligero #letra .linea { text-shadow: none; }

/* ── Cristal en la GPU (cristal.js) ──────────────────────────────────────
   Con WebGL, el lienzo dibuja la caratula, las luces y el vidrio con su
   refraccion, canto y sombra: los paneles HTML quedan transparentes y solo
   llevan el contenido. Sin WebGL se queda el vidrio 2D de arriba. */
#fondo-cristal { position: fixed; top: 0; right: 0; bottom: 0; left: 0; width: 100vw; height: 100vh; opacity: 0; pointer-events: none; transition: opacity 500ms var(--suave); }
body.tema-cristal.gl.con-cancion #fondo-cristal { opacity: 1; }
body.tema-cristal.gl .vidrio { display: none; }
body.tema-cristal.gl #izquierda, body.tema-cristal.gl #derecha { box-shadow: none; }
body.tema-cristal.gl #izquierda::before, body.tema-cristal.gl #derecha::before,
body.tema-cristal.gl #izquierda::after, body.tema-cristal.gl #derecha::after { display: none; }

/* ── Vinilo ──────────────────────────────────────────────────────────────
   El disco gira a 33⅓ con la caratula de etiqueta; arranca y se frena como
   un plato de verdad (receptor.js), y el brazo baja al sonar y se levanta en
   pausa. El reflejo no gira: la luz de la sala esta quieta y el disco pasa
   por debajo. Letra en serif, tonos crema, grano y vineta calidos. */
#vinilo, #vinilo-grano { display: none; }
body.tema-vinilo { --texto: #F4E9D8; --texto-2: rgba(244, 233, 216, 0.62); --texto-3: rgba(244, 233, 216, 0.30); }
body.tema-vinilo #caratula-marco { display: none; }
body.tema-vinilo #vinilo { display: block; position: relative; width: 56vmin; height: 56vmin; margin: 0 4vmin 1vmin 0; }
#disco {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; border-radius: 50%;
  background:
    radial-gradient(circle closest-side, rgba(0, 0, 0, 0) 0 38%, rgba(255, 255, 255, 0.06) 38.5% 39%, rgba(0, 0, 0, 0) 39.5% 97%, rgba(255, 255, 255, 0.05) 97.5% 98%, rgba(0, 0, 0, 0) 98.5%),
    repeating-radial-gradient(circle closest-side, #0c0c0d 0 0.55%, #19191b 0.55% 1.1%);
  box-shadow: 0 3vmin 8vmin rgba(0, 0, 0, 0.6), inset 0 0 0 0.35vmin #050505;
  will-change: transform;
}
#etiqueta { position: absolute; left: 32%; top: 32%; width: 36%; height: 36%; border-radius: 50%; object-fit: cover; background: #3a2a1a; }
#disco .eje { position: absolute; left: 48.9%; top: 48.9%; width: 2.2%; height: 2.2%; border-radius: 50%; background: #d8d8d8; box-shadow: 0 0 0 0.25vmin rgba(0, 0, 0, 0.45); }
#brillo-disco {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from 25deg, rgba(255, 255, 255, 0) 0deg, rgba(255, 255, 255, 0.11) 28deg, rgba(255, 255, 255, 0) 64deg, rgba(255, 255, 255, 0) 190deg, rgba(255, 255, 255, 0.08) 222deg, rgba(255, 255, 255, 0) 256deg);
  -webkit-mask: radial-gradient(circle closest-side, transparent 0 37%, #000 38%);
  mask: radial-gradient(circle closest-side, transparent 0 37%, #000 38%);
}
#brazo {
  position: absolute; right: -5vmin; top: -3vmin; width: 9vmin; height: 44vmin;
  transform-origin: 62% 7%; transform: rotate(-26deg);
  transition: transform 1400ms var(--suave);
  filter: drop-shadow(0 1.2vmin 1.4vmin rgba(0, 0, 0, 0.5));
}
body.tema-vinilo.sonando #brazo { transform: rotate(-3deg); }
#brazo .base { position: absolute; left: 34%; top: 0; width: 5.6vmin; height: 5.6vmin; margin-left: -1.6vmin; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #f2f2f2, #9a9a9a 55%, #5c5c5c); }
#brazo .barra { position: absolute; left: 58%; top: 2.6vmin; width: 0.9vmin; height: 34vmin; border-radius: 0.5vmin;
  background: linear-gradient(90deg, #7a7a7a, #eaeaea 45%, #8d8d8d); }
#brazo .capsula { position: absolute; left: 50%; top: 35vmin; width: 2.6vmin; height: 5vmin; border-radius: 0.5vmin;
  background: linear-gradient(90deg, #2b2b2b, #5a5a5a 50%, #2b2b2b); transform: rotate(18deg); }
body.tema-vinilo #titulo { font-family: "Noto Serif", Georgia, "Times New Roman", serif; font-weight: 600; letter-spacing: 0; }
body.tema-vinilo #artista { font-style: italic; }
body.tema-vinilo #letra .linea { font-family: "Noto Serif", Georgia, "Times New Roman", serif; font-weight: 600; letter-spacing: 0; }
body.tema-vinilo #vinilo-grano {
  display: block; position: fixed; top: 0; right: 0; bottom: 0; left: 0; pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 50%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.55) 100%),
    linear-gradient(rgba(255, 150, 60, 0.07), rgba(255, 150, 60, 0.07)),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 .86 0 0 0 0 .66 0 0 0 .10 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ── Galeria ─────────────────────────────────────────────────────────────
   Como un cuadro en la pared: la caratula flotando despacio, el titulo fino
   y una sola linea de letra, sobre la misma caratula difuminada a pantalla
   completa. Sin luces animadas: es el tema mas liviano. */
#galeria-fondo { position: fixed; top: 0; right: 0; bottom: 0; left: 0; display: none; overflow: hidden; }
body.tema-galeria #galeria-fondo { display: block; }
body.tema-galeria #fondo, body.tema-nocturno #fondo { visibility: hidden; }
#galeria-fondo .gf {
  position: absolute; left: -8%; top: -8%; width: 116%; height: 116%;
  opacity: 0; transition: opacity 1400ms ease;
  filter: blur(3vmin) saturate(1.3) brightness(0.52);
}
#galeria-fondo .gf.visible { opacity: 1; }
#galeria, #nocturno {
  position: absolute; top: var(--seguro); right: var(--seguro); bottom: var(--seguro); left: var(--seguro); display: none;
  flex-direction: column; align-items: center; justify-content: center; text-align: center;
  transition: opacity 800ms var(--suave) 150ms, visibility 0s linear 950ms;
}
body.tema-galeria #ambiente, body.tema-nocturno #ambiente { display: none; }
body.tema-galeria #galeria, body.tema-nocturno #nocturno { display: flex; }
#escena.vacia #galeria, #escena.vacia #nocturno { opacity: 0; visibility: hidden; }
#escena.con-cancion #galeria, #escena.con-cancion #nocturno { opacity: 1; visibility: visible; }
#gal-caratula {
  width: 54vmin; height: 54vmin; border-radius: 1.8vmin; object-fit: cover; background: #111;
  box-shadow: 0 4vmin 11vmin rgba(0, 0, 0, 0.55);
  animation: flotar 9s ease-in-out infinite;
}
#escena.pausa #gal-caratula { animation-play-state: paused; }
@keyframes flotar { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-1.3vmin); } }
#gal-titulo { margin-top: 4.4vmin; max-width: 80vw; font-size: 4.8vmin; font-weight: 300; letter-spacing: 0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#gal-artista { margin-top: 0.8vmin; font-size: 2.2vmin; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--texto-2); }
#gal-linea, #noc-linea { transition: opacity 380ms ease; }
#gal-linea.cambia, #noc-linea.cambia { opacity: 0; }
#gal-linea { margin-top: 2.8vmin; min-height: 3.4vmin; max-width: 70vw; font-size: 2.7vmin; font-style: italic; color: var(--texto-2); }

/* ── Nocturno ────────────────────────────────────────────────────────────
   Negro de verdad (en un OLED, pixeles apagados), la hora grande, la fecha y
   la linea que suena. Todo se corre un poco cada minuto para no marcar la
   pantalla (receptor.js). */
body.tema-nocturno .marca { visibility: hidden; }
#nocturno { transition: opacity 800ms var(--suave) 150ms, transform 2400ms ease, visibility 0s linear 950ms; }
#noc-hora { font-size: 21vmin; font-weight: 200; line-height: 1; letter-spacing: -0.02em; color: rgba(242, 245, 243, 0.86); font-variant-numeric: tabular-nums; }
#noc-hora small { font-size: 0.22em; font-weight: 400; letter-spacing: 0.04em; margin-left: 1.4vmin; color: rgba(242, 245, 243, 0.5); }
#noc-fecha { margin-top: 1.6vmin; font-size: 2.6vmin; letter-spacing: 0.04em; color: rgba(242, 245, 243, 0.42); }
#noc-fecha::first-letter { text-transform: uppercase; }
#noc-linea { margin-top: 7vmin; min-height: 5vmin; max-width: 80vw; font-size: 3.8vmin; font-weight: 500; color: rgba(242, 245, 243, 0.72); }
#noc-cancion { margin-top: 1.8vmin; font-size: 2vmin; color: rgba(242, 245, 243, 0.32); }

/* ── Paisaje real (temas pro) ────────────────────────────────────────────
   Un video real a pantalla completa (receptor.js funde dos copias en el
   empalme). Se amplia un poco para que no se vean los bordes del clip, y
   una sombra abajo deja leer la cancion sin tapar el paisaje. */
#paisaje { position: fixed; top: 0; right: 0; bottom: 0; left: 0; display: none; overflow: hidden; background: #000; }
body.tema-atardecer #paisaje { display: block; }
body.tema-atardecer #fondo { visibility: hidden; }
#paisaje .pj {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; object-fit: cover;
  transform-origin: 50% 45%; /* el zoom de cada clip lo pone receptor.js */
  opacity: 0; transition: opacity 1600ms linear;
}
#paisaje .pj.visible { opacity: 1; }
#paisaje .pj-sombra {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 3; pointer-events: none;
  background:
    linear-gradient(to top, rgba(0, 0, 0, 0.74) 0%, rgba(0, 0, 0, 0.42) 24%, rgba(0, 0, 0, 0) 52%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0.28) 0%, rgba(0, 0, 0, 0) 16%);
}

/* ── Atardecer ───────────────────────────────────────────────────────────
   Como un reproductor de sala: el paisaje manda; abajo a la izquierda la
   caratula, el titulo y el artista; debajo, la barra a todo lo ancho con
   los tiempos; encima, la linea de letra que suena. */
#atardecer {
  position: absolute; top: var(--seguro); right: var(--seguro); bottom: var(--seguro); left: var(--seguro); padding: 0 2vmin 1vmin; display: none;
  flex-direction: column; justify-content: flex-end;
  transition: opacity 900ms var(--suave) 150ms, visibility 0s linear 1050ms;
  text-shadow: 0 0.3vmin 2.4vmin rgba(0, 0, 0, 0.45);
}
body.tema-atardecer #ambiente { display: none; }
body.tema-atardecer #atardecer { display: flex; }
#escena.vacia #atardecer { opacity: 0; visibility: hidden; }
#escena.con-cancion #atardecer { opacity: 1; visibility: visible; transition-delay: 0s; }
#atd-linea {
  min-height: 4.4vmin; max-width: 72vw; margin-bottom: 3.2vmin;
  font-size: 3.6vmin; font-weight: 500; line-height: 1.25; color: rgba(255, 246, 236, 0.92);
  transition: opacity 380ms ease;
}
#atd-linea.cambia { opacity: 0; }
#atd-info { display: flex; align-items: center; }
#atd-caratula {
  width: 12vmin; height: 12vmin; margin-right: 2.6vmin; flex: none; border-radius: 1.1vmin; object-fit: cover; background: rgba(255, 255, 255, 0.08);
  box-shadow: 0 1.2vmin 4vmin rgba(0, 0, 0, 0.5);
}
#atd-textos { min-width: 0; }
#atd-titulo {
  max-width: 70vw; font-size: 5.4vmin; font-weight: 700; letter-spacing: -0.015em; line-height: 1.1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#atd-artista { margin-top: 0.7vmin; font-size: 2.6vmin; font-weight: 500; color: rgba(255, 246, 236, 0.74); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#atd-fila { display: flex; align-items: center; margin-top: 3.4vmin; font-size: 1.9vmin; font-weight: 500; color: rgba(255, 246, 236, 0.78); font-variant-numeric: tabular-nums; }
#atd-tiempo, #atd-duracion { min-width: 5vmin; }
#atd-duracion { text-align: right; }
#atd-progreso { flex: 1; margin: 0 2vmin; height: 0.55vmin; border-radius: 0.3vmin; background: rgba(255, 255, 255, 0.24); overflow: hidden; }
#atd-barra { width: 0%; height: 100%; border-radius: inherit; background: rgba(255, 250, 244, 0.94); transition: width 260ms linear; }
#escena.pausa #atd-fila { opacity: 0.55; }

/* ── Liviano (22-10-2026, pedido de CG) ─────────────────────────────────
   Para TV sencillos: el diseño de Ambiente sin nada pesado. Sin el lienzo de luces (no se redibuja), sin
   video de fondo, sin mascara de degradado en la letra, sin sombras ni escalas: un color plano tomado de
   la caratula, la caratula, el titulo, la barra y la letra. Solo transiciones de opacidad y un desplazamiento. */
body.tema-liviano { background: #0E0E0E; background: rgb(var(--fondo-liviano, 14, 14, 14)); transition: background-color 1.2s linear; }
body.tema-liviano #fondo, body.tema-liviano #destello, body.tema-liviano #canvas { display: none; }
body.tema-liviano #ambiente { transition: opacity 400ms linear, visibility 0s linear 400ms; }
body.tema-liviano #escena.vacia #ambiente { transform: none; }
body.tema-liviano #caratula-marco { width: 40vmin; height: 40vmin; box-shadow: none; transition: none; }
body.tema-liviano #escena.pausa #caratula-marco { transform: none; }
body.tema-liviano #caratula-marco .caratula { transition: opacity 400ms linear; }
body.tema-liviano #caratula-marco .caratula.entra { transform: none; }
body.tema-liviano #titulo, body.tema-liviano #artista { max-width: 40vmin; transition: opacity 240ms linear; }
body.tema-liviano #titulo.sale, body.tema-liviano #artista.sale, body.tema-liviano #titulo.entra, body.tema-liviano #artista.entra { transform: none; }
body.tema-liviano #progreso { width: 40vmin; max-width: 40vmin; height: 0.6vmin; }
body.tema-liviano #progreso-barra { transition: none; }
body.tema-liviano #derecha { height: 64vh; }
body.tema-liviano #letra-ventana { -webkit-mask-image: none; mask-image: none; }
body.tema-liviano #letra { top: 30%; transition: transform 300ms ease-out; will-change: auto; }
/* Sin mascara, la letra no se corta a medias: se ve la linea que suena y las tres que vienen; las cantadas se van. */
body.tema-liviano #letra .linea { transition: opacity 200ms linear; transform: none; text-shadow: none; }
body.tema-liviano #letra .linea.pasada, body.tema-liviano #letra .linea.viva ~ .linea ~ .linea ~ .linea ~ .linea { opacity: 0; }
body.tema-liviano #letra .linea.viva { transform: none; }
body.tema-liviano #letra .linea .p { transition: none; }

/* ── Tocadiscos (pro) ────────────────────────────────────────────────────
   La foto manda; la escena va en pixeles de la foto y #td-marco la escala
   para cubrir la pantalla (receptor.js). La caratula es un circulo que gira
   dentro de #td-etiqueta, aplanado a la elipse medida en la foto; encima, la
   luz del papel multiplicada y el eje por delante. */
#tocadiscos { position: fixed; top: 0; right: 0; bottom: 0; left: 0; display: none; overflow: hidden; background: #0b0705; }
body.tema-tocadiscos #tocadiscos { display: block; }
body.tema-tocadiscos #fondo { visibility: hidden; }
#td-marco { position: absolute; left: 50%; top: 50%; transform-origin: 50% 50%; opacity: 0; transition: opacity 1200ms ease; }
#tocadiscos.listo #td-marco { opacity: 1; }
#td-escena { position: absolute; left: 0; top: 0; }
#td-foto { position: absolute; left: 0; top: 0; width: 100%; height: 100%; }
#td-etiqueta { position: absolute; width: 200px; height: 200px; border-radius: 50%; overflow: hidden; transform-origin: 50% 50%; }
#td-caratula {
  display: block; width: 100%; height: 100%; border-radius: 50%; object-fit: cover;
  transition: opacity 300ms ease;
}
#td-caratula.cambia, #td-caratula:not([src]) { opacity: 0; }
#td-sombreado { position: absolute; mix-blend-mode: multiply; }
#td-eje { position: absolute; }
#td-luz {
  position: absolute; border-radius: 50%; mix-blend-mode: screen; opacity: 0.25; pointer-events: none;
  background: radial-gradient(circle, rgba(255, 176, 92, 0.55) 0%, rgba(255, 150, 70, 0.18) 45%, rgba(255, 140, 60, 0) 70%);
}
#td-polvo { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; pointer-events: none; }
#tocadiscos .td-sombra {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; pointer-events: none;
  background: linear-gradient(to left, rgba(8, 4, 2, 0.55) 0%, rgba(8, 4, 2, 0.25) 30%, rgba(8, 4, 2, 0) 46%);
}

body.tema-tocadiscos #ambiente { display: none; }
#td-ui { position: absolute; top: var(--seguro); right: var(--seguro); bottom: var(--seguro); left: var(--seguro); display: none; transition: opacity 900ms var(--suave) 150ms, visibility 0s linear 1050ms; }
body.tema-tocadiscos #td-ui { display: block; }
#escena.vacia #td-ui { opacity: 0; visibility: hidden; }
#escena.con-cancion #td-ui { opacity: 1; visibility: visible; transition-delay: 0s; }
#td-letra {
  position: absolute; left: 59vw; right: 1vw; top: 50%; transform: translateY(-50%);
  color: rgba(255, 241, 222, 0.97);
}
#td-linea {
  font-size: 6.4vmin; font-weight: 700; line-height: 1.12; letter-spacing: -0.01em;
  text-shadow: 0 0 2.2vmin rgba(255, 170, 80, 0.55), 0 0.3vmin 1.2vmin rgba(0, 0, 0, 0.5);
  transition: opacity 360ms ease, transform 360ms var(--suave);
}
#td-linea span { opacity: 0.42; transition: opacity 260ms ease; }
#td-linea span.dicha { opacity: 1; }
#td-siguiente {
  margin-top: 2.6vmin; font-size: 3vmin; font-weight: 600; line-height: 1.25; color: rgba(255, 236, 210, 0.42);
  text-shadow: 0 0.3vmin 1.2vmin rgba(0, 0, 0, 0.5);
  transition: opacity 360ms ease;
}
#td-linea.cambia { opacity: 0; transform: translateY(-1vmin); }
#td-siguiente.cambia { opacity: 0; }
#td-info { position: absolute; right: 1vw; bottom: 0.5vmin; width: 30vw; text-align: right; text-shadow: 0 0.3vmin 1.2vmin rgba(0, 0, 0, 0.6); }
#td-titulo { font-size: 2.5vmin; font-weight: 700; color: rgba(255, 241, 222, 0.92); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#td-artista { margin-top: 0.4vmin; font-size: 2vmin; font-weight: 500; color: rgba(255, 236, 210, 0.6); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#td-progreso { margin-top: 1.4vmin; margin-left: auto; width: 100%; height: 0.45vmin; border-radius: 0.3vmin; background: rgba(255, 236, 210, 0.2); overflow: hidden; }
#td-barra { width: 0%; height: 100%; background: rgba(255, 228, 190, 0.9); transition: width 260ms linear; }
#escena.pausa #td-progreso { opacity: 0.5; }

/* ── Navegadores viejos (1.3.3) ──────────────────────────────────────────
   El navegador del TV Hisense (VIDAA) es un Chrome viejo: no entendia inset
   (por eso esta hoja ya no lo usa: top/right/bottom/left) ni gap en flex
   (Chrome < 84). receptor.js lo detecta y pone html.sin-gap (y html.sin-grid
   si tampoco hay grid, Chrome < 57); aqui van los mismos espacios con
   margenes. Con ?compat=viejo se fuerzan las dos para probar en un PC. */
.sin-gap #bienvenida > * + * { margin-top: 1.2vmin; }
.sin-gap #bienvenida .saludo-estado { margin-top: 2.6vmin; }
.sin-gap #titulo { margin-top: 2.6vmin; }
.sin-gap #artista { margin-top: 1.6vmin; }
.sin-gap #progreso { margin-top: 2.2vmin; }
.sin-grid #ambiente { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; gap: 0; }
.sin-grid #izquierda { -webkit-flex: 40 1 0%; flex: 40 1 0%; margin-right: 6vmin; }
.sin-grid #derecha { -webkit-flex: 60 1 0%; flex: 60 1 0%; }
.sin-grid body.tema-cristal #izquierda { margin-right: 4vmin; }
.sin-grid #escena.sin-letra #ambiente { -webkit-justify-content: center; justify-content: center; }
.sin-grid #escena.sin-letra #izquierda { -webkit-flex: none; flex: none; margin-right: 0; }
@media (orientation: portrait) {
  .sin-grid #ambiente { -webkit-flex-direction: column; flex-direction: column; }
  .sin-grid #izquierda { -webkit-flex: none; flex: none; width: 100%; margin: 0 0 6vmin; }
  .sin-grid #derecha { width: 100%; }
}

/* ── TV con navegador (lifemusic.app/tv): enlace por codigo o QR ──────────
   Identidad Pulso (maqueta aprobada por CG el 22-10-2026, Brand/maquetas/2026-10-22-receptor-tv):
   carbon para la sala de noche, Geist, Nova recibe y mira el codigo, el codigo grande en dos grupos,
   el QR claro sobre hueso. Medidas de la maqueta (1920 x 1080) pasadas a vmin (1vmin = 10,8 px).
   Sin desenfoques ni animaciones de pantalla completa: va en TV flojos. Sin inset, sin gap y con
   prefijos -webkit-: esta parte la tiene que pintar bien hasta un navegador de TV muy viejo. */
#enlace {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 30; overflow: hidden;
  display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column;
  padding: 5vmin 8.9vmin;
  font-family: "Geist", "Segoe UI", Roboto, sans-serif; color: #F2F2EF;
  background: #0E0E0E;
  opacity: 1; transition: opacity 600ms ease, visibility 0s linear 0s;
}
#enlace.oculto { opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 600ms ease, visibility 0s linear 600ms; }

/* Cabecera: el logo «la nota es el pulso» con TV al lado, y el estado del servidor dicho con palabras. */
.enl-cabecera { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: space-between; justify-content: space-between; min-height: 5.2vmin; }
.marca-tv { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; }
.marca-tv svg { height: 4.26vmin; width: 22.6vmin; overflow: visible; }
.marca-tv span { margin-left: 1.5vmin; font-size: 3.7vmin; font-weight: 600; letter-spacing: -0.02em; color: #A1A19D; }
.enl-servidor { font-size: 2.4vmin; color: #A1A19D; }
.enl-servidor.mal { color: #FFB49A; }

/* Cuerpo: Nova, los pasos y el codigo a la izquierda; el QR a la derecha. */
.enl-cuerpo { -webkit-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; }
.enlace-texto { -webkit-flex: 1 1 auto; flex: 1 1 auto; min-width: 0; }
.enl-anfitriona { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; }
.enl-anfitriona .nova-tv { -webkit-flex: none; flex: none; width: 22.2vmin; height: 22.2vmin; margin: 0 3.7vmin 0 -1.3vmin; }
.enl-dice { max-width: 61vmin; font-size: 3.5vmin; line-height: 1.28; letter-spacing: -0.014em; color: #F2F2EF; }
.enl-dice b { font-weight: 600; }
.enl-pasos { margin: 4.1vmin 0 0; padding: 0; list-style: none; }
.enl-pasos li { display: -webkit-flex; display: flex; -webkit-align-items: baseline; align-items: baseline; font-size: 2.87vmin; line-height: 1.3; }
.enl-pasos li + li { margin-top: 0.93vmin; }
.enl-pasos li > span { -webkit-flex: none; flex: none; width: 2vmin; margin-right: 1.7vmin; font-weight: 600; color: #A1A19D; }
.enl-pasos b { font-weight: 600; }
/* El codigo justo debajo del paso 3: 216 px, en dos grupos de 3, sin fichas. */
.enl-clave { display: inline-block; margin-top: 2vmin; }
.enl-codigo { display: -webkit-flex; display: flex; min-height: 20vmin; font-size: 20vmin; line-height: 1; font-weight: 600; letter-spacing: 0.03em; color: #F2F2EF; }
.enl-codigo span { -webkit-animation: enl-entra 0.5s both; animation: enl-entra 0.5s both; }
.enl-codigo span + span { margin-left: 5.9vmin; -webkit-animation-delay: 0.08s; animation-delay: 0.08s; }
@-webkit-keyframes enl-entra { from { opacity: 0; -webkit-transform: translateY(1.6vmin); } }
@keyframes enl-entra { from { opacity: 0; transform: translateY(1.6vmin); } }
.enl-vigencia { margin-top: 3.1vmin; }
.enl-vigencia.oculto { visibility: hidden; }
.enl-barra { display: block; height: 0.56vmin; border-radius: 0.3vmin; background: rgba(242, 242, 239, 0.14); overflow: hidden; }
.enl-barra i { display: block; height: 100%; width: 100%; border-radius: 0.3vmin; background: #F2F2EF; transition: width 1s linear; }
#enl-vence { display: block; margin-top: 1.5vmin; font-size: 2.5vmin; color: #A1A19D; }
#enl-vence b { font-weight: 600; color: #F2F2EF; }
.enlace-estado { min-height: 3vmin; margin-top: 2vmin; font-size: 2.5vmin; color: #F2F2EF; }
.enlace-nota { margin-top: 0.6vmin; font-size: 2vmin; color: #A1A19D; }

/* El QR: lo unico claro de la pantalla, para que la camara lo lea siempre; no mas grande, para no encandilar. */
.enlace-qr-marco { -webkit-flex: none; flex: none; margin: 0 0 0 13vmin; text-align: center; }
.enl-qr-caja { width: 40.7vmin; height: 40.7vmin; border-radius: 2.8vmin; background: #F5F5F3; display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center; }
#enlace-qr { display: block; width: 34.7vmin; height: 34.7vmin; }
.enlace-qr-marco figcaption { margin-top: 2.4vmin; font-size: 2.3vmin; color: #A1A19D; white-space: nowrap; }
.enlace-compat { font-size: 1.76vmin; color: #6E6E6A; }

/* Nova en el TV (nova-tv.js): respira con CSS, sin bucle de animacion; al hablar se ven sus anillos. */
.nova-tv svg { display: block; width: 100%; height: 100%; overflow: visible; }
.nova-tv .nova-cuerpo { -webkit-transform-origin: 100px 100px; transform-origin: 100px 100px; -webkit-animation: nova-respira 4.6s ease-in-out infinite; animation: nova-respira 4.6s ease-in-out infinite; }
.nova-tv .nova-anillos { opacity: 0; -webkit-transform-origin: 100px 100px; transform-origin: 100px 100px; transition: opacity 300ms ease; }
.nova-tv .nova-habla .nova-anillos { opacity: 1; -webkit-animation: nova-voz 1.1s ease-in-out infinite; animation: nova-voz 1.1s ease-in-out infinite; }
.nova-tv .nova-habla .nova-aro { opacity: 0; }
@-webkit-keyframes nova-respira { 50% { -webkit-transform: scale(1.025); } }
@keyframes nova-respira { 50% { transform: scale(1.025); } }
@-webkit-keyframes nova-voz { 50% { -webkit-transform: scale(1.06); opacity: 0.6; } }
@keyframes nova-voz { 50% { transform: scale(1.06); opacity: 0.6; } }
body.ligero .nova-tv .nova-cuerpo, body.ligero .nova-tv .nova-anillos { -webkit-animation: none; animation: none; }

/* Activar (Pulso, 22-10): Nova mira el boton; un solo boton con el foco puesto y la razon debajo. */
#activar {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 40;
  display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column;
  padding: 5vmin 8.9vmin;
  font-family: "Geist", "Segoe UI", Roboto, sans-serif; color: #F2F2EF; background: #0E0E0E;
}
#activar.oculto { display: none; }
.act-escena { -webkit-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center; padding-bottom: 5.2vmin; }
.act-escena .nova-tv { width: 27.8vmin; height: 27.8vmin; }
#activar-boton {
  display: -webkit-inline-flex; display: inline-flex; -webkit-align-items: center; align-items: center;
  margin-top: 3.7vmin; min-height: 10vmin; padding: 0 5.6vmin; border: 0; border-radius: 5vmin; cursor: pointer;
  font: inherit; font-size: 3.9vmin; font-weight: 600; letter-spacing: -0.01em;
  color: #F2F2EF; background: transparent; box-shadow: inset 0 0 0 2px rgba(242, 242, 239, 0.32);
}
#activar-boton svg { width: 4.07vmin; height: 4.07vmin; margin-right: 1.7vmin; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* El foco del control: relleno hueso, letra carbon y un aro hueso separado (se ve desde el sofa). */
#activar-boton:focus { outline: none; color: #111111; background: #F5F5F3; box-shadow: 0 0 0 0.55vmin #0E0E0E, 0 0 0 0.93vmin #F5F5F3; }
.act-nota { margin-top: 3.7vmin; font-size: 2.78vmin; color: #A1A19D; }

/* Mandos del control (Pulso, 22-10): circulos de 88 px en carbon al 78 %, abajo a la derecha. El que tiene el
   foco se abre en pastilla hueso con su nombre y un aro hueso separado. Fondo solido, sin desenfoque. */
#mandos-tv { display: none; }
body.modo-tv #mandos-tv { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; position: fixed; right: 8.9vmin; bottom: 5vmin; z-index: 35; opacity: 0; transition: opacity 400ms ease; }
body.modo-tv #escena.vacia ~ #mandos-tv, body.modo-tv.mandos #mandos-tv, body.modo-tv.enlazando #mandos-tv { opacity: 1; }
.boton-ico {
  position: relative; height: 8.15vmin; min-width: 8.15vmin; margin-left: 1.85vmin; padding: 0; border: 0; border-radius: 4.07vmin; cursor: pointer;
  display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center;
  font-family: "Geist", "Segoe UI", Roboto, sans-serif; font-size: 3.15vmin; font-weight: 600; letter-spacing: -0.01em;
  color: #F2F2EF; background: rgba(14, 14, 14, 0.78);
}
.boton-ico svg { width: 3.5vmin; height: 3.5vmin; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.boton-ico .etiqueta { display: none; margin-left: 1.5vmin; white-space: nowrap; }
.boton-ico:focus, .boton-ico:hover { outline: none; padding: 0 4.07vmin; color: #111111; background: #F5F5F3; box-shadow: 0 0 0 0.55vmin rgba(14, 14, 14, 0.78), 0 0 0 0.93vmin #F5F5F3; }
.boton-ico:focus .etiqueta, .boton-ico:hover .etiqueta { display: inline; }

/* Aviso corto abajo al centro (1.3.3): p. ej., si el navegador no deja pantalla completa. */
.tv-aviso {
  position: fixed; left: 50%; bottom: 7vmin; z-index: 50; max-width: 80vw;
  -webkit-transform: translateX(-50%); transform: translateX(-50%);
  padding: 1.6vmin 3vmin; border-radius: 10vmin; text-align: center;
  font-family: "Geist", "Segoe UI", Roboto, sans-serif; font-size: 2.4vmin; font-weight: 500; color: #F2F2EF; background: #171717; border: 1px solid rgba(242, 242, 239, 0.14);
  box-shadow: 0 2vmin 5vmin rgba(0, 0, 0, 0.5);
  opacity: 0; transition: opacity 300ms ease; pointer-events: none;
}
.tv-aviso.visible { opacity: 1; }
/* Diagnostico en pantalla (?diag=1): para fotografiarlo; no sale nada del TV. */
#tv-diag {
  position: fixed; top: 3vmin; left: 3vmin; z-index: 60; max-width: 72vw; max-height: 92vh; overflow: hidden;
  padding: 2vmin 2.4vmin; border-radius: 1.6vmin;
  font-family: monospace; font-size: 1.8vmin; line-height: 1.45; color: #E6F4EC; white-space: pre-wrap; word-wrap: break-word;
  background: rgba(0, 0, 0, 0.9); border: 1px solid rgba(52, 211, 153, 0.5);
}

/* Dialogos del TV (1.3.2; Pulso, 22-10): la musica se oscurece con una capa solida (sin desenfoque) y la
   pregunta va en una tarjeta carbon de 920 px. El foco arranca en la opcion que no rompe nada (tv.js). */
.tv-capa {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 45;
  display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center;
  background: rgba(10, 10, 10, 0.8);
}
.tv-capa.oculto { display: none; }
.tv-dialogo {
  width: 85.2vmin; padding: 5.9vmin 6.7vmin 5.6vmin; border-radius: 3vmin; text-align: left;
  font-family: "Geist", "Segoe UI", Roboto, sans-serif; color: #F2F2EF;
  background: #171717; box-shadow: inset 0 0 0 1px rgba(242, 242, 239, 0.08);
  -webkit-animation: enl-entra 0.35s both; animation: enl-entra 0.35s both;
}
.tv-dialogo-ico { width: 6.7vmin; height: 6.7vmin; }
.tv-dialogo-ico svg { width: 100%; height: 100%; fill: none; stroke: #F2F2EF; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.tv-dialogo.alerta .tv-dialogo-ico svg { stroke: #FF6B3D; }
.tv-dialogo h2 { margin: 2.6vmin 0 0; font-size: 5.37vmin; line-height: 1.05; font-weight: 600; letter-spacing: -0.035em; color: #F2F2EF; }
.tv-dialogo p { margin: 2vmin 0 0; font-size: 3.06vmin; line-height: 1.4; color: #A1A19D; }
.tv-dialogo p b { font-weight: 600; color: #F2F2EF; }
.tv-dialogo-acciones { display: -webkit-flex; display: flex; margin-top: 4.8vmin; }
.tv-dialogo-acciones button {
  min-height: 8.15vmin; margin: 0 2.6vmin 0 0; padding: 0 4.07vmin; border: 0; border-radius: 4.07vmin; cursor: pointer;
  font: inherit; font-size: 3.15vmin; font-weight: 600; letter-spacing: -0.01em; color: #F2F2EF;
  background: transparent; box-shadow: inset 0 0 0 2px rgba(242, 242, 239, 0.32);
}
.tv-dialogo-acciones button:focus { outline: none; color: #111111; background: #F5F5F3; box-shadow: 0 0 0 0.55vmin #171717, 0 0 0 0.93vmin #F5F5F3; }
.tv-dialogo-acciones button[hidden] { display: none; }

/* Sin video H.264: el Atardecer se queda con un cielo pintado, quieto. */
body.sin-video #paisaje {
  background: #2A1A2E;
  background: linear-gradient(180deg, #1C2748 0%, #6B3F6E 38%, #D9746A 58%, #F2B26B 66%, #3A2433 67%, #140E18 100%);
}

/* Pantalla vertical (alguien abre /tv en un celular o una tablet parada): uno debajo del otro. */
@media (orientation: portrait) {
  #enlace { overflow-y: auto; padding: 5vmin 6vmin; }
  .enl-cuerpo { -webkit-flex-direction: column; flex-direction: column; -webkit-justify-content: center; justify-content: center; -webkit-flex: none; flex: none; margin-top: 6vmin; }
  .enlace-texto { -webkit-flex: none; flex: none; width: 100%; margin: 0 0 6vmin; }
  .enl-dice { font-size: 4.4vmin; }
  .enl-pasos li { font-size: 4vmin; }
  .enl-codigo { font-size: 16vmin; min-height: 16vmin; }
  #enl-vence, .enlace-estado { font-size: 3.2vmin; }
  .enlace-qr-marco { margin: 0; }
  .enl-qr-caja { width: 62vmin; height: 62vmin; }
  #enlace-qr { width: 54vmin; height: 54vmin; }
  .enlace-qr-marco figcaption, .enl-servidor { font-size: 3vmin; }
  .enlace-compat { font-size: 2.6vmin; }
  .tv-dialogo { width: 88vmin; }
}
