/* =============================================================================
   EL MENÚ PRINCIPAL
   La casa a pantalla completa y, encima, la columna de lo que se puede hacer.
   Ver client/js/ui/menu.js.

   TRES CAPAS Y EN ESTE ORDEN, que es de lo que depende que se lea:
     1. la ilustración, con su deriva lenta
     2. un velo que la oscurece por la izquierda y por arriba
     3. la interfaz, que va quieta

   La 2 no es un adorno: la ilustración tiene farolas encendidas y hierba clara,
   y un texto blanco encima de eso no se lee. El velo es lo que compra el
   contraste sin tener que meter la interfaz en cajas opacas.
============================================================================= */

/* LA CAPA ES OPACA DESDE EL PRIMER FOTOGRAMA; LO QUE ENTRA ES LO DE DENTRO.
   El desvanecido estaba en la capa entera, y eso significaba medio segundo de
   menú translúcido con el juego debajo: al arrancar, justo debajo hay montado el
   cuartel —hace falta una sala para que exista un mundo— y se veía asomar
   durante un segundo, con su muñeco y todo, antes de que el menú acabara de
   entrar. Con el fondo puesto desde el principio, ahí abajo no se ve nada nunca:
   lo que se desvanece es el contenido. */
.menu {
  position: fixed;
  inset: 0;
  z-index: 180;
  overflow: hidden;
  background: #05040a;
}
.menu > * {
  opacity: 0;
  transition: opacity 420ms var(--ease-out, cubic-bezier(.22, 1, .36, 1));
}
.menu[data-on='true'] > * { opacity: 1; }
.menu[hidden] { display: none; }

/* --- El cursor del menú ------------------------------------------------------ */

/* ES UNA IMAGEN, NO UN ELEMENTO. Los dibujos están en client/css/tokens.css y
   los pinta el sistema operativo: van a la velocidad del ratón y no cuestan un
   fotograma. Aquí hay paneles con desenfoque por detrás, y un cursor hecho de
   elementos animados obligaba a recomponer media pantalla en cada movimiento.
   Sigue siendo el punto de este juego —no la flecha de Windows— y encima de algo
   pulsable el aro se abre y se enciende. */
.menu, .menu * { cursor: var(--cursor-punto); }
.menu a,
.menu label,
.menu [role='button'],
.menu button:not([disabled]) { cursor: var(--cursor-pulsable); }
/* Salvo donde se escribe: ahí la barrita del sistema dice dónde va a caer la
   letra, y eso un punto no lo dice. */
.menu input:not([type='range']),
.menu textarea { cursor: text; }

/* --- 1. La ilustración ------------------------------------------------------ */

.menu-escena { position: absolute; inset: 0; }

/* `cover` y centrada. La imagen es 1536x1024 (3:2) y las pantallas son más
   anchas, así que se recorta por arriba y por abajo — que es donde solo hay
   bosque y carretera. Se escala un pelín de más (1.06) para que la deriva no
   descubra los bordes. */
/* LA CÁMARA. El fondo no está quieto: se mete despacio, se va a la derecha, se
   va a la izquierda y vuelve, como una cámara plantada en un trípode que alguien
   dejó grabando la casa. Antes era una deriva en línea recta de cuarenta y seis
   segundos y de ida y vuelta, y eso no se lee como una cámara: se lee como una
   imagen que se estira.

   SON DOS MOVIMIENTOS A LA VEZ Y NO UNO, porque una cámara de verdad hace dos
   cosas: el recorrido —lento, largo, con sus paradas en las esquinas— y el
   temblor de quien la sujeta, que es diminuto y va a otro ritmo. Con solo el
   primero parece un pase de diapositivas; con los dos, parece una señal.

   VAN EN `scale`, `translate` y `rotate` SUELTOS y no en un `transform`: son
   propiedades independientes, así que dos animaciones distintas pueden llevar
   cada una la suya sin pisarse. Metidas en un `transform` compartido, la segunda
   animación borraría a la primera.

   Y LOS DOS CICLOS NO CUADRAN a propósito —setenta y ocho segundos contra
   nueve—: si cuadraran, el conjunto se repetiría igual cada minuto y pico y el
   ojo lo cazaría. Así no vuelve a pasar por el mismo sitio en un buen rato. */
.menu-fondo {
  position: absolute;
  inset: 0;
  scale: 1.06;
  animation: menu-camara 78s ease-in-out infinite,
             menu-pulso 9s ease-in-out infinite alternate;
}

/* LA LÁMINA Y SU LIENZO, uno encima del otro y con el mismo encuadre. La imagen
   era un `background` del contenedor y ha tenido que salir a ser un `img`: el
   glitch pinta la imagen en un lienzo, y para eso necesita un elemento del que
   leerla. La lámina se queda debajo como respaldo — es lo que se ve mientras el
   lienzo no está listo, y lo que se queda si el glitch no llega a arrancar. */
.menu-fondo-img,
.menu-fondo canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 46%;
}
.menu-fondo[data-glitch='true'] .menu-fondo-img { opacity: 0; }
.menu-fondo canvas {
  opacity: 0;
  transition: opacity 700ms ease;
}
.menu-fondo canvas[data-on='true'] { opacity: 1; }

/* EL RECORRIDO. Se mete, se va a un lado, se va al otro y vuelve a empezar. El
   ciclo se cierra donde empezó —de 100 % a 0 % el mismo sitio— para que no haya
   ningún salto al reiniciarse: con `alternate` el recorrido se veía ir y volver
   por el mismo camino, que es lo que delataba que era una animación.

   El margen es el 6 % del `scale` de salida, así que ningún paso puede pasarse:
   con un 2 % de traslación y un 13 % de acercamiento, el borde de la lámina no
   llega a asomar ni en la esquina más forzada. */
@keyframes menu-camara {
  0%   { scale: 1.06; translate: 0 0; }
  22%  { scale: 1.10; translate: -1.5% -0.6%; }
  46%  { scale: 1.13; translate: 0.3% -1.3%; }
  72%  { scale: 1.09; translate: 1.6% -0.4%; }
  100% { scale: 1.06; translate: 0 0; }
}

/* Y EL TEMBLOR DE LA MANO: una décima de grado a un lado y al otro. Suena a
   nada y es lo que separa «una foto que se acerca» de «alguien está grabando
   esto». Más de eso y el fondo marea. */
@keyframes menu-pulso {
  from { rotate: -0.13deg; }
  to   { rotate: 0.13deg; }
}

/* --- 2. El velo ------------------------------------------------------------- */

/* Tres degradados sumados, cada uno con su trabajo:
     · de la izquierda, para la columna de botones
     · de arriba, para el logotipo y la ficha
     · uno general muy flojo, para bajar el brillo de las farolas */
.menu-velo {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(4, 3, 10, .94) 0%, rgba(4, 3, 10, .8) 26%, rgba(4, 3, 10, .1) 52%, transparent 70%),
    linear-gradient(180deg, rgba(4, 3, 10, .82) 0%, transparent 30%, transparent 74%, rgba(4, 3, 10, .68) 100%),
    radial-gradient(ellipse 90% 80% at 50% 50%, transparent 40%, rgba(4, 3, 10, .5) 100%);
  pointer-events: none;
}

/* --- 3. La interfaz --------------------------------------------------------- */

/* Rejilla de dos columnas y tres filas. El hueco central queda VACÍO a propósito:
   es donde está la casa, y es lo único que hay que mirar aquí. */
.menu-rejilla {
  position: relative;
  height: 100%;
  display: grid;
  grid-template-columns: minmax(300px, 25vw) 1fr;
  grid-template-rows: auto 1fr auto;
  gap: clamp(16px, 2.4vh, 30px) 24px;
  padding: clamp(20px, 3.4vh, 40px) clamp(22px, 3vw, 46px);
  align-items: start;
}
/* HACE FALTA, aunque parezca redundante: el atributo `hidden` del navegador vale
   `display: none`, y cualquier `display` que se ponga en una regla lo pisa. Sin
   esta línea, abrir la pantalla de la noche dejaba la portada del menú encima y
   las dos apiladas, con el menú midiendo el doble de alto que la pantalla. */
.menu-rejilla[hidden] { display: none; }

/* El sello y la ficha comparten la fila de arriba. */
.menu-sello { grid-column: 1; grid-row: 1; }
.menu-ficha { grid-column: 2; grid-row: 1; justify-self: end; }
.menu-botones { grid-column: 1; grid-row: 2; align-self: center; }

/* --- El sello --------------------------------------------------------------- */

/* EL SELLO FLOTA. Es un fantasma: quedarse clavado en la esquina como un logo
   corporativo es lo único que podía hacer mal.

   DOS ANIMACIONES ENCADENADAS y no una: primero entra —eso ya estaba— y después
   se pone a flotar, para siempre. El retraso de la segunda es exactamente lo que
   dura la primera, así que empieza justo cuando la otra acaba y no se pisan. Va
   en `translate` suelto por lo mismo que el fondo (ver más arriba): así la
   entrada puede seguir usando `transform` sin que se estorben.

   Y EL RESPLANDOR RESPIRA CON ÉL. Un fantasma que se mueve con la sombra
   clavada detrás parece un recorte de papel; con el brillo subiendo y bajando
   con el vaivén, parece que la luz sale de él. */
.menu-marca {
  display: block;
  width: min(300px, 22vw);
  height: auto;
  filter: drop-shadow(0 0 34px rgba(168, 244, 37, .26));
  animation: menu-entra 620ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both,
             menu-flota 6.4s 620ms ease-in-out infinite;
}

@keyframes menu-flota {
  0%, 100% {
    translate: 0 0;
    filter: drop-shadow(0 0 34px rgba(168, 244, 37, .26));
  }
  50% {
    translate: 0 -7px;
    filter: drop-shadow(0 6px 44px rgba(168, 244, 37, .38));
  }
}

.menu-version {
  margin: 10px 0 0 4px;
  display: flex;
  align-items: center;
  gap: 9px;
  font: 500 10px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-faint, #6e678c);
  animation: menu-entra 620ms 120ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both;
}
/* La etiqueta de acceso anticipado, en su píldora. No se esconde: quien entra
   tiene que saber en qué se está metiendo antes de encontrarse el primer fallo. */
.menu-version-t {
  padding: 4px 8px;
  border: 1px solid rgba(157, 107, 255, .4);
  border-radius: 99px;
  color: var(--violet, #9d6bff);
  letter-spacing: .12em;
}

/* --- Los botones ------------------------------------------------------------ */

.menu-botones {
  display: grid;
  gap: 9px;
  width: 100%;
  max-width: 380px;
}

.menu-b {
  position: relative;
  display: grid;
  grid-template-columns: 46px 1fr;
  align-items: center;
  gap: 14px;
  padding: 13px 16px;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 12px;
  background: rgba(14, 10, 28, .62);
  backdrop-filter: blur(7px);
  color: inherit;
  cursor: pointer;
  transition: transform 180ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              background 180ms ease, border-color 180ms ease;
  animation: menu-entra 520ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both;
}

/* Se desplaza a la DERECHA al pasar por encima, no se hace más grande. Crecer
   mueve a los vecinos y hace que la columna baile; desplazarse deja todo lo
   demás donde estaba. */
.menu-b:hover:not([disabled]),
.menu-b:focus-visible {
  transform: translateX(9px);
  background: rgba(24, 17, 46, .82);
  border-color: rgba(157, 107, 255, .5);
}
.menu-b:active:not([disabled]) { transform: translateX(9px) scale(.985); }

/* EL PRINCIPAL SE VE DISTINTO DE LEJOS. Si los seis botones son iguales, quien
   entra por primera vez tiene que leerlos todos para saber por dónde se empieza.
   Con uno en violeta, no. */
.menu-b[data-principal='true'] {
  border-color: rgba(157, 107, 255, .55);
  background: linear-gradient(100deg, rgba(91, 47, 184, .78), rgba(40, 22, 84, .7));
  box-shadow: 0 10px 34px rgba(91, 47, 184, .3);
}
.menu-b[data-principal='true']:hover,
.menu-b[data-principal='true']:focus-visible {
  border-color: rgba(190, 150, 255, .8);
  background: linear-gradient(100deg, rgba(110, 60, 214, .9), rgba(52, 28, 104, .8));
}

.menu-b[disabled] { cursor: default; opacity: .5; }

.menu-b-icono {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 10px;
  color: var(--lime, #a8f425);
  background: rgba(168, 244, 37, .1);
  box-shadow: inset 0 0 0 1px rgba(168, 244, 37, .2);
}
.menu-b[data-principal='true'] .menu-b-icono {
  color: #fff;
  background: rgba(255, 255, 255, .14);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
}

.menu-b-texto { display: grid; gap: 2px; min-width: 0; }
.menu-b-t {
  font: 700 15px/1.2 Rubik, system-ui, sans-serif;
  letter-spacing: .05em;
  color: var(--ink, #f4f2ff);
}
.menu-b-p {
  font: 400 11.5px/1.3 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* «PRONTO»: se dice, no se disimula. */
.menu-b-pronto {
  position: absolute;
  top: 9px;
  right: 11px;
  padding: 3px 7px;
  border: 1px solid rgba(255, 196, 71, .35);
  border-radius: 99px;
  font: 700 8.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .12em;
  color: var(--amber, #ffc447);
}

/* --- La ficha --------------------------------------------------------------- */

.menu-ficha {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 16px 10px 10px;
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 14px;
  background: rgba(14, 10, 28, .62);
  backdrop-filter: blur(7px);
  animation: menu-entra 620ms 180ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both;
}
.menu-ficha:empty { display: none; }

.menu-cara {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 11px;
  font: 700 19px/1 Rubik, system-ui, sans-serif;
  color: #0a0714;
  background: linear-gradient(160deg, var(--tono, #9d6bff), rgba(0, 0, 0, .35));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
}

.menu-datos { display: grid; gap: 3px; min-width: 118px; }
.menu-nombre {
  margin: 0;
  font: 600 14px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink, #f4f2ff);
}
.menu-nivel {
  margin: 0;
  font: 500 10px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint, #6e678c);
}
.menu-xp {
  height: 3px;
  border-radius: 99px;
  overflow: hidden;
  background: rgba(255, 255, 255, .1);
}
.menu-xp > i { display: block; height: 100%; background: var(--violet, #9d6bff); }

.menu-dinero {
  padding-left: 14px;
  border-left: 1px solid rgba(255, 255, 255, .1);
}
.menu-dinero-n {
  font: 700 15px/1 Rubik, system-ui, sans-serif;
  color: var(--lime, #a8f425);
}

@keyframes menu-entra {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* --- Pantallas apretadas ---------------------------------------------------- */

/* Bajas: los botones se estrechan y la frase de debajo se va. Antes de quitarla
   se probó a encogerla, y una frase de nueve píxeles no la lee nadie: mejor no
   estar que estar y no servir. */
@media (max-height: 640px) {
  .menu-botones { gap: 6px; max-width: 330px; }
  .menu-b { padding: 9px 13px; grid-template-columns: 36px 1fr; gap: 11px; }
  .menu-b-icono { width: 36px; height: 36px; }
  .menu-b-icono svg { width: 19px; height: 19px; }
  .menu-b-t { font-size: 13.5px; }
  .menu-b-p { display: none; }
  .menu-marca { width: min(210px, 18vw); }
}

/* Estrechas: la ficha baja a la fila de abajo y se pega a la izquierda, debajo
   de los botones. Encogerla en su esquina la dejaba pisando el logotipo. */
@media (max-width: 820px) {
  .menu-rejilla { grid-template-columns: 1fr; grid-template-rows: auto auto 1fr; }
  .menu-sello, .menu-botones, .menu-ficha { grid-column: 1; }
  .menu-ficha { grid-row: 2; justify-self: start; }
  /* SE QUEDAN ESTRECHOS, no se estiran. Sin tope, cada botón se convertía en una
     franja de setecientos píxeles con dos palabras a la izquierda y la etiqueta
     de PRONTO perdida en la otra punta: se leía como una tabla, no como un menú. */
  .menu-botones { grid-row: 3; align-self: start; max-width: 440px; }
  .menu-velo {
    background:
      linear-gradient(180deg, rgba(4, 3, 10, .92) 0%, rgba(4, 3, 10, .78) 55%, rgba(4, 3, 10, .5) 100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .menu-fondo { animation: none; }
  .menu-marca, .menu-version, .menu-b, .menu-ficha { animation: none; }
  .menu-b { transition: background 180ms ease, border-color 180ms ease; }
  .menu-b:hover:not([disabled]), .menu-b:focus-visible { transform: none; }
}

/* =============================================================================
   EL CUADRO DEL CENTRO
   Los dos pasos de salir a un contrato: la casa y el equipo. Van en una caja
   centrada sobre la misma ilustración del menú — no es otra pantalla, es lo
   mismo con algo delante, y por eso el fondo ni cambia ni se recarga.
   Ver client/js/ui/menu-noche.js y menu-equipo.js.
============================================================================= */

.noc-cuadro {
  width: min(920px, 92vw);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* Y lo que no quepa se desplaza aquí dentro. Antes esto no hacía falta porque
     el cuadro se estiraba sin límite; ahora que su fila no crece, hace falta. */
  overflow-y: auto;
  scrollbar-width: thin;
  padding: clamp(16px, 2.4vh, 26px) clamp(18px, 2.2vw, 30px);
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 18px;
  /* Cristal oscuro. La ilustración se sigue viendo detrás —eso es lo bonito—
     pero al 12 % de lo que era: encima del tejado iluminado no se lee nada. */
  background: rgba(10, 7, 22, .88);
  backdrop-filter: blur(14px);
  box-shadow: 0 30px 90px rgba(0, 0, 0, .6);
  animation: noc-entra 340ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both;
}
@keyframes noc-entra {
  from { opacity: 0; transform: translateY(16px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

/* La hoja pasa a ser solo el sitio donde se centra el cuadro. */
/* LA FILA NO PUEDE PASARSE DE ALTA, y esto no es un detalle: sin las pistas
   explícitas, la única fila de esta rejilla se dimensiona por su contenido, así
   que el `max-height: 100%` de lo que va dentro se medía contra una fila que ya
   había crecido — o sea, contra sí misma. Con el taller lleno, el catálogo
   estiraba el cuadro entero y el botón de salir se iba por debajo de la
   pantalla. Con `minmax(0, 1fr)` la fila se queda en el alto que hay y lo que
   sobra se desplaza por dentro. */
.menu-hoja {
  position: relative;
  height: 100%;
  display: grid;
  grid-template-rows: minmax(0, 1fr);
  grid-template-columns: minmax(0, 1fr);
  place-items: center;
  padding: clamp(14px, 2.5vh, 30px);
  animation: none;
}
.menu-hoja[hidden] { display: none; }

/* Un velo flojo por debajo: el cuadro ya es opaco, pero sin esto los bordes de
   la ilustración compiten con él y la pantalla se ve ruidosa. */
.menu-hoja::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 78% 78% at 50% 46%, rgba(4, 3, 10, .5), rgba(4, 3, 10, .84));
  pointer-events: none;
}

/* EL LOBBY DEJA VER LA CASA, Y A COLOR. Encima de la ilustración había DOS velos
   sumados —el del menú entero, pensado para la portada, y el de la hoja, pensado
   para un cuadro centrado— y entre los dos dejaban el centro casi negro: justo
   donde el lobby pone a la cuadrilla y justo lo que se quería enseñar.
   Aquí el del menú se apaga, y el de la hoja se queda solo con lo imprescindible
   —los dos lados, que es donde va la interfaz— dejando el medio despejado. */
.menu[data-pantalla='sala'] .menu-velo { background: none; }
/* Y la ilustración, un punto más viva: al quitarle el velo se queda pidiendo el
   color que tiene. */
.menu[data-pantalla='sala'] .menu-fondo { filter: saturate(1.18) brightness(1.14); }

/* LA TIENDA TAMBIÉN DEJA VER LA CASA. El velo de la portada oscurece la
   izquierda —donde estaba su columna de botones— y el del cuadro centrado
   oscurece el medio: sumados dejaban la tienda flotando en un negro plano, con
   el buhonero recortado sobre nada. Aquí basta con bajar la persiana un poco,
   que lo que hay que leer va dentro de su cristal. */
.menu[data-pantalla='tienda'] .menu-velo { background: none; }
.menu[data-pantalla='tienda'] .menu-fondo { filter: saturate(1.1) brightness(1.06); }
.menu-hoja[data-pantalla='tienda']::before {
  background:
    radial-gradient(ellipse 92% 92% at 50% 50%, rgba(4, 3, 10, .34), rgba(4, 3, 10, .8)),
    linear-gradient(180deg, rgba(4, 3, 10, .44) 0%, transparent 24%, transparent 82%, rgba(4, 3, 10, .44) 100%);
}

.menu-hoja[data-pantalla='sala']::before {
  background:
    linear-gradient(90deg, rgba(4, 3, 10, .9) 0%, rgba(4, 3, 10, .46) 17%, transparent 32%),
    linear-gradient(270deg, rgba(4, 3, 10, .9) 0%, rgba(4, 3, 10, .46) 16%, transparent 31%),
    linear-gradient(180deg, rgba(4, 3, 10, .5) 0%, transparent 17%, transparent 78%, rgba(4, 3, 10, .42) 100%);
}

/* --- Cabecera: volver y los dos pasos --------------------------------------- */

.noc-cabeza { display: flex; align-items: center; gap: 16px; }

.noc-atras {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  padding: 8px 15px 8px 11px;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 99px;
  background: rgba(255, 255, 255, .04);
  font: 600 11px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-dim, #a79fc8);
  cursor: pointer;
  transition: transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              color 160ms ease, border-color 160ms ease;
}
.noc-atras:hover, .noc-atras:focus-visible {
  transform: translateX(-4px);
  color: var(--ink, #f4f2ff);
  border-color: rgba(157, 107, 255, .5);
}
.noc-atras-f { font-size: 14px; line-height: 1; }

/* Los dos pasos. No es adorno: dice que esto tiene un final y cuánto falta, que
   es lo que evita la sensación de «¿cuántas pantallas más van a salir?». */
.noc-pasos { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.noc-paso {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px 5px 5px;
  border-radius: 99px;
  font: 600 11px/1 Rubik, system-ui, sans-serif;
  color: var(--ink-faint, #6e678c);
  border: 1px solid transparent;
}
.noc-paso-n {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 99px;
  font: 700 10px/1 Rubik, system-ui, sans-serif;
  font-style: normal;
  background: rgba(255, 255, 255, .08);
  color: inherit;
}
.noc-paso[data-on='true'] {
  color: var(--ink, #f4f2ff);
  border-color: rgba(157, 107, 255, .45);
  background: rgba(91, 47, 184, .3);
}
.noc-paso[data-on='true'] .noc-paso-n { background: var(--violet, #9d6bff); color: #0a0714; }
.noc-paso[data-hecho='true'] { color: var(--lime, #a8f425); }
.noc-paso[data-hecho='true'] .noc-paso-n { background: rgba(168, 244, 37, .18); }

.noc-titulo {
  margin: 0;
  font: 700 clamp(19px, 2.1vw, 26px)/1.1 Rubik, system-ui, sans-serif;
  color: var(--ink, #f4f2ff);
}
.noc-lead {
  margin: -6px 0 0;
  font: 400 12.5px/1.4 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
}
.noc-rotulo {
  margin: 0;
  font: 700 10px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-faint, #6e678c);
}
.noc-nota {
  margin: 0;
  font: 400 12px/1.45 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
}
/* «Elige una casa», mientras no hay ninguna. Va donde va a salir la dificultad,
   para que se entienda que ahí abajo va a aparecer algo. */
.noc-pide {
  margin: 0;
  padding: 16px;
  border: 1px dashed rgba(255, 255, 255, .12);
  border-radius: 12px;
  text-align: center;
  font: 500 12.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-faint, #6e678c);
}

/* --- Las casas, en rejilla -------------------------------------------------- */

/* AUTO-FILL Y NO UN NÚMERO DE COLUMNAS: hoy hay dos casas y para el lanzamiento
   van a ser seis. Con columnas fijas, dos casas salen estiradas y seis salen
   apretadas; así el sitio lo reparte la rejilla. */
.noc-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
  overflow-y: auto;
  scrollbar-width: thin;
  min-height: 0;
}

.noc-casa {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
  overflow: hidden;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 12px;
  background: rgba(255, 255, 255, .03);
  cursor: pointer;
  transition: transform 170ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              border-color 170ms ease, background 170ms ease;
}
.noc-casa:hover:not([disabled]), .noc-casa:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(157, 107, 255, .55);
  background: rgba(255, 255, 255, .06);
}
.noc-casa[data-on='true'] {
  border-color: var(--lime, #a8f425);
  background: rgba(168, 244, 37, .1);
  box-shadow: 0 0 0 1px rgba(168, 244, 37, .35), 0 12px 30px rgba(168, 244, 37, .12);
}
.noc-casa[disabled] { cursor: default; opacity: .45; }

.noc-casa-foto {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: #0a0714;
}
.noc-casa-foto img { width: 100%; height: 100%; object-fit: cover; }
.noc-sinfoto { font-size: 26px; color: rgba(255, 255, 255, .16); }

.noc-casa-pie { display: grid; gap: 4px; padding: 10px 12px 11px; min-width: 0; }
.noc-casa-n {
  font: 600 13.5px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink, #f4f2ff);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.noc-tira { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.noc-pago { font: 700 13px/1 Rubik, system-ui, sans-serif; color: var(--lime, #a8f425); }
.noc-obras {
  padding: 3px 7px;
  border: 1px solid rgba(255, 196, 71, .35);
  border-radius: 99px;
  font: 700 8.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--amber, #ffc447);
}
.noc-marca {
  position: absolute;
  top: 8px;
  right: 8px;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 99px;
  font-size: 13px;
  color: #0a1400;
  background: var(--lime, #a8f425);
}

/* --- La dificultad, cuando ya hay casa -------------------------------------- */

.noc-dif {
  display: grid;
  gap: 9px;
  padding-top: 13px;
  border-top: 1px solid rgba(255, 255, 255, .08);
  animation: noc-abre 320ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both;
}
@keyframes noc-abre {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}

.noc-dif-fila {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 7px;
}
.noc-dif-b {
  display: grid;
  gap: 3px;
  padding: 11px 6px;
  text-align: center;
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 11px;
  background: rgba(255, 255, 255, .03);
  cursor: pointer;
  transition: transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              background 160ms ease, border-color 160ms ease;
}
.noc-dif-b:hover:not([disabled]), .noc-dif-b:focus-visible {
  transform: translateY(-3px);
  border-color: rgba(157, 107, 255, .5);
}
.noc-dif-b[data-on='true'] {
  border-color: rgba(157, 107, 255, .75);
  background: linear-gradient(160deg, rgba(91, 47, 184, .82), rgba(30, 18, 62, .7));
}
.noc-dif-b[disabled] { cursor: default; opacity: .5; }
.noc-dif-n { font: 700 12.5px/1.2 Rubik, system-ui, sans-serif; color: var(--ink, #f4f2ff); }
.noc-dif-paga { font: 700 15px/1 Rubik, system-ui, sans-serif; color: var(--lime, #a8f425); }
.noc-dif-pruebas {
  font: 400 9.5px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink-faint, #6e678c);
}
/* Alto fijo: cambiar de noche no puede mover lo que hay debajo. */
.noc-dif-pista {
  margin: 0;
  min-height: 2.9em;
  font: 400 12px/1.45 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
}

/* =============================================================================
   PASO 2: EL EQUIPO
============================================================================= */

.eqp-cuadro { width: min(1020px, 94vw); }

.eqp-tit { display: flex; align-items: baseline; gap: 14px; }
/* El contador manda: el tope es la regla del juego más dura de esta pantalla. */
.eqp-cuenta {
  margin-left: auto;
  font: 700 17px/1 Rubik, system-ui, sans-serif;
  color: var(--lime, #a8f425);
}
.eqp-cuenta[data-lleno='true'] { color: var(--amber, #ffc447); }

.eqp-cuerpo { min-height: 0; overflow-y: auto; scrollbar-width: thin; }

.eqp-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
  gap: 9px;
}

.eqp-card {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 5px;
  padding: 13px 8px 11px;
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 12px;
  background: rgba(255, 255, 255, .03);
  cursor: pointer;
  transition: transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              border-color 160ms ease, background 160ms ease;
}
.eqp-card:hover:not([disabled]), .eqp-card:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(157, 107, 255, .55);
  background: rgba(255, 255, 255, .06);
}
.eqp-card[data-on='true'] {
  border-color: rgba(168, 244, 37, .55);
  background: rgba(168, 244, 37, .09);
}
.eqp-card[disabled] { cursor: default; opacity: .42; }
.eqp-card img, .eqp-card canvas, .eqp-card svg { display: block; }
.eqp-card-n {
  font: 600 11.5px/1.2 Rubik, system-ui, sans-serif;
  text-align: center;
  color: var(--ink, #f4f2ff);
}
.eqp-card-q {
  font: 400 9.5px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink-faint, #6e678c);
}
/* Cuántas llevas subidas de ésta, en la esquina. */
.eqp-card-sello {
  position: absolute;
  top: 7px;
  right: 7px;
  display: grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: 99px;
  font: 700 11px/1 Rubik, system-ui, sans-serif;
  color: #0a1400;
  background: var(--lime, #a8f425);
}

/* --- El pie: lo que va en el coche y los botones ---------------------------- */

.eqp-pie {
  display: flex;
  align-items: flex-end;
  gap: 16px;
  padding-top: 13px;
  border-top: 1px solid rgba(255, 255, 255, .08);
}
.eqp-coche { flex: 1; display: grid; gap: 7px; min-width: 0; }

.eqp-lista { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.eqp-puesto {
  position: relative;
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 5px 7px;
  border: 1px solid rgba(168, 244, 37, .28);
  border-radius: 9px;
  background: rgba(168, 244, 37, .07);
}
.eqp-x { font: 700 10px/1 Rubik, system-ui, sans-serif; color: var(--lime, #a8f425); }
.eqp-menos {
  display: grid;
  place-items: center;
  width: 17px;
  height: 17px;
  border: none;
  border-radius: 99px;
  font: 700 12px/1 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
  background: rgba(255, 255, 255, .08);
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.eqp-menos:hover, .eqp-menos:focus-visible { background: var(--danger, #ff5566); color: #fff; }

.eqp-botones { display: flex; align-items: center; gap: 9px; flex: none; }

.eqp-todo {
  padding: 14px 18px;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 12px;
  background: rgba(255, 255, 255, .04);
  font: 600 12px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-dim, #a79fc8);
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease, background 150ms ease;
}
.eqp-todo:hover, .eqp-todo:focus-visible {
  color: var(--ink, #f4f2ff);
  border-color: rgba(157, 107, 255, .5);
  background: rgba(255, 255, 255, .07);
}

.eqp-jugar {
  padding: 14px clamp(24px, 4vw, 52px);
  border: 1px solid rgba(168, 244, 37, .55);
  border-radius: 12px;
  background: linear-gradient(100deg, rgba(106, 163, 16, .92), rgba(60, 96, 8, .84));
  font: 700 14px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #f6ffe6;
  cursor: pointer;
  transition: transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              background 160ms ease, box-shadow 160ms ease;
}
.eqp-jugar:hover:not([disabled]), .eqp-jugar:focus-visible {
  transform: translateY(-2px);
  background: linear-gradient(100deg, rgba(126, 190, 22, .96), rgba(76, 118, 12, .9));
  box-shadow: 0 12px 34px rgba(106, 163, 16, .34);
}
.eqp-jugar[disabled] {
  cursor: default;
  border-color: rgba(255, 255, 255, .12);
  background: rgba(255, 255, 255, .05);
  color: var(--ink-faint, #6e678c);
}

/* --- Apretadas -------------------------------------------------------------- */

@media (max-width: 720px), (max-height: 560px) {
  .noc-lead { display: none; }
  .noc-pasos span:not(.noc-paso-n) { display: none; }
  .noc-rejilla { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .eqp-rejilla { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); }
  .eqp-pie { flex-direction: column; align-items: stretch; }
  .eqp-botones > * { flex: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .noc-cuadro, .noc-dif { animation: none; }
  .noc-atras:hover, .noc-casa:hover, .noc-dif-b:hover,
  .eqp-card:hover, .eqp-jugar:hover { transform: none; }
}

/* =============================================================================
   MULTIJUGADOR
   Abrir sala, entrar con un código y ver quién viene. Mismo cuadro del centro.
   Ver client/js/ui/menu-multi.js.
============================================================================= */

.mul-cuadro { width: min(760px, 92vw); }

/* Las dos maneras de juntarse, la una al lado de la otra y del mismo tamaño:
   ninguna es «la buena», depende de si tú convocas o te convocan. */
.mul-dos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 10px;
}

.mul-grande,
.mul-conCodigo {
  display: grid;
  align-content: start;
  gap: 4px;
  padding: 16px;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 13px;
  background: rgba(255, 255, 255, .03);
}
.mul-grande {
  align-content: space-between;
  cursor: pointer;
  transition: transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              border-color 160ms ease, background 160ms ease;
}
.mul-grande:hover, .mul-grande:focus-visible {
  transform: translateY(-3px);
  border-color: rgba(157, 107, 255, .55);
  background: rgba(91, 47, 184, .22);
}
.mul-grande-t {
  font: 700 14px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink, #f4f2ff);
}
.mul-grande-p {
  font: 400 11.5px/1.35 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
}
.mul-grande-ir {
  justify-self: end;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 99px;
  font-size: 16px;
  color: var(--lime, #a8f425);
  background: rgba(168, 244, 37, .12);
  transition: transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)), background 160ms ease;
}
.mul-grande:hover .mul-grande-ir,
.mul-grande:focus-visible .mul-grande-ir {
  transform: translateX(4px);
  background: rgba(168, 244, 37, .24);
}

.mul-codigo { margin-top: 8px; }
.mul-form { display: flex; gap: 7px; }

/* El campo del código: monoespaciado y con las letras separadas, que es como se
   leen cuatro letras sueltas sin confundir una O con un cero. */
.mul-code {
  flex: 1;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 10px;
  background: rgba(0, 0, 0, .34);
  font: 700 16px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .3em;
  text-align: center;
  text-transform: uppercase;
  color: var(--ink, #f4f2ff);
}
.mul-code::placeholder { color: var(--ink-faint, #6e678c); letter-spacing: .2em; }
.mul-code:focus-visible { border-color: var(--violet, #9d6bff); outline: none; }

.mul-entrar {
  padding: 10px 18px;
  border: 1px solid rgba(157, 107, 255, .5);
  border-radius: 10px;
  background: rgba(91, 47, 184, .5);
  font: 700 12px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink, #f4f2ff);
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease;
}
.mul-entrar:hover, .mul-entrar:focus-visible {
  background: rgba(110, 60, 214, .75);
  border-color: rgba(190, 150, 255, .8);
}
.mul-aviso {
  margin: 7px 0 0;
  min-height: 1.2em;
  font: 500 11px/1.2 Rubik, system-ui, sans-serif;
  color: var(--danger, #ff5566);
}

/* --- Las salas abiertas ----------------------------------------------------- */

.mul-cab { display: flex; align-items: center; gap: 12px; }
.mul-mirar {
  margin-left: auto;
  padding: 5px 11px;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 99px;
  background: transparent;
  font: 600 10px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint, #6e678c);
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease;
}
.mul-mirar:hover, .mul-mirar:focus-visible {
  color: var(--ink, #f4f2ff);
  border-color: rgba(157, 107, 255, .5);
}

.mul-salas {
  display: grid;
  gap: 6px;
  max-height: 33vh;
  overflow-y: auto;
  scrollbar-width: thin;
}

.mul-sala {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 9px 13px;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 10px;
  background: rgba(255, 255, 255, .03);
  cursor: pointer;
  transition: transform 150ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              border-color 150ms ease, background 150ms ease;
}
.mul-sala:hover:not([disabled]), .mul-sala:focus-visible {
  transform: translateX(5px);
  border-color: rgba(157, 107, 255, .5);
  background: rgba(255, 255, 255, .06);
}
.mul-sala[disabled] { cursor: default; opacity: .45; }

.mul-sala-cod {
  padding: 5px 9px;
  border-radius: 7px;
  background: rgba(157, 107, 255, .18);
  font: 700 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .12em;
  color: var(--violet, #9d6bff);
}
.mul-sala-texto { display: grid; gap: 2px; min-width: 0; }
.mul-sala-n {
  font: 600 12.5px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink, #f4f2ff);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mul-sala-p {
  font: 400 10.5px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink-faint, #6e678c);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mul-sala-tag {
  font: 600 10px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-dim, #a79fc8);
}

/* --- Dentro de una sala: el código y la cuadrilla --------------------------- */

.mul-chapa {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 18px;
  border: 1px solid rgba(157, 107, 255, .3);
  border-radius: 14px;
  background: linear-gradient(160deg, rgba(43, 24, 92, .6), rgba(14, 10, 28, .5));
  text-align: center;
}

/* EL CÓDIGO, ENORME Y PINCHABLE. Cuatro letras se transcriben mal más veces de
   las que parece: se copia de un clic y se dice que se ha copiado. */
.mul-cod {
  padding: 6px 20px;
  border: 1px dashed rgba(168, 244, 37, .45);
  border-radius: 12px;
  background: transparent;
  font: 700 clamp(30px, 4.4vw, 46px)/1.1 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .22em;
  color: var(--lime, #a8f425);
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease;
}
.mul-cod:hover, .mul-cod:focus-visible {
  background: rgba(168, 244, 37, .1);
  border-style: solid;
}
.mul-cod[data-copiado='true'] {
  font-size: clamp(18px, 2.4vw, 26px);
  letter-spacing: .12em;
}

.mul-crew { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.mul-crew-fila {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 13px;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 10px;
  background: rgba(255, 255, 255, .03);
}
/* El tuyo, marcado. En una lista de cuatro nombres parecidos, saber cuál eres
   no puede depender de acordarte de tu propio nombre de usuario. */
.mul-crew-fila[data-yo='true'] {
  border-color: rgba(157, 107, 255, .4);
  background: rgba(91, 47, 184, .2);
}
.mul-crew-n {
  flex: 1;
  min-width: 0;
  font: 600 13px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink, #f4f2ff);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* La luz de listo: verde encendido, apagada gris. Se lee sin leer. */
.mul-luz {
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: 99px;
  background: rgba(255, 255, 255, .18);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12);
}
.mul-luz[data-on='true'] {
  background: var(--lime, #a8f425);
  box-shadow: 0 0 10px rgba(168, 244, 37, .7);
}
.mul-tag {
  padding: 3px 8px;
  border-radius: 99px;
  font: 600 9.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-faint, #6e678c);
  background: rgba(255, 255, 255, .05);
}
.mul-tag--jefe { color: var(--amber, #ffc447); background: rgba(255, 196, 71, .12); }

.mul-solo {
  padding: 12px;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 11px;
  background: transparent;
  font: 600 11.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-dim, #a79fc8);
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease;
}
.mul-solo:hover, .mul-solo:focus-visible {
  color: var(--danger, #ff5566);
  border-color: rgba(255, 85, 102, .4);
}

/* --- La cuadrilla dentro del paso del equipo -------------------------------- */

.eqp-crew {
  display: grid;
  gap: 7px;
  padding-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, .08);
}

/* «Estoy listo» no es verde: verde es «salir», y son dos cosas distintas. */
.eqp-jugar[data-listo] {
  border-color: rgba(157, 107, 255, .55);
  background: linear-gradient(100deg, rgba(91, 47, 184, .85), rgba(40, 22, 84, .75));
  color: var(--ink, #f4f2ff);
}
.eqp-jugar[data-listo='true'] {
  border-color: rgba(168, 244, 37, .5);
  background: rgba(168, 244, 37, .12);
  color: var(--lime, #a8f425);
}

@media (prefers-reduced-motion: reduce) {
  .mul-grande:hover, .mul-sala:hover { transform: none; }
}

/* =============================================================================
   LA TIENDA
   Comprar con lo cobrado y vender lo que sobra. Ver client/js/ui/menu-tienda.js.
============================================================================= */

/* El sello de la tienda: en la esquina de la hoja, como en el lobby, y FUERA de
   la rejilla que centra al tendero con su mostrador — si entrara en ella, movería
   el centro de la pareja. Por detrás del bocadillo, que le pasa por delante. */
.tnd-sello {
  position: absolute;
  top: clamp(10px, 1.6vh, 20px);
  left: clamp(12px, 1.6vw, 24px);
  z-index: 1;
  pointer-events: none;
}
.tnd-sello .menu-marca { width: min(220px, 16vw); }

/* --- El buhonero ------------------------------------------------------------ */

/* UNA TIENDA SIN TENDERO ES UN CATÁLOGO. Con él, entrar aquí es ir a ver a
   alguien — y ese alguien te saluda al abrir la puerta. Va a la izquierda del
   mostrador y no dentro: el mostrador se repinta en cada compra y él no.

   Y OCUPA TODO EL ALTO, saliéndose por el borde izquierdo. Empezó cabiendo
   entero y educadamente dentro de su columna, y así no era un tendero: era una
   figurita en una esquina con un palmo de negro por encima. Recortado por el
   borde está DE PIE AHÍ, en su sitio, y el mostrador empieza justo donde acaba
   su abrigo. */
/* LOS DOS JUNTOS Y CENTRADOS. Con la segunda columna a `1fr` el mostrador se
   comía todo el hueco que sobraba y la pareja quedaba escorada a la derecha, con
   el buhonero colgando en el vacío. Con las dos a su ancho, lo que se centra es
   el conjunto: el tendero y su mostrador, juntos. */
.tnd-escena {
  display: grid;
  grid-template-columns: auto auto;
  align-items: stretch;
  justify-content: center;
  justify-items: center;
  width: 100%;
  height: 100%;
}
.tnd-mostrador {
  display: grid;
  align-items: center;
  justify-items: center;
  min-width: 0;
  min-height: 0;
}

.tnd-buhonero {
  position: relative;
  display: grid;
  align-content: end;
  /* Se sale por la izquierda a propósito, y se mete un poco por debajo del
     mostrador: así hay una persona detrás del cristal y no dos dibujos uno al
     lado del otro. */
  /* DELANTE DEL MOSTRADOR Y NO DETRÁS. Iba metido por debajo del cuadro —quedaba
     bonito, como un tendero asomado— pero eso se llevaba por delante su
     bocadillo: el cuadro se pintaba encima y el «Welcome» salía cortado por la
     mitad. Delante, con el hombro montado sobre el borde, se lee igual de bien
     como profundidad y además puede hablar. */
  z-index: 3;
  margin-left: clamp(-190px, -9vw, -60px);
  margin-right: clamp(-58px, -2.8vw, -18px);
  margin-bottom: clamp(-46px, -3.5vh, -14px);
  pointer-events: none;
  animation: tnd-llega 700ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both;
}
.tnd-buhonero img {
  display: block;
  width: auto;
  height: 100%;
  max-height: 1040px;
  /* Se balancea despacio: lo justo para que esté vivo y no distraiga de lo que
     hay que mirar, que es lo que se compra. */
  transform-origin: 50% 100%;
  animation: tnd-mece 5.4s ease-in-out infinite;
  filter: drop-shadow(0 22px 34px rgba(0, 0, 0, .75));
}

/* El resplandor de su farol, que respira a otro ritmo que el balanceo: dos
   cosas a compás se leen como una animación, a destiempo se leen como una
   persona con un farol. */
.tnd-farol {
  position: absolute;
  left: 4%;
  bottom: 32%;
  width: 40%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 176, 74, .36), transparent 68%);
  animation: tnd-farol 3.1s ease-in-out infinite;
}

/* EL BOCADILLO. Sale de su boca, rebota al aparecer, flota mientras está y se va
   solo a los dos segundos: un saludo que se queda puesto deja de ser un saludo y
   pasa a ser un cartel. */
/* Un poco más abajo y a la derecha de lo que cabría: así queda más cerca de su
   cabeza —de donde tiene que salir— y de paso deja ver el logotipo, que está
   justo detrás. */
/* LA FIGURA: el hueco exacto del dibujo, para poder colgarle el bocadillo.
   El contenedor de fuera se estira a lo que da la pantalla y el buhonero ocupa
   la mitad de abajo, así que un globo puesto «al 6 % de arriba» acababa en la
   esquina, encima del logotipo. Anclado aquí, los porcentajes son del muñeco. */
.tnd-figura {
  position: relative;
  display: grid;
  align-content: end;
  justify-items: center;
  height: 100%;
  min-height: 0;
}

.tnd-globo {
  position: absolute;
  /* Justo encima de la cabeza y un poco a la derecha, que es hacia donde mira.
     Medido sobre el dibujo: la capucha empieza a un pelo del borde de arriba. */
  left: 52%;
  bottom: 90%;
  z-index: 2;
  padding: 12px 20px 13px;
  border-radius: 16px;
  background: #f4f1ea;
  color: #17131f;
  font: 700 clamp(17px, 1.5vw, 23px)/1 Rubik, system-ui, sans-serif;
  letter-spacing: .01em;
  white-space: nowrap;
  box-shadow: 0 14px 34px rgba(0, 0, 0, .55);
  transform-origin: 10% 100%;
  animation:
    tnd-globo-entra 420ms var(--ease-pop, cubic-bezier(.2, 1.5, .4, 1)) both,
    tnd-globo-flota 2.4s 420ms ease-in-out infinite;
}
/* El pico, apuntándole a él: sin pico es un cartel flotando al lado, con pico
   lo está diciendo alguien. */
.tnd-globo-pico {
  position: absolute;
  left: 14px;
  bottom: -9px;
  width: 20px;
  height: 12px;
  background: #f4f1ea;
  clip-path: polygon(0 0, 100% 0, 22% 100%);
}
.tnd-globo[data-fuera='true'] {
  animation: tnd-globo-sale 320ms ease both;
}
@keyframes tnd-globo-entra {
  from { opacity: 0; transform: scale(.4) translateY(10px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
@keyframes tnd-globo-flota {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -5px; }
}
@keyframes tnd-globo-sale {
  to { opacity: 0; transform: scale(.75) translateY(-14px); }
}

@keyframes tnd-mece {
  0%, 100% { transform: rotate(-1deg) translateY(0); }
  50%      { transform: rotate(1deg) translateY(-6px); }
}
@keyframes tnd-farol {
  0%, 100% { opacity: .55; transform: scale(1); }
  50%      { opacity: 1; transform: scale(1.08); }
}
@keyframes tnd-llega {
  from { opacity: 0; transform: translateX(-50px); }
  to   { opacity: 1; transform: none; }
}

/* EL MOSTRADOR NO PARPADEA AL COMPRAR. El cuadro se rehace en cada compra —el
   dinero baja, el taller crece— y con la entrada animada puesta, cada cacharro
   comprado era un fogonazo de la tienda entera. Aquí entra el buhonero, y con
   eso basta. */
.tnd-mostrador .noc-cuadro { animation: none; }

/* Cuando no cabe, se va: el mostrador manda. */
@media (max-width: 1180px), (max-height: 560px) {
  .tnd-buhonero { display: none; }
  .tnd-escena { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  .tnd-buhonero, .tnd-buhonero img, .tnd-farol { animation: none; }
  .tnd-globo { animation: none; }
  .tnd-globo[data-fuera='true'] { opacity: 0; }
}

.tnd-cuadro {
  width: min(1020px, 94vw);
  /* Un poco menos opaco que los demás cuadros: ahora hay algo que ver detrás. */
  background: rgba(10, 7, 22, .8);
}

/* El dinero manda: es el número que decide todo lo que se puede hacer aquí, y
   tenerlo que ir a buscar a una esquina convierte cada compra en una cuenta
   mental. Va al lado del título y en el verde de la marca. */
.tnd-dinero {
  margin-left: auto;
  font: 700 20px/1 Rubik, system-ui, sans-serif;
  color: var(--lime, #a8f425);
}

.tnd-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 9px;
}

.tnd-card {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 4px;
  padding: 13px 8px 11px;
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 12px;
  background: rgba(255, 255, 255, .03);
  cursor: pointer;
  transition: transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              border-color 160ms ease, background 160ms ease;
}
.tnd-card:hover:not([disabled]), .tnd-card:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(168, 244, 37, .5);
  background: rgba(168, 244, 37, .07);
}
/* Lo que ya tienes, marcado — pero se puede comprar otro: la estantería es del
   equipo y llevar dos linternas entre cuatro no es un capricho. */
.tnd-card[data-tuyo='true'] { border-color: rgba(157, 107, 255, .4); }
/* LO QUE NO SE PUEDE PAGAR NO SE ESCONDE: ver lo que hay y no poder es lo que
   hace que se quiera. Apagado, pero ahí. */
.tnd-card[disabled] { cursor: default; opacity: .4; }

.tnd-card-n {
  font: 600 11.5px/1.2 Rubik, system-ui, sans-serif;
  text-align: center;
  color: var(--ink, #f4f2ff);
}
.tnd-precio { font: 700 14px/1 Rubik, system-ui, sans-serif; color: var(--lime, #a8f425); }
.tnd-card-q { font: 400 9.5px/1.2 Rubik, system-ui, sans-serif; color: var(--ink-faint, #6e678c); }
.tnd-nollega {
  position: absolute;
  top: 7px;
  right: 7px;
  padding: 3px 7px;
  border-radius: 99px;
  font: 700 8.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--amber, #ffc447);
  background: rgba(255, 196, 71, .14);
}

/* LO QUE PIDE NIVEL SE VE DISTINTO DE LO QUE NO PUEDES PAGAR, y tiene que
   verse: son dos noes que no se arreglan igual. El ámbar de arriba dice «vuelve
   con dinero»; el morado dice «vuelve cuando sepas». Si los dos fueran el mismo
   gris apagado, alguien ahorraría tres noches para algo que no está en venta.

   Y NO SE APAGA TANTO como lo que no se puede pagar (.4): estos son el
   escaparate del futuro y hay que poder mirarlos. Se les quita el color, no la
   presencia — el icono se queda casi entero y lo que se va es el brillo. */
.tnd-card[data-cerrado='true'] {
  opacity: .74;
  border-color: rgba(157, 107, 255, .22);
  background: rgba(157, 107, 255, .045);
  filter: saturate(.35);
}
.tnd-card[data-cerrado='true']:hover { filter: saturate(.7); opacity: .88; }
.tnd-llave {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px 3px 7px;
  border-radius: 99px;
  font: 700 9.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .05em;
  color: var(--violet-soft, #c3a4ff);
  background: rgba(157, 107, 255, .16);
}
/* El candado se dibuja, no se escribe: un emoji cambia de forma en cada sistema
   y este va a salir cinco veces en la misma rejilla. */
.tnd-llave::before {
  content: '';
  width: 7px;
  height: 8px;
  border-radius: 1px 1px 2px 2px;
  background: currentColor;
  box-shadow: 0 -4px 0 -2px currentColor, -2px -3px 0 -2px currentColor, 2px -3px 0 -2px currentColor;
}

.tnd-pie { align-items: flex-start; }
/* En el taller de la tienda el aspa VENDE, así que va en ámbar y no en rojo:
   vender no es un error, es una decisión. */
.tnd-puesto { border-color: rgba(157, 107, 255, .28); background: rgba(157, 107, 255, .07); }
.tnd-puesto .eqp-menos:hover,
.tnd-puesto .eqp-menos:focus-visible { background: var(--amber, #ffc447); color: #1a1200; }

/* =============================================================================
   EQUIPAMIENTO
   Tu cara y lo que tienes guardado. Ver client/js/ui/menu-equipa.js.
============================================================================= */

.eqa-cuadro { width: min(940px, 94vw); }
.eqa-sep { margin-top: 6px; }

.eqa-caras {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 9px;
}

.eqa-pj {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 3px;
  padding: 12px 10px 13px;
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 12px;
  background: rgba(255, 255, 255, .03);
  cursor: pointer;
  transition: transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              border-color 160ms ease, background 160ms ease;
}
.eqa-pj:hover, .eqa-pj:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(157, 107, 255, .55);
  background: rgba(255, 255, 255, .06);
}
.eqa-pj[data-on='true'] {
  border-color: var(--lime, #a8f425);
  background: rgba(168, 244, 37, .1);
}

/* La cara sale recortada de la lámina del juego, así que va pixelada a
   propósito: es el mismo muñeco que sale luego en la casa. */
.eqa-cara { image-rendering: pixelated; }
.eqa-pj-n { font: 600 13px/1.2 Rubik, system-ui, sans-serif; color: var(--ink, #f4f2ff); }
/* DOS LÍNEAS SIEMPRE, corte incluido. Las descripciones van de una línea a tres
   y las fichas salían de tres alturas distintas: una fila de caras a distinto
   nivel se lee como un fallo de maquetación, no como cinco personajes. */
.eqa-pj-p {
  font: 400 10.5px/1.3 Rubik, system-ui, sans-serif;
  text-align: center;
  color: var(--ink-faint, #6e678c);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  min-height: 2.6em;
}

/* Más anchas de lo que parecen necesarias: «Cámara de fotos» y «Chivato del
   frío» son nombres largos, y a 160 se cortaban justo por donde se distinguen
   de sus vecinos. */
.eqa-cosas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(205px, 1fr));
  gap: 7px;
}
.eqa-cosa {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 10px;
  background: rgba(255, 255, 255, .03);
}
.eqa-cosa-n {
  flex: 1;
  min-width: 0;
  font: 600 11.5px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink, #f4f2ff);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.eqa-cosa-x { font: 700 12px/1 Rubik, system-ui, sans-serif; color: var(--lime, #a8f425); }

/* El taller vacío no se queda en una frase triste: lleva la puerta al sitio
   donde se arregla. */
.eqa-vacio {
  display: grid;
  justify-items: center;
  gap: 12px;
  padding: 22px;
  border: 1px dashed rgba(255, 255, 255, .12);
  border-radius: 12px;
  text-align: center;
}

/* =============================================================================
   AJUSTES
   Idioma, volumen y pantalla completa. Ver client/js/ui/menu-ajustes.js.
============================================================================= */

.ajs-cuadro { width: min(720px, 92vw); }
.ajs-cuerpo { display: grid; gap: 9px; }

/* Cada ajuste en su fila: a la izquierda qué es y por qué, a la derecha lo que
   se toca. En columna no —tres bloques apilados con su control debajo hacen que
   la pantalla parezca un formulario, y esto no se rellena, se ajusta. */
.ajs-fila {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  padding: 14px 16px;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 12px;
  background: rgba(255, 255, 255, .03);
}
.ajs-texto { flex: 1; min-width: 180px; display: grid; gap: 3px; }
.ajs-t { font: 600 13.5px/1.2 Rubik, system-ui, sans-serif; color: var(--ink, #f4f2ff); }
.ajs-p { font: 400 11.5px/1.35 Rubik, system-ui, sans-serif; color: var(--ink-dim, #a79fc8); }

/* Los idiomas, cada uno en su propia lengua: «Spanish» no lo busca un español. */
.ajs-idiomas { display: flex; flex-wrap: wrap; gap: 6px; }
.ajs-idioma {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 11px;
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 99px;
  background: rgba(255, 255, 255, .03);
  font: 600 11.5px/1 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease, background 150ms ease;
}
.ajs-idioma:hover, .ajs-idioma:focus-visible {
  color: var(--ink, #f4f2ff);
  border-color: rgba(157, 107, 255, .5);
}
.ajs-idioma[data-on='true'] {
  color: var(--ink, #f4f2ff);
  border-color: rgba(168, 244, 37, .5);
  background: rgba(168, 244, 37, .1);
}
.ajs-bandera { font-size: 14px; line-height: 1; }

.ajs-vol { display: flex; align-items: center; gap: 12px; }
.ajs-cifra {
  min-width: 42px;
  text-align: right;
  font: 700 13px/1 Rubik, system-ui, sans-serif;
  color: var(--lime, #a8f425);
}

/* El deslizador, pintado a mano: el del navegador cambia de un sistema a otro y
   en una pantalla oscura sale gris claro y desentona. */
.ajs-rango {
  width: clamp(140px, 22vw, 220px);
  height: 4px;
  appearance: none;
  border-radius: 99px;
  background: rgba(255, 255, 255, .12);
  cursor: pointer;
}
.ajs-rango::-webkit-slider-thumb {
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 99px;
  background: var(--lime, #a8f425);
  box-shadow: 0 0 0 4px rgba(168, 244, 37, .18);
  cursor: pointer;
}
.ajs-rango::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border: none;
  border-radius: 99px;
  background: var(--lime, #a8f425);
  cursor: pointer;
}

.ajs-boton {
  padding: 10px 20px;
  border: 1px solid rgba(157, 107, 255, .45);
  border-radius: 10px;
  background: rgba(91, 47, 184, .35);
  font: 600 12px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink, #f4f2ff);
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease;
}
.ajs-boton:hover, .ajs-boton:focus-visible { background: rgba(110, 60, 214, .6); }
.ajs-boton[data-on='true'] {
  border-color: rgba(168, 244, 37, .45);
  background: rgba(168, 244, 37, .12);
  color: var(--lime, #a8f425);
}

@media (prefers-reduced-motion: reduce) {
  .tnd-card:hover, .eqa-pj:hover { transform: none; }
}

/* =============================================================================
   EL LOBBY DE LA SALA
   Tres columnas: qué se decide · quién viene · qué lleváis y cuándo salís.
   Ver client/js/ui/menu-sala.js.

   PANELES DE CRISTAL, NO CAJAS GRISES. Cada zona tiene su marco —hace falta:
   son tres cosas distintas y sin marco se mezclan— pero traslúcido y con un
   borde de un píxel, para que la casa se siga viendo por debajo. Es la
   diferencia entre una interfaz que está SOBRE la ilustración y una que la tapa.
============================================================================= */

.sal-cuadro {
  position: relative;
  justify-self: stretch;
  align-self: stretch;
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-columns: minmax(250px, 19vw) 1fr minmax(250px, 19vw);
  grid-template-rows: auto 1fr;
  gap: clamp(14px, 1.8vw, 30px);
}

/* El sello, igual que en la portada: mismo sitio y mismo tamaño. */
.sal-sello { grid-column: 1; grid-row: 1; padding-left: 4px; }
.sal-sello .menu-marca { width: min(220px, 16vw); }

/* --- La columna de la izquierda --------------------------------------------- */

.sal-izq {
  grid-column: 1;
  grid-row: 2;
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-height: 0;
  padding: clamp(12px, 1.5vh, 18px);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 18px;
  background: rgba(10, 7, 22, .58);
  backdrop-filter: blur(10px);
}

/* El código, en su chapa: es lo que hay que pasarle a alguien, así que va
   arriba del todo y es lo más grande de la columna. */
/* EL `hidden` TIENE QUE GANAR. Cualquier regla de autor con `display:` pisa al
   `display:none` que el navegador le pone a `[hidden]`, así que la chapa del
   código se veía igual jugando solo, que es justo cuando no sirve para nada. */
.sal-chapa[hidden] { display: none; }

.sal-chapa {
  display: grid;
  justify-items: center;
  gap: 6px;
  padding: 12px 10px 14px;
  text-align: center;
}
.sal-chapa-t {
  margin: 0;
  font: 700 9.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-faint, #6e678c);
}
/* De trazo discontinuo: se lee como «esto es un código para copiar» y no como un
   botón más. Y se copia pinchándolo — cuatro letras se transcriben mal más
   veces de las que parece. */
.sal-cod {
  padding: 7px 20px;
  border: 1px dashed rgba(168, 244, 37, .5);
  border-radius: 11px;
  background: transparent;
  font: 700 clamp(22px, 2.2vw, 30px)/1.1 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .2em;
  color: var(--lime, #a8f425);
  cursor: pointer;
  transition: background 150ms ease, border-style 150ms ease;
}
.sal-cod:hover, .sal-cod:focus-visible {
  background: rgba(168, 244, 37, .1);
  border-style: solid;
}
.sal-cod[data-copiado='true'] { font-size: clamp(14px, 1.4vw, 18px); letter-spacing: .1em; }

/* Los botones: icono a la izquierda, qué decide arriba y lo que hay puesto
   debajo. Sin fondo propio salvo el destacado — flotan dentro del panel. */
.sal-b {
  display: grid;
  grid-template-columns: 34px 1fr;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, .07);
  border-radius: 12px;
  background: rgba(255, 255, 255, .028);
  cursor: pointer;
  transition: transform 170ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              border-color 170ms ease, background 170ms ease;
}
.sal-b:hover:not([disabled]), .sal-b:focus-visible {
  transform: translateX(5px);
  border-color: rgba(157, 107, 255, .5);
  background: rgba(255, 255, 255, .06);
}
.sal-b[disabled] { cursor: default; opacity: .4; }

.sal-b-i {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  color: var(--ink-dim, #a79fc8);
  background: rgba(255, 255, 255, .05);
}
.sal-b-texto { display: grid; gap: 1px; min-width: 0; }
.sal-b-t {
  font: 700 11px/1.2 Rubik, system-ui, sans-serif;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink, #f4f2ff);
}
.sal-b-v {
  font: 400 12px/1.25 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sal-solo {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 13px;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 12px;
  background: transparent;
  font: 600 11px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-dim, #a79fc8);
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease, background 150ms ease;
}
.sal-solo:hover, .sal-solo:focus-visible {
  color: var(--ink, #f4f2ff);
  border-color: rgba(255, 255, 255, .16);
  background: rgba(255, 255, 255, .04);
}
.sal-solo-f { font-size: 14px; line-height: 1; }

/* --- El centro --------------------------------------------------------------- */

/* EL CENTRO: UNA HOJA QUE SE SUSTITUYE, Y DEBAJO LA NOCHE.
   La hoja es lo único que cambia de toda la pantalla — el sello, las dos
   columnas y la tira de abajo se quedan donde están. Antes cambiaba todo y la
   pantalla entera volvía a entrar animada: un fogonazo por clic. */
.sal-centro {
  grid-column: 2;
  grid-row: 1 / -1;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  gap: clamp(12px, 2vh, 26px);
  min-width: 0;
  min-height: 0;
}

/* Y el marco no crece nunca más alto que su hueco: lo que pase de ahí se
   desplaza dentro del catalogo, no empuja al resto. */
.sal-cuadro { max-height: 100%; }
.sal-vista { min-height: 0; overflow: hidden; }

.sal-vista { display: grid; min-height: 0; }
.sal-hoja {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: clamp(12px, 2vh, 24px);
  min-height: 0;
}

/* SE VA LO QUE HABÍA Y LLEGA LO NUEVO. Sin ese medio segundo, cambiar de la sala
   a las casas se lee como un fallo de pintado: todo lo demás sigue exactamente
   donde estaba, así que nada dice que has ido a otro sitio. */
@keyframes sal-se-va {
  to { opacity: 0; transform: translateY(-12px) scale(.99); filter: blur(5px); }
}
@keyframes sal-llega {
  from { opacity: 0; transform: translateY(16px) scale(.99); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: none; }
}
.sal-vista[data-paso='sale'] { animation: sal-se-va 150ms ease both; }
.sal-vista[data-paso='entra'] {
  animation: sal-llega 380ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both;
}
/* Y sus dos partes llegan escalonadas, que es como se lee un sitio nuevo. */
.sal-vista[data-paso='entra'] .sal-cabeza { animation: sal-llega 420ms 40ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both; }
.sal-vista[data-paso='entra'] .sal-cabeza + * { animation: sal-llega 460ms 110ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both; }

/* Título y frase a la izquierda; lo que la vista quiera poner —«cargar todo»—
   a la derecha, a su altura. */
.sal-cabeza {
  align-self: start;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px 16px;
}
.sal-titulo {
  grid-area: 1 / 1;
  margin: 0;
  font: 700 clamp(26px, 3vw, 40px)/1 Rubik, system-ui, sans-serif;
  letter-spacing: .01em;
  color: var(--ink, #f4f2ff);
  text-shadow: 0 3px 20px rgba(0, 0, 0, .8);
}
.sal-lead {
  grid-area: 2 / 1;
  margin: 6px 0 0;
  font: 400 13px/1.4 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
}
/* CARGAR TODO. Con el taller lleno, pinchar dieciséis veces para decir
   «llévatelo todo» es hacer trabajar a alguien por gusto. */
.sal-todo {
  grid-area: 1 / 2 / span 2 / 3;
  padding: 11px 18px;
  border: 1px solid rgba(168, 244, 37, .45);
  border-radius: 11px;
  background: rgba(168, 244, 37, .1);
  font: 700 11px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--lime, #a8f425);
  cursor: pointer;
  transition: background 150ms ease, transform 150ms var(--ease-out, cubic-bezier(.22, 1, .36, 1));
}
.sal-todo:hover, .sal-todo:focus-visible {
  background: rgba(168, 244, 37, .2);
  transform: translateY(-2px);
}

/* --- La noche, abajo y siempre puesta ---------------------------------------- */

/* NO SE ESCONDE DETRÁS DE UN BOTÓN porque no es una pantalla: son cuatro
   opciones de una línea que se comparan de un vistazo y se cambian hasta el
   último momento. Metida en su propio sitio obligaba a entrar, elegir y salir
   para cambiar un número que está a la vista. */
.sal-noches {
  align-self: end;
  padding: clamp(12px, 1.6vh, 18px) clamp(14px, 1.6vw, 22px);
  border: 1px solid rgba(255, 255, 255, .07);
  border-radius: 16px;
  background: rgba(10, 7, 22, .78);
}
.sal-noches .noc-dif { gap: 10px; }
.sal-noches .noc-dif-b { background: rgba(255, 255, 255, .04); }
.sal-noches .noc-dif-b[data-on='true'] { background: rgba(157, 107, 255, .3); }
.sal-noches .noc-dif-pista { text-shadow: 0 2px 10px rgba(0, 0, 0, .8); }

/* EL TABLADO. Un marco muy fino alrededor de la cuadrilla: sin él, los muñecos
   flotaban sueltos encima de la casa y no se entendía que los cuatro sitios son
   una sola cosa —la sala— y no cuatro adornos. */
.sal-tablado {
  position: relative;
  align-self: center;
  display: grid;
  padding: clamp(14px, 2vh, 24px) clamp(12px, 1.6vw, 24px);
  border: 1px solid rgba(255, 255, 255, .07);
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(10, 7, 22, .42), rgba(10, 7, 22, .16));
}


/* ALINEADOS POR LA CABEZA Y NO POR LOS PIES. Debajo del tuyo cuelgan dos cosas
   que los demás no tienen —tu nivel y el botón de cambiar la cara—, así que
   cuadrando los pies el tuyo se subía y la cuadrilla salía a distinta altura,
   que se lee como un fallo de maquetación y no como cuatro personas de pie. */
.sal-fila {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-items: stretch;
  gap: clamp(6px, 1vw, 18px);
}
/* SOLO, UNO Y CENTRADO. Con la rejilla de cuatro, el único que hay se quedaba
   arrinconado a la izquierda con tres huecos vacíos al lado — que es justo la
   sensación que no queremos dar a quien elige jugar solo. Y el marco se ciñe a
   él: un tablado del ancho de la pantalla con una figura en medio se lee como un
   sitio al que le falta gente, no como tu partida. */
.sal-fila[data-solo='true'] { grid-template-columns: minmax(0, auto); justify-content: center; }
.sal-tablado[data-solo='true'] {
  justify-self: center;
  padding-inline: clamp(34px, 5vw, 76px);
}

.sal-pj {
  display: grid;
  justify-items: center;
  align-content: start;
  gap: 4px;
  animation: sal-llega 420ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both;
}
@keyframes sal-llega {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

/* El muñeco respira: la fila de frente de su lámina, corrida a saltos.
   `--tira` y el número de pasos los pone el JS, que es quien sabe cuántos
   fotogramas tiene cada personaje (client/js/ui/personajes.js). */
@keyframes pj-respira { to { background-position-x: var(--tira, 0); } }

.sal-pj-cara {
  image-rendering: pixelated;
  filter: drop-shadow(0 12px 14px rgba(0, 0, 0, .75));
}
/* Quien no está listo, apagado: se lee de un vistazo quién falta. */
.sal-pj[data-listo='false'] .sal-pj-cara {
  filter: drop-shadow(0 12px 14px rgba(0, 0, 0, .75)) grayscale(.5) brightness(.76);
}

.sal-pj-nombre {
  margin: 0;
  font: 700 12px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink, #f4f2ff);
  text-shadow: 0 2px 10px rgba(0, 0, 0, .9);
}
.sal-pj[data-yo='true'] .sal-pj-nombre { color: var(--ink, #f4f2ff); }

/* Tu nivel, y SOLO el tuyo: de los demás no se sabe y no se inventa. */
.sal-pj-nivel {
  margin: 0;
  font: 700 9px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--lime, #a8f425);
  text-shadow: 0 2px 8px rgba(0, 0, 0, .9);
}

/* Y EL BOTÓN DE CAMBIAR LA CARA, DEBAJO DE LA CARA. Ahí y no en el menú de la
   izquierda: el muñeco está delante, y lo que lo cambia tiene que estar donde se
   está mirando. Se queda apagado hasta que pasas por encima de tu propio
   muñeco — es tuyo, no hace falta que grite. */
.sal-cambiar {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 4px;
  padding: 7px 13px;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 99px;
  background: rgba(10, 7, 22, .7);
  font: 700 9.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-dim, #a79fc8);
  cursor: pointer;
  opacity: .72;
  transition: opacity 160ms ease, color 160ms ease, border-color 160ms ease,
              background 160ms ease, transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1));
}
.sal-pj:hover .sal-cambiar { opacity: 1; }
.sal-cambiar:hover, .sal-cambiar:focus-visible {
  opacity: 1;
  transform: translateY(-2px);
  color: var(--ink, #f4f2ff);
  border-color: rgba(157, 107, 255, .6);
  background: rgba(91, 47, 184, .55);
}

.sal-pj-pie { display: flex; align-items: center; gap: 6px; }
.sal-pj-listo {
  padding: 4px 11px;
  border-radius: 99px;
  font: 700 9px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-dim, #a79fc8);
  background: rgba(6, 4, 14, .78);
}
.sal-pj-listo[data-on='true'] {
  color: #0a1400;
  background: var(--lime, #a8f425);
}

/* El hueco libre: dice que cabe más gente y que ahí irá el invitar. */
.sal-hueco {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 10px;
  width: 100%;
  min-height: clamp(120px, 15vh, 200px);
  border: 2px dashed rgba(255, 255, 255, .13);
  border-radius: 16px;
  background: transparent;
  cursor: pointer;
  transition: border-color 160ms ease, background 160ms ease;
}
.sal-hueco:hover:not([disabled]) {
  border-color: rgba(157, 107, 255, .5);
  background: rgba(91, 47, 184, .16);
}
.sal-hueco[disabled] { cursor: default; }
.sal-mas { font: 200 40px/1 Rubik, system-ui, sans-serif; color: rgba(255, 255, 255, .3); }
.sal-hueco-t {
  max-width: 90px;
  font: 700 9.5px/1.3 Rubik, system-ui, sans-serif;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-align: center;
  color: var(--ink-faint, #6e678c);
}

/* --- La columna de la derecha ------------------------------------------------ */

.sal-der {
  grid-column: 3;
  grid-row: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: clamp(10px, 1.4vh, 16px);
  min-height: 0;
}

/* Tu ficha, la misma de la portada, pero ocupando el ancho de la columna. */
.sal-ficha { width: 100%; }

.sal-coche {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: clamp(12px, 1.5vh, 18px);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 18px;
  background: rgba(10, 7, 22, .58);
  backdrop-filter: blur(10px);
}
.sal-der-cab { display: flex; align-items: baseline; gap: 10px; }
.sal-cuenta {
  margin-left: auto;
  font: 700 14px/1 Rubik, system-ui, sans-serif;
  color: var(--lime, #a8f425);
}
.sal-cuenta[data-lleno='true'] { color: var(--amber, #ffc447); }

.sal-carga {
  flex: 1;
  min-height: 0;
  display: grid;
  align-content: start;
  gap: 5px;
  overflow-y: auto;
  scrollbar-width: thin;
}
.sal-vacio {
  margin: 0;
  font: 400 12px/1.45 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
}

/* SIN CASA NO HAY BOTÓN, HAY UNA EXPLICACIÓN. Un botón gris que no dice por qué
   está gris se lee como una avería; una caja que dice de quién es el turno se
   lee como un turno. */
.sal-falta {
  display: grid;
  gap: 5px;
  padding: 16px 18px;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 14px;
  background: rgba(10, 7, 22, .8);
}
.sal-falta-t {
  margin: 0;
  font: 700 11px/1.2 Rubik, system-ui, sans-serif;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink, #f4f2ff);
}
.sal-falta-p {
  margin: 0;
  font: 400 12px/1.45 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
}

.sal-gordo-hueco { display: grid; }

.sal-gordo {
  padding: 18px;
  border-radius: 14px;
  border: 1px solid rgba(157, 107, 255, .55);
  background: linear-gradient(100deg, rgba(91, 47, 184, .88), rgba(40, 22, 84, .8));
  font: 700 13.5px/1.2 Rubik, system-ui, sans-serif;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink, #f4f2ff);
  cursor: pointer;
  transition: transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              background 160ms ease, box-shadow 160ms ease;
}
.sal-gordo:hover:not([disabled]), .sal-gordo:focus-visible { transform: translateY(-2px); }
/* Ya marcado listo: verde apagado, porque lo que queda es esperar. */
.sal-gordo[data-modo='yano'] {
  border-color: rgba(168, 244, 37, .4);
  background: rgba(168, 244, 37, .12);
  color: var(--lime, #a8f425);
}
/* Y COMENZAR PARTIDA en verde lleno: es el único botón de todo el menú que
   arranca una noche, y tiene que verse desde la puerta. */
.sal-gordo[data-modo='empezar'] {
  border-color: rgba(168, 244, 37, .6);
  background: linear-gradient(100deg, rgba(106, 163, 16, .95), rgba(60, 96, 8, .85));
  color: #f6ffe6;
  box-shadow: 0 12px 34px rgba(106, 163, 16, .32);
}
.sal-gordo[disabled] {
  cursor: default;
  border-color: rgba(255, 255, 255, .1);
  background: rgba(14, 10, 28, .6);
  color: var(--ink-faint, #6e678c);
}

/* --- Las otras vistas del centro --------------------------------------------- */

/* La rejilla de casas y la de caras, dentro del centro: sin el ancho de la
   ventana que las llevaba antes, tienen que ceñirse a su columna. */
.sal-catalogo .noc-rejilla,
.sal-catalogo .eqa-caras { padding-bottom: 4px; }

/* --- Apretadas -------------------------------------------------------------- */

/* APILADO SOLO CUANDO DE VERDAD NO CABE. Estaba en 1280 y se llevaba por delante
   a cualquier portátil normal: apilado, el lobby deja de caber en una pantalla y
   se convierte en una página que hay que bajar para encontrar el botón de salir.
   Con las tres columnas aguantando hasta 1080, eso solo le pasa a quien de
   verdad no tiene ancho.
   Y ahí SÍ se desplaza todo junto: la caja de dentro deja de recortar, porque lo
   que se desplaza ya no es el catálogo sino la página entera. */
@media (max-width: 1080px) {
  .sal-cuadro {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto 1fr;
    max-height: none;
    overflow-y: auto;
  }
  .sal-sello { grid-column: 1 / -1; }
  .sal-centro { grid-column: 1 / -1; grid-row: 2; }
  .sal-izq { grid-column: 1; grid-row: 3; }
  .sal-der { grid-column: 2; grid-row: 3; }
  .sal-vista { overflow: visible; }
  .sal-catalogo { overflow: visible; align-self: start; }
}
@media (max-width: 820px) {
  .sal-cuadro { grid-template-columns: 1fr; grid-template-rows: repeat(4, auto); }
  .sal-izq, .sal-der { grid-column: 1; }
  .sal-izq { grid-row: 3; }
  .sal-der { grid-row: 4; }
  .sal-fila { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
  .sal-cuadro, .sal-pj, .sal-carga-fila { animation: none; }
  .sal-pj-cara { animation: none; }
  .sal-vista[data-paso='sale'],
  .sal-vista[data-paso='entra'],
  .sal-vista[data-paso='entra'] .sal-cabeza,
  .sal-vista[data-paso='entra'] .sal-cabeza + * { animation: none; }
  .sal-b:hover, .sal-gordo:hover, .sal-todo:hover { transform: none; }
}

/* =============================================================================
   EL EQUIPAMIENTO, DENTRO DEL LOBBY
   El catálogo en el centro y lo elegido a la derecha, a la vez. Ver
   client/js/ui/menu-sala.js.

   LO ELEGIDO SE NUMERA Y SE COLOREA. El número de la esquina de la ficha es el
   mismo que el de su fila en la lista de la derecha, y comparten color: con
   dieciséis cosas en dos sitios, emparejarlas por el nombre obliga a leer, y por
   el número y el color no.
============================================================================= */

/* SE DESPLAZA DENTRO DE SU HUECO, NO CRECE.
   Iba centrado en su fila y eso le dejaba tomar el alto que quisiera: con el
   taller lleno, el catálogo empujaba la tira de noches fuera de sitio y el botón
   de LISTO se salía por abajo de la pantalla. Estirado ocupa su hueco y lo que
   sobra se desplaza aquí dentro, que es lo único que se mueve. */
.sal-catalogo {
  align-self: stretch;
  align-content: start;
  width: 100%;
  min-height: 0;
  /* SITIO PARA QUE LAS FICHAS SE LEVANTEN. Al pasar por encima suben cuatro
     píxeles, y sin este margen la caja de desplazamiento les cortaba la parte de
     arriba: la foto de la casa parecía desaparecer justo al ir a pincharla. */
  padding: 8px 4px 6px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}

.sal-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}

.sal-card {
  position: relative;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 5px;
  min-height: 132px;
  padding: 14px 10px;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 14px;
  background: rgba(10, 7, 22, .76);
  cursor: pointer;
  transition: transform 170ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              border-color 170ms ease, background 170ms ease, box-shadow 170ms ease;
}
.sal-card:hover:not([disabled]), .sal-card:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(157, 107, 255, .5);
  background: rgba(24, 17, 46, .86);
}
.sal-card[disabled] { cursor: default; opacity: .4; }
/* SALVO SI ES QUE TE LA HAS LLEVADO TÚ. Apagar igual «no tengo» y «ya la llevo»
   dejaba lo que sí llevas como lo más tenue de la pantalla: justo al revés. */
.sal-card[disabled][data-on='true'] { opacity: .92; }

/* ELEGIDO: borde de neón con su color, y de ahí sale también el número. Es lo
   que hace que se vea desde el otro lado de la pantalla cuáles llevas. */
.sal-card[data-on='true'] {
  border-color: var(--tono, #a8f425);
  background: color-mix(in srgb, var(--tono, #a8f425) 9%, rgba(10, 7, 22, .7));
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--tono, #a8f425) 45%, transparent),
    0 0 22px color-mix(in srgb, var(--tono, #a8f425) 26%, transparent);
}

.sal-card-n {
  font: 600 12.5px/1.25 Rubik, system-ui, sans-serif;
  text-align: center;
  color: var(--ink, #f4f2ff);
}
.sal-card-q {
  font: 400 10px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink-faint, #6e678c);
}

/* El número, en su chapa amarilla y sobresaliendo por la esquina: no es un dato
   de la ficha, es la etiqueta que la empareja con la lista de la derecha. */
.sal-card-num {
  position: absolute;
  top: -9px;
  right: -8px;
  display: grid;
  place-items: center;
  min-width: 26px;
  height: 26px;
  padding: 0 7px;
  border-radius: 8px;
  font: 700 13px/1 Rubik, system-ui, sans-serif;
  color: #1a1200;
  background: var(--amber, #ffc447);
  box-shadow: 0 4px 12px rgba(0, 0, 0, .5);
}
.sal-card-num[hidden] { display: none; }
/* UN GOLPE AL CONTAR TU CLIC. La ficha no se mueve y el número cambia en una
   esquina de veintiséis píxeles: sin el saltito, pinchar tres veces seguidas se
   siente exactamente igual que pinchar una. */
.sal-card-num[data-late='true'] {
  animation: sal-late 260ms var(--ease-out, cubic-bezier(.22, 1, .36, 1));
}
@keyframes sal-late {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.28); }
  100% { transform: scale(1); }
}

/* El hueco de «esto llegará»: dice que la lista va a crecer, que en un juego en
   obras es información y no adorno. */
.sal-card--pronto {
  border-style: dashed;
  border-color: rgba(255, 255, 255, .12);
  background: transparent;
  cursor: default;
}

/* --- La lista de la derecha ------------------------------------------------- */

.sal-der-p {
  margin: -4px 0 2px;
  font: 400 11.5px/1.4 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
}

.sal-carga-fila {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 9px 11px;
  border: 1px solid color-mix(in srgb, var(--tono, #a8f425) 34%, transparent);
  border-radius: 12px;
  background: color-mix(in srgb, var(--tono, #a8f425) 8%, rgba(10, 7, 22, .5));
  /* Entra desde la derecha: al subir algo se ve APARECER, y eso dice «se ha
     cargado» sin necesidad de un aviso. */
  animation: sal-entra 260ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both;
}
@keyframes sal-entra {
  from { opacity: 0; transform: translateX(14px); }
  to   { opacity: 1; transform: none; }
}
.sal-carga-num {
  display: grid;
  place-items: center;
  min-width: 26px;
  height: 22px;
  padding: 0 6px;
  border-radius: 7px;
  font: 700 11px/1 Rubik, system-ui, sans-serif;
  color: #1a1200;
  background: var(--amber, #ffc447);
}
.sal-carga-texto { display: grid; gap: 1px; min-width: 0; }
.sal-carga-n {
  font: 600 12px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink, #f4f2ff);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sal-carga-x {
  font: 700 10px/1 Rubik, system-ui, sans-serif;
  color: var(--tono, #a8f425);
}

.sal-quita {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 99px;
  background: rgba(255, 255, 255, .05);
  font: 700 14px/1 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.sal-quita:hover, .sal-quita:focus-visible {
  background: var(--danger, #ff5566);
  border-color: var(--danger, #ff5566);
  color: #fff;
}

/* El botón del equipo, cuando ESTÁS dentro: encendido, para que se vea que es
   por donde se vuelve. Sin esto, el catálogo es un sitio sin puerta. */
.sal-b[data-aqui='true'] {
  border-color: rgba(157, 107, 255, .85);
  background: linear-gradient(100deg, rgba(110, 60, 214, .8), rgba(52, 28, 104, .7));
  box-shadow: 0 8px 26px rgba(91, 47, 184, .34);
}
.sal-b[data-aqui='true'] .sal-b-i { color: #fff; background: rgba(255, 255, 255, .16); }

/* =============================================================================
   «¿SEGURO?»
   =============================================================================
   El cuadro de confirmar de los menús. Ver client/js/ui/preguntar.js.

   VA EN MEDIO Y OSCURECE TODO LO DEMÁS, que es lo contrario de lo que hace el
   resto del menú —donde la ilustración se ve siempre—. Aquí es a propósito: es
   el único momento en que hay UNA sola cosa que decidir, y dejar la casa
   asomando detrás invita a seguir mirándola en vez de contestar.

   Y EL «SÍ» GRAVE VA EN ROJO, pero no es el botón bonito: el que lleva el foco
   al abrirse es el de volver. Lo peligroso se puede pulsar, no se ofrece.
============================================================================= */
.preg {
  position: fixed;
  inset: 0;
  z-index: 900;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(4, 3, 10, .78);
  backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 180ms ease;
}
.preg[hidden] { display: none; }
.preg[data-on='true'] { opacity: 1; }

.preg-caja {
  width: min(440px, 100%);
  display: grid;
  gap: 14px;
  padding: 26px 26px 22px;
  border: 1px solid rgba(157, 107, 255, .32);
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(19, 15, 34, .97), rgba(9, 7, 18, .97));
  box-shadow: 0 30px 80px rgba(0, 0, 0, .7);
  text-align: center;
  transform: translateY(10px) scale(.97);
  transition: transform 220ms var(--ease-pop, cubic-bezier(.2, .9, .3, 1.2));
}
.preg[data-on='true'] .preg-caja { transform: none; }

.preg-t {
  margin: 0;
  font-family: var(--face-pixel);
  font-size: 26px;
  font-weight: 400;
  letter-spacing: .04em;
  color: var(--ink, #f4f2ff);
}
.preg-p {
  margin: 0;
  font: 400 14px/1.55 Rubik, system-ui, sans-serif;
  color: var(--ink-dim, #a79fc8);
}

.preg-botones { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 4px; }
.preg-b {
  padding: 12px 14px;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 12px;
  background: rgba(255, 255, 255, .05);
  color: var(--ink, #f4f2ff);
  font-family: var(--face-pixel);
  font-size: 17px;
  letter-spacing: .05em;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease, transform 140ms ease;
}
.preg-b:hover { background: rgba(255, 255, 255, .1); transform: translateY(-1px); }
/* El de volver es el que manda: borde de la marca y foco de salida. */
.preg-b--no { border-color: rgba(168, 244, 37, .38); }
.preg-b--no:hover { border-color: var(--lime, #a8f425); background: rgba(168, 244, 37, .12); }
.preg-b--grave {
  border-color: rgba(255, 85, 102, .4);
  color: #ff9aa6;
}
.preg-b--grave:hover {
  border-color: var(--danger, #ff5566);
  background: rgba(255, 85, 102, .16);
  color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .preg, .preg-caja { transition: none; }
}

/* =============================================================================
   EL PANEL DE AMIGOS: «EN ANTENA»
   =============================================================================
   Debajo de tu ficha y pegado a la derecha, que es donde la ilustración del
   fondo ya es bosque negro y se puede poner algo encima sin tapar la casa.
   Ver client/js/ui/menu-amigos.js.

   LA LUZ DE CADA UNO ES EL DATO, no un adorno: se lee el color antes que el
   nombre. Verde en el cuartel (a ese llamas), azul montando equipo (a ese
   llamas sabiendo que le robas), ámbar dentro de una casa (a ese no se le
   molesta) y apagado el que no está. Son cuatro y no dos porque el tercero
   —«está jugando»— es justo el que no hay que interrumpir.
============================================================================= */
.amg {
  grid-column: 2;
  grid-row: 2;
  justify-self: end;
  align-self: start;
  width: min(310px, 26vw);
  max-height: min(52vh, 460px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 14px 12px;
  border: 1px solid rgba(157, 107, 255, .22);
  border-radius: 16px;
  background: rgba(8, 6, 16, .74);
  backdrop-filter: blur(9px);
  animation: menu-entra 620ms 200ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)) both;
}

.amg-cabeza { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.amg-t {
  margin: 0;
  font-family: var(--face-pixel);
  font-size: 19px;
  font-weight: 400;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink, #f4f2ff);
}
.amg-cuantos {
  font: 700 10px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-faint, #6e678c);
}
.amg-cuantos[data-hay='true'] { color: var(--lime, #a8f425); }

.amg-lista {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-height: 0;
  overflow-y: auto;
  margin: 0 -6px;
  padding: 0 6px;
}

.amg-fila {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 8px;
  border-radius: 10px;
  transition: background 140ms ease;
}
.amg-fila:hover { background: rgba(255, 255, 255, .05); }

/* LA LUZ. Late solo la de quien está libre: un panel entero de puntos
   parpadeando es una guirnalda, y lo que hay que mirar es el que puede venir. */
.amg-luz {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ink-faint, #6e678c);
  box-shadow: none;
}
.amg-fila[data-sitio='libre'] .amg-luz {
  background: var(--lime, #a8f425);
  box-shadow: 0 0 10px rgba(168, 244, 37, .8);
  animation: amg-late 2.4s ease-in-out infinite;
}
.amg-fila[data-sitio='sala'] .amg-luz {
  background: var(--cyan, #35e0f0);
  box-shadow: 0 0 9px rgba(53, 224, 240, .6);
}
.amg-fila[data-sitio='casa'] .amg-luz {
  background: var(--amber, #ffc447);
  box-shadow: 0 0 9px rgba(255, 196, 71, .55);
}
.amg-fila[data-sitio='fuera'] { opacity: .5; }
@keyframes amg-late {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(.72); opacity: .55; }
}

.amg-quien { flex: 1; min-width: 0; display: grid; gap: 1px; }
.amg-nombre {
  font: 600 13px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink, #f4f2ff);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.amg-donde {
  font: 400 10px/1.2 Rubik, system-ui, sans-serif;
  color: var(--ink-faint, #6e678c);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Y LAS PETICIONES, EN MORADO Y ARRIBA. Es lo único de este panel que espera una
   respuesta tuya, así que no puede parecer un amigo más. */
.amg-fila--pide {
  background: rgba(157, 107, 255, .12);
  box-shadow: inset 0 0 0 1px rgba(157, 107, 255, .3);
}
.amg-fila--pide .amg-luz {
  background: var(--violet, #9d6bff);
  box-shadow: 0 0 10px rgba(157, 107, 255, .75);
  animation: amg-late 1.6s ease-in-out infinite;
}
.amg-fila--pide .amg-donde { color: var(--violet-soft, #c3a4ff); }
.amg-fila--espera { opacity: .6; }

.amg-invitar, .amg-si {
  flex: none;
  padding: 5px 11px;
  border: 1px solid rgba(168, 244, 37, .4);
  border-radius: 99px;
  background: rgba(168, 244, 37, .1);
  color: var(--lime, #a8f425);
  font: 700 10.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .05em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.amg-invitar:hover, .amg-si:hover { background: var(--lime, #a8f425); color: #0a1400; }

.amg-x {
  flex: none;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--ink-faint, #6e678c);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 140ms ease, background 140ms ease, color 140ms ease;
}
/* EL ASPA SOLO AL PASAR POR ENCIMA. Borrar a un amigo es lo más destructivo del
   panel y no puede estar pidiendo que lo pulses todo el rato; en un dispositivo
   sin ratón se queda puesta, que ahí no hay «pasar por encima». */
.amg-fila:hover .amg-x, .amg-x:focus-visible { opacity: 1; }
.amg-x:hover { background: rgba(255, 85, 102, .18); color: var(--danger, #ff5566); }
@media (hover: none) { .amg-x { opacity: .6; } }

.amg-nadie {
  margin: 6px 2px;
  font: 400 11.5px/1.5 Rubik, system-ui, sans-serif;
  color: var(--ink-faint, #6e678c);
}

/* --- AGREGAR AMIGO -----------------------------------------------------------
   ES EL ÚNICO BOTÓN DEL PANEL, así que se comporta como tal: ancho entero, en
   el verde de la marca y con su icono. Aquí estuvo una casilla de escribir con
   un «+» al lado, y era lo peor de las dos opciones — parecía un campo de
   formulario perdido al final de una lista, y encima agregaba a ciegas.

   Y ES LA PUERTA DE ENTRADA A TODO ESTO. Con la lista vacía —que es como está
   el panel el primer día— es literalmente lo único que se puede hacer en él,
   así que tiene que verse antes que nada: un botón tímido ahí abajo deja el
   panel pareciendo una lista rota en vez de una lista por empezar.

   EL ICONO ES UNA SILUETA CON UN «+», dibujada con CSS. Un emoji cambia de
   forma en cada sistema y aquí tiene que casar con el resto del panel. */
.amg-add-b {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  margin-top: 2px;
  padding: 11px 12px;
  border: 1px solid rgba(168, 244, 37, .42);
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(168, 244, 37, .16), rgba(168, 244, 37, .07));
  color: var(--lime, #a8f425);
  font-family: var(--face-pixel);
  font-size: 17px;
  letter-spacing: .05em;
  cursor: pointer;
  transition: background 160ms ease, color 160ms ease, transform 160ms var(--ease-out, cubic-bezier(.22, 1, .36, 1)),
              box-shadow 160ms ease;
}
.amg-add-b:hover, .amg-add-b:focus-visible {
  transform: translateY(-2px);
  background: var(--lime, #a8f425);
  color: #0a1400;
  box-shadow: 0 8px 22px rgba(168, 244, 37, .25);
}
.amg-add-b:active { transform: translateY(0); }

/* La silueta: una cabeza y unos hombros, con el «+» pegado en la esquina. */
.amg-add-icono {
  position: relative;
  flex: none;
  width: 17px;
  height: 17px;
}
.amg-add-icono::before {
  /* La cabeza. */
  content: '';
  position: absolute;
  top: 0;
  left: 2px;
  width: 8px;
  height: 8px;
  border: 1.8px solid currentColor;
  border-radius: 50%;
}
.amg-add-icono::after {
  /* Y los hombros: media elipse con el borde de abajo quitado. */
  content: '';
  position: absolute;
  bottom: 1px;
  left: 0;
  width: 12px;
  height: 8px;
  border: 1.8px solid currentColor;
  border-bottom: 0;
  border-radius: 7px 7px 0 0;
}
.amg-add-mas {
  position: absolute;
  right: -1px;
  bottom: 0;
  font-family: var(--face-ui);
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  /* Un filo del color del panel para que el «+» se despegue de los hombros. */
  text-shadow: 0 0 3px rgba(8, 6, 16, .95), 0 0 3px rgba(8, 6, 16, .95);
}
.amg-add-b:hover .amg-add-mas, .amg-add-b:focus-visible .amg-add-mas {
  text-shadow: 0 0 3px rgba(168, 244, 37, 1), 0 0 3px rgba(168, 244, 37, 1);
}

/* CUANDO NO TIENES A NADIE, EL BOTÓN LLAMA. Es el primer día de todo el mundo:
   la lista está vacía y esto es lo único que se puede hacer, así que respira
   despacio hasta que agregues al primero. Con alguien en la lista se queda
   quieto — a partir de ahí ya no es lo único, es una cosa más. */
.amg[data-solo='true'] .amg-add-b { animation: amg-llama 2.6s ease-in-out infinite; }
@keyframes amg-llama {
  0%, 100% { box-shadow: 0 0 0 0 rgba(168, 244, 37, 0); }
  50% { box-shadow: 0 0 0 4px rgba(168, 244, 37, .1); }
}
@media (prefers-reduced-motion: reduce) {
  .amg[data-solo='true'] .amg-add-b { animation: none; }
}

.amg-recado {
  margin: 0;
  font: 400 11px/1.4 Rubik, system-ui, sans-serif;
  color: var(--lime, #a8f425);
}
.amg-recado[data-bien='false'] { color: #ff9aa6; }

/* En pantallas bajas o estrechas el panel estorba más de lo que aporta: la
   columna de botones es lo que hay que poder pulsar. */
@media (max-height: 700px), (max-width: 1100px) {
  .amg { display: none; }
}

/* EL RÓTULO DE LAS SOLICITUDES, encima de las que hay que contestar.
   Estaban ahí arriba con su color morado pero sin decir qué eran: una fila más
   en otro tono, que había que leerse entera para enterarse. Con el rótulo y el
   número al lado se ve sin buscarlo, que es lo que hace falta para algo que
   espera una respuesta tuya. */
.amg-pendientes {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 2px 2px 4px;
  font: 700 9.5px/1 Rubik, system-ui, sans-serif;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--violet-soft, #c3a4ff);
}
.amg-cuantas {
  display: grid;
  place-items: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 99px;
  background: var(--violet, #9d6bff);
  color: #0a0714;
  font-size: 10px;
  line-height: 1;
}
