@font-face {
  font-family: 'CraftpixTiny';
  src: url('../assets/gui/TinyFontCraftpixPixel.otf') format('opentype');
  font-display: swap;
}

:root {
  --ink: #d8dcea;
  --dim: #8b93ad;
  --gold: #ffb347;
  --ember: #ff7a2f;
  --panel: rgba(12, 13, 22, .82);
  --line: rgba(255, 179, 71, .22);
  --c1: #7dd66b;
  --c2: #e8e8f0;
  --c3: #ff5fa8;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  width: 100%; height: 100%;
  overflow: hidden;
  background: #05050a;
  color: var(--ink);
  font-family: "Segoe UI", Roboto, system-ui, sans-serif;
  user-select: none;
}

.hidden { display: none !important; }

/* El canvas tiene resolucion de mundo y lo estira el compositor. */
#game {
  position: fixed; inset: 0;
  display: block;
  width: 100%; height: 100%;
  cursor: crosshair;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}

#vignette {
  position: fixed; inset: 0;
  pointer-events: none; z-index: 5;
  background: radial-gradient(ellipse at center,
    rgba(0, 0, 0, 0) 26%, rgba(0, 0, 0, .26) 52%,
    rgba(0, 0, 0, .55) 78%, rgba(0, 0, 0, .82) 100%);
}

#names { position: fixed; inset: 0; pointer-events: none; z-index: 8; }
.nameplate {
  position: absolute;
  transform: translate(-50%, -100%);
  font-size: 12px; font-weight: 600;
  white-space: nowrap;
  text-shadow: 0 0 3px #000, 0 0 6px #000, 0 1px 2px #000;
}

/* La lupa (Alt + raton): mini-ficha de lo que la intuicion alcanza a ver.
   Compacta y sin raton encima (pointer-events none): es un tooltip, no una
   ventana. Se ancla sobre la cabeza de lo mirado, como los nameplates. */
#lupa {
  position: fixed; z-index: 9; pointer-events: none;
  transform: translate(-50%, -115%);
  background: rgba(14, 10, 6, 0.92);
  border: 1px solid #6b4a22;
  padding: 5px 8px;
  font-size: 10px; letter-spacing: 0.5px; line-height: 1.7;
  color: #e8d9b0; text-align: left; white-space: nowrap;
}
#lupa b { color: #ffe294; }
#lupa .lupagris { color: #9a8b6b; }
#lupa .lupavioleta { color: #c77dff; }

/* El cartel del puesto del mercado (junto a la entrada del piso) y la
   ventana del tablon (2026-08-30). El cartel va anclado al mundo, como los
   nameplates; la ventana sigue el patron .uiwin de la casa. */
#mercadoTag {
  position: fixed; z-index: 7; pointer-events: none;
  transform: translate(-50%, -100%);
  font-size: 11px; font-weight: 600; letter-spacing: 1.5px;
  color: #ffd76a;
  text-shadow: 0 0 3px #000, 0 0 6px #000, 0 1px 2px #000;
}
#mercado .mercnota { font-size: 9px; color: #6b4a22; margin: 0 0 8px; }
#mercLista { max-height: 220px; overflow-y: auto; margin-bottom: 10px; }
#mercLista .mercoferta {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 2px; border-bottom: 1px solid rgba(107, 74, 34, 0.35);
  font-size: 11px;
}
#mercLista .mercoferta .crece { flex: 1; }
#mercLista .mercoferta .quien { display: block; font-size: 9px; color: #8a6a9a; }
#mercLista .mercoferta.mia .quien { color: #5a7a3a; }
#mercLista .mercoferta .precio { color: #a97817; white-space: nowrap; font-weight: 600; }
#mercLista .vacio { font-size: 10px; color: #8a7a5a; font-style: italic; }
#mercPublicar h4 { margin-top: 10px; }
#mercPublicar .mercfila { display: flex; gap: 6px; align-items: center; }
#mercPublicar select, #mercPublicar input {
  background: rgba(0, 0, 0, 0.18); color: #3a2a12;
  border: 1px solid #6b4a22; border-radius: 3px;
  font: inherit; font-size: 10px; padding: 4px 5px;
}
#mercPublicar input { width: 54px; }
#mercPublicar #mercOro { font-size: 10px; color: #6b4a22; margin: 6px 0 0; }

/* La bolsa en la ficha del heroe */
#invBolsa .bolsafila {
  display: flex; align-items: center; gap: 8px;
  padding: 3px 0; font-size: 11px;
}
#invBolsa .bolsafila .crece { flex: 1; }
#invBolsa h4 { margin-top: 12px; }

/* Boton chico del kit, para filas apretadas (bolsa, tablon del mercado) */
.uibtn.chica { font-size: 9px; padding: 3px 9px; }

/* ------------------------------------------------------------------ HUD */
#hud {
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 10;
  font-size: 13px;
}

#topbar {
  position: absolute; top: 12px; left: 50%;
  transform: translateX(-50%);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 5px 14px;
  letter-spacing: 1.6px;
  font-size: 11px;
  text-transform: uppercase;
  color: var(--dim);
  backdrop-filter: blur(4px);
}
#topbar #floorLabel { color: var(--gold); font-weight: 700; }
#topbar .sep { opacity: .4; margin: 0 2px; }

/* minimapa */
#minimap {
  position: absolute; top: 12px; right: 12px;
  width: 160px; height: 160px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: #07070d;
  image-rendering: pixelated;
  opacity: .92;
}
#minimap.off { display: none; }

/* vitales */
#vitals {
  position: absolute; bottom: 14px; left: 50%;
  transform: translateX(-50%);
  width: 268px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 7px 10px 8px;
  backdrop-filter: blur(4px);
}
.vrow { display: flex; justify-content: space-between; font-size: 10px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--dim); margin-bottom: 5px; }
#clsName { color: var(--gold); }
#hpwrap { position: relative; height: 14px; background: #12131f; border-radius: 2px; overflow: hidden; }
#hpfill { height: 100%; width: 100%; background: linear-gradient(90deg, #8e1d1d, #d64545 60%, #ff6b6b); transition: width .16s; }
#hpText { position: absolute; inset: 0; text-align: center; line-height: 14px; font-size: 10px; font-weight: 700; text-shadow: 0 1px 2px #000; }
/* experiencia: mas fina que la vida, para que no compitan */
#xpwrap {
  position: relative; height: 6px; margin-top: 3px;
  background: #10111c; border-radius: 2px; overflow: hidden;
}
#xpfill {
  height: 100%; width: 0;
  background: linear-gradient(90deg, #3d6ea8, #6fc3ff);
  box-shadow: 0 0 8px rgba(110, 195, 255, .5);
  transition: width .2s;
}
#xpText {
  position: absolute; inset: 0; text-align: center; line-height: 6px;
  font-size: 7px; letter-spacing: .5px; color: #cfe6ff; text-shadow: 0 1px 1px #000;
}
#stats { display: flex; justify-content: space-between; font-size: 10px; color: var(--dim); margin-top: 5px; letter-spacing: 1px; }
/* Que ninguna etiqueta se parta por dentro. Al entrar la quinta —las pocimas—
   la caja se quedo justa y "a media luz" se rompia en dos renglones, que
   descuadraba la barra entera. Antes cabian de sobra y no hacia falta. */
#stats span { white-space: nowrap; }
#goldLabel { color: var(--gold); }
#defLabel { color: #8fb6e8; }
/* Las pocimas, del verde del frasco: el mismo del boton tactil, para que sean
   la misma cosa mirando la barra o mirando el pulgar. */
#pocimaLabel { color: #6fe0a0; }

/* inventario */
/* ---------------------------------------------------------- ventanas del kit
   El marco es una sola imagen de 98x101 estirada con border-image: los 13 px
   de arriba son la barra de titulo verde, y el resto el borde rasgado del
   pergamino. Asi una misma pieza sirve para cualquier tamano de ventana. */
.uiwin {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  pointer-events: auto;
  image-rendering: pixelated;
  border-style: solid;
  border-width: 39px 24px 27px 21px;          /* 13/8/9/7 del arte, a 3x */
  border-image-source: url('../assets/ui/parts/frame.png');
  border-image-slice: 13 8 9 7 fill;
  border-image-repeat: stretch;
  filter: drop-shadow(0 18px 40px rgba(0, 0, 0, .75));
  color: #3a2a17;
  z-index: 30;
}
/* El titulo se pinta encima de la barra verde que ya trae el marco */
.uititle {
  position: absolute; top: -33px; left: 0; right: 0;
  text-align: center;
  font-size: 12px; letter-spacing: 3px; font-weight: 700;
  color: #10331f;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .28);
  pointer-events: none;
}
.uiclose {
  position: absolute; top: -8px; right: -18px;
  width: 26px; height: 26px;
  background: none; border: 0; cursor: pointer;
  color: #10331f; font-family: inherit; font-size: 12px; font-weight: 700;
  pointer-events: auto;
}
.uiclose:hover { color: #7a1616; }
.uibody { min-width: 300px; }

.uiwin h4 {
  font-size: 9px; letter-spacing: 2.5px; color: #6b4a22;
  margin: 0 0 6px; text-transform: uppercase;
}
.uiwin h4:not(:first-child) { margin-top: 14px; }

/* Casillas: la misma pieza de 16x16 del kit, a 3x */
.uislot {
  width: 48px; height: 48px; flex: none;
  background: url('../assets/ui/parts/slot.png') center / 100% 100% no-repeat;
  image-rendering: pixelated;
  display: grid; place-items: center;
  position: relative;
}
.uislot.big { width: 60px; height: 60px; }
.uislot .ico { transform: scale(2); }
.uislot.big .ico { transform: scale(2.6); }
.uislot .cnt {
  position: absolute; right: 2px; bottom: 0;
  font-size: 10px; font-weight: 700; color: #f5e6c8;
  text-shadow: 0 0 3px #000, 0 1px 0 #000;
}
.uislot .key {
  position: absolute; left: 3px; top: 0;
  font-size: 9px; font-weight: 700; color: #5b3c17;
}
.uislot.on { filter: brightness(1.15) drop-shadow(0 0 6px #ffcf7a); }
.uislot.vacia { filter: grayscale(.4) brightness(.9); }

.ico {
  display: block; width: 16px; height: 16px;
  image-rendering: pixelated;
  background-repeat: no-repeat;
}

/* La ficha del heroe es una sola columna: dentro solo hay estadisticas, la
   armadura si la lleva y un renglon de mejoras. */
.ficha { width: 280px; }

/* Cabecera: el heroe con su animacion de reposo y sus numeros al lado */
.heroblock { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 4px; }
.heroframe {
  width: 84px; height: 84px; flex: none;
  display: grid; place-items: center;
  background: rgba(92, 62, 28, .16);
  border: 2px solid rgba(92, 62, 28, .3);
  border-radius: 3px;
  box-shadow: inset 0 2px 10px rgba(60, 38, 12, .25);
}
#invPortrait { width: 76px; height: 76px; image-rendering: pixelated; }
.heroinfo { flex: 1; min-width: 0; }
.heroinfo > b { display: block; font-size: 14px; letter-spacing: 1px; line-height: 1.1; }
.heroinfo > span { display: block; font-size: 10px; color: #7a5a30; letter-spacing: 1.5px; margin-bottom: 5px; }
#invStats { list-style: none; margin: 0; }
#invStats li {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 10.5px; color: #7a5a30;
  border-bottom: 1px dotted rgba(90, 60, 25, .25);
  padding: 1px 0;
}
#invStats li b { color: #3a2a17; font-size: 11.5px; }

/* Karma y atributos, dentro de la ficha. Los renglones copian el aire de
   #invStats; lo unico nuevo son los botones + y −, chicos y a la derecha,
   como para tocarlos con el pulgar sin taparse el numero. */
#invAtributos { margin-top: 10px; border-top: 1px dotted rgba(90, 60, 25, .35); padding-top: 6px; }
#invKarmaStats { list-style: none; margin: 0 0 4px; }
#invKarmaStats li {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 10.5px; color: #7a5a30;
  border-bottom: 1px dotted rgba(90, 60, 25, .25);
  padding: 1px 0;
}
#invKarmaStats li b { color: #3a2a17; font-size: 11.5px; }
.atrfila {
  display: flex; align-items: center; gap: 6px;
  font-size: 10.5px; color: #7a5a30;
  border-bottom: 1px dotted rgba(90, 60, 25, .25);
  padding: 2px 0;
}
.atrfila span { flex: 1; }
.atrfila b { color: #3a2a17; font-size: 11.5px; min-width: 16px; text-align: right; }
.atrbtn {
  width: 20px; height: 20px; padding: 0; line-height: 1;
  font: inherit; font-size: 13px; cursor: pointer;
  color: #3a2a17; background: transparent;
  border: 1px solid rgba(90, 60, 25, .55); border-radius: 3px;
}
.atrbtn:not(:disabled):hover { background: rgba(90, 60, 25, .15); }
.atrbtn:disabled { opacity: .3; cursor: default; }

/* --- El foco del mando ------------------------------------------------------
   Donde esta apuntando el mando dentro de la ficha. Se pone y se quita desde
   js/main.js (`pintarFoco`) y solo existe jugando con mando: con raton o con el
   dedo no aparece nunca, porque ahi el foco es donde tengas la mano.

   No se usa `:focus` del navegador a proposito: el foco de verdad se lo lleva
   cualquier click y se quedaria un cerco puesto en un boton que ya nadie mira.
   El aro late despacio para que se encuentre de un vistazo en una ventana que
   es casi toda texto. */
.focopad {
  outline: 2px solid var(--gold, #ffcf7a);
  outline-offset: 2px;
  border-radius: 3px;
  animation: focopad 1.1s ease-in-out infinite;
}
@keyframes focopad {
  0%, 100% { outline-color: rgba(255, 207, 122, .55); }
  50% { outline-color: rgba(255, 207, 122, 1); }
}
/* Quien pide "menos animaciones" se queda con el cerco quieto, que sigue
   diciendo lo mismo. */
@media (prefers-reduced-motion: reduce) {
  .focopad { animation: none; outline-color: #ffcf7a; }
}
#invAtrPuntos { margin: 5px 0 0; font-size: 9.5px; letter-spacing: .5px; color: #7a5a30; }
/* La linea de atributos en la carta del menu de heroes */
.hsub.hatr { opacity: .8; }

.equiprow { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.equipinfo { display: flex; flex-direction: column; line-height: 1.35; min-width: 0; }
.equipinfo b { font-size: 12px; color: #3a2a17; }
.equipinfo span { font-size: 10px; color: #7a5a30; }

/* Las mejoras, en texto: cuantas llevas y cuales. Solo sale si hay alguna. */
.mejoras {
  margin: 10px 0 0;
  padding: 7px 9px;
  background: rgba(184, 134, 44, .16);
  border-left: 3px solid #b8862c;
  border-radius: 2px;
}
.mejoras b {
  display: block; font-size: 11.5px; color: #3a2a17;
  letter-spacing: 1px; margin-bottom: 3px;
}
.mejoras span { display: block; font-size: 10px; color: #7a5a30; line-height: 1.4; }

/* --- Los pactos que llevas, en la ficha ---------------------------------
   Ver shared/pactos.js. La ventana es de pergamino y los colores de los
   patrones estan pensados para la cripta —verde claro, naranja, celeste—, asi
   que aqui el color NO va en la letra, que se leeria fatal sobre el papel: va
   en una barrita a la izquierda de cada renglon. Se distingue igual de bien el
   patron de cada uno y el texto se sigue leyendo. */
#invPactos {
  margin-top: 10px;
  padding: 7px 9px;
  background: rgba(120, 70, 180, .13);
  border-left: 3px solid #7846b4;
  border-radius: 2px;
}
#invPactos.hidden { display: none; }
#invPactos b {
  display: block; font-size: 11.5px; color: #3a2a17;
  letter-spacing: 1px; margin-bottom: 4px;
}
#invPactos .unpacto {
  display: block; font-size: 10px; color: #7a5a30; line-height: 1.4;
  padding-left: 7px; margin-bottom: 2px;
  border-left: 3px solid var(--tono, #b8862c);
}
#invPactos .unpacto i {
  font-style: normal; font-weight: 700; color: #3a2a17;
  margin-right: 5px;
}
/* Los dobles no se eligen: aparecen. Van los primeros y marcados, porque son
   lo unico que puede estar haciendo algo que no te esperas. */
#invPactos .unpacto.doble {
  border-left-style: double; border-left-width: 4px;
  background: rgba(120, 70, 180, .12);
}

/* ------------------------------------------------------------------ ajustes */
.setrow { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.setlab { font-size: 11px; letter-spacing: 1px; color: #3a2a17; min-width: 118px; }
.setsep { height: 2px; background: rgba(90, 60, 25, .25); margin: 14px 0; }
.sethint { font-size: 10px; color: #7a5a30; }
.uiicon {
  width: 39px; height: 39px; flex: none;
  image-rendering: pixelated;
  background-repeat: no-repeat; background-position: center;
  background-size: 100% 100%;
}
.uiicon.music { background-image: url('../assets/ui/parts/icon_music.png'); }
.uiicon.sound { background-image: url('../assets/ui/parts/icon_sound.png'); }

/* Barra de volumen: los mismos segmentitos del kit, uno por tramo */
.segbar { display: flex; gap: 3px; cursor: pointer; }
.segbar .seg {
  width: 9px; height: 33px;
  background: url('../assets/ui/parts/seg_off.png') center / 100% 100% no-repeat;
  image-rendering: pixelated;
}
.segbar .seg.on { background-image: url('../assets/ui/parts/seg_on.png'); }
.segbar .seg:hover { filter: brightness(1.2); }

.uicheck {
  width: 33px; height: 36px; flex: none;
  background: url('../assets/ui/parts/check_off.png') center / 100% 100% no-repeat;
  image-rendering: pixelated;
  border: 0; cursor: pointer;
}
.uicheck.on { background-image: url('../assets/ui/parts/check_on.png'); }

.uibtn {
  min-width: 117px; height: 39px;
  background: url('../assets/ui/parts/btn.png') center / 100% 100% no-repeat;
  image-rendering: pixelated;
  border: 0; cursor: pointer;
  font-family: inherit; font-size: 11px; letter-spacing: 2px; font-weight: 700;
  color: #10331f;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
  padding-bottom: 3px;
}
.uibtn:hover { filter: brightness(1.08); }
.uibtn:active { background-image: url('../assets/ui/parts/btn_down.png'); }
.uibtn:disabled { filter: grayscale(.7) brightness(.85); cursor: default; }
.uibtn.wide { min-width: 210px; }
/* Salir de la sala se sale de la partida: conviene que no se pulse sin querer */
.uibtn.danger { filter: hue-rotate(-92deg) saturate(1.5); }
.uibtn.danger:hover { filter: hue-rotate(-92deg) saturate(1.7) brightness(1.1); }

/* ------------------------------------------------------------ menu de pausa
   Dos columnas: a la izquierda lo que se toca (volumen y resolucion) y a la
   derecha lo que se lee (controles y reglas). Asi cabe entero sin scroll y no
   hay que elegir entre ajustar el sonido o consultar una tecla. */
#pause { z-index: 45; }
.pausecols { display: flex; gap: 26px; }
.pausecol { width: 260px; }
.pausecol.reglas {
  width: 300px;
  border-left: 2px solid rgba(90, 60, 25, .18);
  padding-left: 24px;
}
#pauseHint { display: block; margin-top: 6px; min-height: 1.2em; }

/* Controles: la tecla a la izquierda y lo que hace a la derecha */
.klist, .rlist { list-style: none; margin: 0; }
.klist li {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 10.5px; color: #7a5a30;
  padding: 1.5px 0;
  border-bottom: 1px dotted rgba(90, 60, 25, .2);
}
.klist li b {
  flex: none; min-width: 96px;
  color: #3a2a17; font-size: 10.5px; letter-spacing: .3px;
}
.klist li span { flex: 1; }

.rlist li {
  font-size: 10.5px; color: #6b4f2a; line-height: 1.4;
  padding-left: 11px; position: relative; margin-bottom: 3px;
}
.rlist li::before {
  content: '·'; position: absolute; left: 2px; top: -1px;
  color: #b8862c; font-weight: 700; font-size: 13px;
}
.rlist li b { color: #3a2a17; }

.controls h4 {
  font-size: 9px; letter-spacing: 2.5px; text-transform: uppercase;
  color: var(--gold); margin: 12px 0 4px;
}
.controls ul.rules { flex-direction: column; align-items: center; gap: 3px; }
.controls ul.rules li { max-width: 46ch; text-align: center; }

/* barra del jefe */
#bossbar {
  position: absolute; top: 46px; left: 50%;
  transform: translateX(-50%);
  width: min(520px, 62vw);
  text-align: center;
}
#bossbar .bname {
  font-size: 11px; letter-spacing: 6px; color: #ff6b6b;
  text-shadow: 0 0 12px rgba(255, 60, 60, .6);
  margin-bottom: 4px;
}
#bossbar .bwrap {
  height: 11px;
  background: rgba(8, 6, 12, .88);
  border: 1px solid rgba(255, 80, 80, .45);
  border-radius: 2px;
  overflow: hidden;
}
#bossFill {
  display: block; height: 100%; width: 100%;
  background: linear-gradient(90deg, #6d0f2a, #d02f3a 55%, #ff7a4a);
  transition: width .2s;
}

/* Jefe intermedio: la misma barra en morado y algo mas estrecha, debajo de la
   del jefe de piso por si coinciden los dos. */
#elitebar {
  position: absolute; top: 46px; left: 50%;
  transform: translateX(-50%);
  width: min(400px, 52vw);
  text-align: center;
}
#bossbar:not(.hidden) ~ #elitebar { top: 88px; }
#elitebar .bname {
  font-size: 10px; letter-spacing: 5px; color: #c99bff;
  text-shadow: 0 0 12px rgba(150, 80, 255, .7);
  margin-bottom: 4px;
}
#elitebar .bwrap {
  height: 9px;
  background: rgba(8, 6, 12, .88);
  border: 1px solid rgba(170, 100, 255, .5);
  border-radius: 2px;
  overflow: hidden;
}
#eliteFill {
  display: block; height: 100%; width: 100%;
  background: linear-gradient(90deg, #35105e, #7b2fd0 55%, #c07aff);
  transition: width .2s;
}

/* ------------------------------------------------- encargos del Errante
   El rastreador va debajo del minimapa, en la esquina que ya se mira para
   orientarse. Verde y oro: los colores del mensajero, para que se lea de un
   vistazo que eso no es del jefe ni de la vida. */
#questbox {
  position: absolute; top: 180px; right: 12px;
  width: 190px;
  background: var(--panel);
  border: 1px solid rgba(182, 255, 122, .22);
  border-left: 3px solid #b6ff7a;
  border-radius: 3px;
  padding: 6px 9px 7px;
  backdrop-filter: blur(4px);
}
#questbox .qhead {
  font-size: 9px; letter-spacing: 3px; color: #8fc96a;
  text-transform: uppercase; margin-bottom: 3px;
}
#questbox .qname {
  font-size: 12px; color: #ffe066; line-height: 1.25; margin-bottom: 3px;
}
#questbox .qgoal { font-size: 11px; color: var(--ink); line-height: 1.3; }
#questbox .qwrap {
  height: 4px; margin: 5px 0 4px;
  background: rgba(8, 6, 12, .85);
  border: 1px solid rgba(182, 255, 122, .28);
  border-radius: 2px; overflow: hidden;
}
#questbox .qfill {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, #3d7a2a, #8fd44f 60%, #d9ff9a);
  transition: width .25s;
}
#questbox .qhint { font-size: 10px; color: var(--dim); line-height: 1.3; }
#questbox.hecho { border-left-color: #6b7a5c; opacity: .72; }
#questbox.hecho .qname { color: #9fb08a; text-decoration: line-through; }
/* Un unico latido dorado al tacharlo: el aviso de que eso ya esta hecho. */
#questbox.hecho { animation: qcumplido .55s ease-out 1; }
@keyframes qcumplido {
  0%   { box-shadow: 0 0 0 0 rgba(255, 224, 102, .55); }
  100% { box-shadow: 0 0 0 14px rgba(255, 224, 102, 0); }
}
/* Y se va solo: el rastreador cumplido deja la esquina libre. */
#questbox.yendose {
  opacity: 0;
  transform: translateX(18px) scale(.96);
  transition: opacity .6s ease, transform .6s ease;
  pointer-events: none;
}

/* Lo que dice el Errante: una linea grande en el centro, un rato, y se va */
/* ------------------------------------------------------- globos de charla
   El Errante y el Caballero Carmesi hablaban en dos paneles plantados en medio
   de la pantalla: uno arriba, ancho de 620px, y otro abajo de 560. Entre los
   dos, los vitales y la barra de armas, quedaba una rendija para ver la
   mazmorra —y lo que dicen no es urgente, es ambiente—.

   Ahora hablan como habla la gente: un globo pegado encima de su cabeza, con su
   pico apuntandoles, que se mueve con ellos porque main.js le pone el sitio en
   cada fotograma (lo mismo que hace con los nombres de los companeros). Ocupan
   un cuarto de lo que ocupaban y ademas se ve QUIEN habla, que antes habia que
   deducirlo por el color del recuadro.

   El pico se apaga (`.sinpico`) cuando quien habla se ha salido de la pantalla
   y el globo se ha tenido que quedar pegado al borde: un pico apuntando a un
   sitio donde no hay nadie se lee como un fallo de dibujo. */
.globo {
  position: absolute;
  transform: translate(-50%, -100%);
  max-width: min(300px, 46vw);
  border-radius: 7px;
  padding: 7px 11px 8px;
  animation: toastIn .22s ease-out;
  backdrop-filter: blur(3px);
  filter: drop-shadow(0 3px 7px rgba(0, 0, 0, .75));
}
/* El pico: un triangulo pegado al borde de abajo, en el centro. El color sale
   de `--globo`, que pone cada globo con el suyo, para no repetir aqui el fondo
   de cada uno en las cuatro combinaciones de arriba/abajo. */
.globo::after {
  content: '';
  position: absolute; left: 50%; bottom: -8px;
  margin-left: -7px;
  border: 7px solid transparent;
  border-top: 9px solid var(--globo);
  border-bottom-width: 0;
}
/* Dado la vuelta: cuelga por debajo de los pies y el pico apunta hacia arriba.
   Pasa cuando quien habla esta en lo alto de la pantalla y el globo no cabe
   encima; antes de recortarlo contra el techo, mejor ponerlo debajo. */
.globo.abajo { transform: translate(-50%, 0); }
.globo.abajo::after {
  bottom: auto; top: -8px;
  border-top: 0;
  border-bottom: 9px solid var(--globo);
}
.globo.sinpico::after { display: none; }

#errante {
  --globo: rgba(10, 14, 10, .93);
  background: var(--globo);
  border: 1px solid rgba(182, 255, 122, .34);
  text-align: center;
}
#errante b {
  display: block; font-size: 9px; letter-spacing: 2.5px;
  color: #b6ff7a; text-transform: uppercase; margin-bottom: 3px;
}
#errante span { font-size: 12px; color: #efe8d6; line-height: 1.35; font-style: italic; }

/* ------------------------------------------- el Caballero Carmesi cuenta algo
   Otro globo, rojo como el, con la barra de tiempo abajo: mientras corre esta
   hablando, y cuando se acaba es cuando se decide si te da algo o te ataca.
   Saber cuanto queda es parte del nervio.

   Es algo mas ancho que el del Errante porque aqui hay dos parrafos que leer,
   pero ya no es un panel de 620px cruzado por delante de la mazmorra. */
#tale {
  --globo: rgba(16, 8, 8, .95);
  background: var(--globo);
  border: 1px solid rgba(255, 106, 82, .38);
  max-width: min(330px, 52vw);
}
#tale .tquien {
  font-size: 9px; letter-spacing: 3px; color: #ff8a6a;
  text-shadow: 0 0 12px rgba(255, 70, 50, .55);
  margin-bottom: 2px;
}
#tale .ttitulo {
  font-size: 12px; color: var(--gold); font-style: italic; margin-bottom: 5px;
}
#tale .ttexto { font-size: 11.5px; color: #efe6da; line-height: 1.45; }
#tale .ttexto p { margin: 0 0 7px; }
#tale .ttexto p:last-child { margin-bottom: 0; }
/* La linea del desenlace: verde si reparte, roja si se tuerce */
#tale .tfinal {
  font-size: 12px; margin-top: 7px; font-weight: 700; letter-spacing: .5px;
  display: none;
}
#tale.bendice .tfinal { display: block; color: #9fe07a; }
#tale.traiciona .tfinal { display: block; color: #ff6a52; }
#tale .twrap {
  height: 3px; margin-top: 8px;
  background: rgba(255, 255, 255, .08);
  border-radius: 2px; overflow: hidden;
}
#tale .tfill {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, #7a2a1c, #ff6a52);
}
#tale.bendice .twrap, #tale.traiciona .twrap { display: none; }

/* ------------------------------------------------------- barra de accion
   La barra de madera del kit, abajo en el centro, con una casilla por arma.
   Antes las armas eran una lista de texto en la esquina; ahora se leen de un
   vistazo por el icono, como en cualquier juego con barra de habilidades. */
/* Abajo a la derecha, en su esquina. El centro lo ocupa el panel de vida y la
   izquierda el chat, asi que aqui no se pisa con nada. */
#actionbar {
  position: absolute; right: 12px; bottom: 12px;
  padding: 9px 12px 10px;
  image-rendering: pixelated;
  border-style: solid;
  border-width: 12px 21px;
  border-image-source: url('../assets/ui/parts/bar.png');
  border-image-slice: 4 7 4 7 fill;
  border-image-repeat: stretch;
  pointer-events: auto;
}
#weapons { display: flex; gap: 8px; }
/* Cada arma es una casilla oscura del kit con su icono, su tecla y su nombre
   debajo. La activa se enciende; las demas quedan apagadas. */
.wslot {
  width: 66px; height: 57px; flex: none;
  background: url('../assets/ui/parts/slot_dark.png') center / 100% 100% no-repeat;
  image-rendering: pixelated;
  position: relative;
  display: grid; place-items: center;
  cursor: pointer;
  opacity: .62;
  transition: .14s;
}
.wslot .ico { transform: scale(2.2); }
.wslot.on { opacity: 1; filter: drop-shadow(0 0 7px var(--gold)) brightness(1.1); }
.wslot .wkey {
  position: absolute; left: 4px; top: 1px;
  font-size: 9px; font-weight: 700; color: #d8c39a;
  text-shadow: 0 1px 0 #000;
}
.wslot.on .wkey { color: var(--gold); }
.wslot .wname {
  position: absolute; left: 0; right: 0; bottom: -13px;
  text-align: center;
  font-size: 8.5px; letter-spacing: .4px; color: var(--dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wslot.on .wname { color: #f0e0c0; }
.wslot .wcd {
  position: absolute; right: 4px; bottom: 2px;
  font-size: 8px; color: #cdb489; text-shadow: 0 1px 0 #000;
}
/* Las curaciones se distinguen de un vistazo de lo que hace dano */
.wslot.heal.on { filter: drop-shadow(0 0 7px #6fe0a0) brightness(1.1); }
.wslot.heal .wname { color: #9ff0bd; }
#actionbar { padding-bottom: 22px; }

/* avisos */
#toast {
  position: absolute; top: 56px; left: 50%;
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.toast-item {
  background: rgba(12, 13, 22, .9);
  border-left: 2px solid var(--gold);
  padding: 5px 12px; font-size: 12px;
  border-radius: 2px;
  animation: toastIn .25s ease-out;
}
@keyframes toastIn { from { opacity: 0; transform: translateY(-6px); } }

#prompt {
  position: absolute; bottom: 92px; left: 50%;
  transform: translateX(-50%);
  background: rgba(12, 13, 22, .9);
  border: 1px solid var(--line);
  padding: 5px 14px; border-radius: 3px;
  font-size: 12px;
}
#prompt b { color: var(--gold); }

/* chat */
#chatbox { position: absolute; left: 12px; bottom: 12px; width: 300px; pointer-events: none; }
#chatlog { display: flex; flex-direction: column; gap: 2px; margin-bottom: 5px; max-height: 130px; overflow: hidden; }
#chatlog div { font-size: 12px; background: rgba(8, 9, 16, .72); padding: 2px 7px; border-radius: 2px; width: fit-content; max-width: 100%; }
#chatlog b { color: var(--gold); }
#chatinput {
  width: 100%; display: none;
  background: rgba(8, 9, 16, .95);
  border: 1px solid var(--line);
  color: var(--ink); padding: 6px 9px; font-size: 12px;
  border-radius: 3px; outline: none;
  pointer-events: auto;
  font-family: inherit;
}
#chatinput.on { display: block; }

/* caido */
#downed {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at center, rgba(80, 0, 0, .18), rgba(0, 0, 0, .55));
  text-align: center;
}
#downed h2 { font-size: 30px; letter-spacing: 6px; color: #ff5c5c; text-shadow: 0 0 22px rgba(255, 60, 60, .5); }
#downed p { color: var(--dim); margin-top: 6px; font-size: 13px; }
#downbar { width: 220px; height: 5px; background: #1a1020; margin-top: 14px; border-radius: 3px; overflow: hidden; }
#downbar i { display: block; height: 100%; width: 0; background: #5ee08a; }

/* ------------------------------------------------------ inicio del juego */
/* Puerta previa: el navegador bloquea el audio hasta que hay un gesto del
   usuario, asi que el sello del estudio arranca con el primer clic. */
#gate {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  background: #000;
  cursor: pointer;
}
#gate span {
  font-size: 11px; letter-spacing: 6px; color: #6a6f85;
  animation: gatePulse 1.9s ease-in-out infinite;
}
@keyframes gatePulse {
  0%, 100% { opacity: .35; }
  50% { opacity: 1; color: #b9a6ff; text-shadow: 0 0 18px rgba(150, 110, 255, .55); }
}

/* Sello del estudio */
#splash {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  background: #000;
  overflow: hidden;
  cursor: pointer;
}
#splashLogo {
  width: min(72vw, 62vh * 1.5);
  max-height: 76vh;
  object-fit: contain;
  opacity: 0;
  animation:
    logoIn 1.5s cubic-bezier(.16, .84, .3, 1) .15s forwards,
    logoFloat 5s ease-in-out 1.65s infinite;
  will-change: transform, opacity;
}
@keyframes logoIn {
  0% { opacity: 0; transform: scale(1.22) translateY(10px); filter: blur(9px) brightness(2.2); }
  45% { opacity: 1; }
  100% { opacity: 1; transform: scale(1) translateY(0); filter: blur(0) brightness(1); }
}
@keyframes logoFloat {
  0%, 100% { transform: scale(1) translateY(0); }
  50% { transform: scale(1.014) translateY(-6px); }
}
/* Halo que late detras del cubo */
.splash-glow {
  position: absolute; width: 68vmin; height: 68vmin;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(150, 80, 255, .30), rgba(120, 60, 255, .08) 45%, transparent 70%);
  opacity: 0;
  animation: glowIn 2.6s ease-out .1s forwards;
  pointer-events: none;
}
@keyframes glowIn {
  0% { opacity: 0; transform: scale(.5); }
  40% { opacity: 1; transform: scale(1.06); }
  100% { opacity: .75; transform: scale(1); }
}
/* Barrido de luz que cruza el logo una vez */
.splash-sweep {
  position: absolute; top: -30%; left: -60%;
  width: 34%; height: 160%;
  background: linear-gradient(90deg, transparent, rgba(200, 170, 255, .16), rgba(255, 255, 255, .30), rgba(200, 170, 255, .16), transparent);
  transform: rotate(14deg);
  mix-blend-mode: screen;
  pointer-events: none;
  animation: sweep 1.5s cubic-bezier(.4, 0, .2, 1) .95s 1 both;
}
@keyframes sweep {
  0% { left: -60%; opacity: 0; }
  18% { opacity: 1; }
  82% { opacity: 1; }
  100% { left: 128%; opacity: 0; }
}

/* ----------------------------------------------------------------- la intro
   Seis laminas con el texto ya dibujado dentro, diez segundos cada una. La
   imagen va en `contain` sobre negro: llevan el texto quemado abajo, asi que
   recortarlas para llenar la pantalla se comeria justo lo que hay que leer.

   El boton SALTAR esta siempre visible desde el primer segundo. Una intro que
   no se puede saltar se odia a la segunda partida. */
#intro {
  position: fixed; inset: 0; z-index: 59;
  background: #000;
  animation: descIn .3s ease-out both;
}
/* La lamina se ancla por los CUATRO lados, dejando libre la franja de abajo
   para SALTAR y los puntos.

   Se hace asi y no con un `max-height: 100%` centrado porque el porcentaje se
   resuelve contra una caja que a su vez se estaba midiendo por su contenido:
   la imagen se salia por abajo y el boton acababa plantado encima del texto,
   que va quemado justo ahi y es lo unico que hay que poder leer.

   Tampoco vale anclarla por los cuatro lados: en una imagen, `width: auto` es
   su tamano de verdad, no "lo que digan las anclas", asi que salia a tamano
   completo. Con una altura calculada el hueco queda fijo y `contain` centra la
   lamina dentro sin deformarla. */
#introImg {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: calc(100% - 58px);
  object-fit: contain;
  image-rendering: pixelated;
  /* SIN fill-mode y con los dos fotogramas escritos, a proposito. Con solo el
     `from` y `fill: both` el navegador se queda con ese unico fotograma tambien
     al terminar, y la lamina se quedaria en opacidad 0: la intro entera en
     negro. Asi el estado normal de la imagen es "visible", y la animacion solo
     es el adorno de entrada: si no llegara a correr, se ve igual. */
  animation: introFade .9s ease-out;
}
@keyframes introFade {
  from { opacity: 0; transform: scale(1.015); }
  to   { opacity: 1; transform: none; }
}

/* Barra de tiempo de la lamina, arriba del todo y muy discreta */
#introBar {
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: rgba(255, 255, 255, .08);
}
#introBar i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, #7a5a20, var(--gold));
}
/* Un punto por lamina, para saber cuanto queda de historia */
#introDots {
  position: absolute; bottom: 48px; left: 50%; transform: translateX(-50%);
  display: flex; gap: 7px;
}
#introDots i {
  width: 7px; height: 7px; border-radius: 50%;
  background: rgba(255, 255, 255, .22);
  transition: background .25s, transform .25s;
}
#introDots i.on { background: var(--gold); transform: scale(1.25); }
#introSkip {
  position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%);
  background: rgba(10, 10, 16, .72);
  border: 1px solid rgba(255, 255, 255, .22);
  color: #e8e2d2;
  font-family: inherit; font-size: 12px; letter-spacing: 3px;
  padding: 7px 22px; border-radius: 3px; cursor: pointer;
}
#introSkip:hover { border-color: var(--gold); color: var(--gold); }

@keyframes descIn { from { opacity: 0; } to { opacity: 1; } }
/* Portada con START.

   La lamina va en `contain`: lleva el rotulo del juego arriba del todo y el
   grupo de heroes abajo, asi que recortarla para llenar la pantalla se comeria
   justo lo que hay que ver. Lo que sobra a los lados se queda en negro, que es
   el color de todo lo demas.

   El START no va en el centro —ahi esta el encapuchado— sino al pie, sobre el
   empedrado. */
#title {
  position: fixed; inset: 0; z-index: 55;
  display: grid; place-items: end center;
  padding-bottom: 5vh;
  background: #000 url('../assets/gui/portada.png') center / contain no-repeat;
  animation: titleIn 1.1s ease-out both;
}
@keyframes titleIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
#startBtn {
  /* El centro exacto de la portada esta despejado: ahi cae el boton */
  font-family: inherit;
  font-size: clamp(20px, 3.4vmin, 34px);
  letter-spacing: 12px; font-weight: 800;
  color: #e8dcff;
  background: rgba(10, 6, 22, .34);
  border: 1px solid rgba(170, 130, 255, .45);
  border-radius: 3px;
  padding: 12px 34px 12px 46px;
  cursor: pointer;
  backdrop-filter: blur(2px);
  text-shadow: 0 0 22px rgba(150, 110, 255, .9), 0 0 46px rgba(90, 60, 200, .6);
  box-shadow: 0 0 34px -6px rgba(140, 90, 255, .6), inset 0 0 22px -8px rgba(160, 120, 255, .8);
  animation: startPulse 2.1s ease-in-out infinite;
  transition: transform .16s, border-color .16s;
}
#startBtn:hover {
  transform: scale(1.06);
  border-color: rgba(210, 180, 255, .9);
}
@keyframes startPulse {
  0%, 100% { opacity: .82; }
  50% { opacity: 1; }
}

/* ----------------------------------------------------------------- menu

   Negro y nada mas. La eleccion de personaje no lleva degradados ni brasas de
   fondo a proposito: lo unico que tiene que brillar ahi son los diez heroes y
   el rotulo del juego. */
#menu {
  position: fixed; inset: 0; z-index: 40;
  background: #000;
}

/* Los dos pasos ocupan la pantalla entera, uno cada vez. Ruedan por dentro por
   si la pantalla es muy baja, pero estan pensados para no tener que rodar. */
.paso {
  position: absolute; inset: 0;
  overflow-y: auto;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 14px;
  padding: 14px;
  text-align: center;
  animation: pasoEntra .28s ease-out both;
}
@keyframes pasoEntra {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* El rotulo del juego, en imagen. Es el mismo dibujo de la portada recortado,
   asi que la eleccion de personaje y la pantalla de inicio se reconocen como la
   misma cosa sin tener que repetir la lamina entera. */
#menuLogo {
  width: min(560px, 76vw);
  max-height: 22vh;
  object-fit: contain;
  image-rendering: auto;
  filter: drop-shadow(0 0 26px rgba(255, 90, 20, .35));
  pointer-events: none;
  user-select: none;
}

/* --- la cuenta de Google, arriba a la derecha ---------------------------
   Sale SIEMPRE, con sesion y sin ella, porque lo que se viene a mirar aqui es
   exactamente eso: si lo que subas de nivel se va a quedar guardado en tu
   cuenta o solo en este aparato. */
#cuenta {
  position: absolute; top: 10px; right: 12px;
  display: flex; align-items: center; gap: 8px;
  z-index: 3;
}
#cuentaEstado {
  font-size: 10.5px; letter-spacing: 1px; color: var(--dim);
  max-width: 34vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#cuentaEstado b { color: var(--gold); }
#cuentaEstado.dentro::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px; margin-right: 6px;
  border-radius: 50%;
  background: #6fe0a0;
  box-shadow: 0 0 8px rgba(111, 224, 160, .9);
}
#cuenta button {
  background: rgba(12, 14, 24, .9);
  border: 1px solid rgba(255, 179, 71, .28);
  color: var(--dim);
  padding: 7px 12px; border-radius: 4px; cursor: pointer;
  font-family: inherit; font-size: 9.5px; letter-spacing: 1.4px; font-weight: 600;
  transition: .15s;
}
#cuenta button:hover { border-color: var(--gold); color: var(--ink); }
#cuenta button:disabled { opacity: .5; cursor: wait; }

/* --- el pie del paso 1: tu nombre y adelante --------------------------- */
.pasopie { display: flex; gap: 10px; justify-content: center; align-items: center; flex-wrap: wrap; }
#elegirBtn {
  background: linear-gradient(#7a2d10, #4a1a08);
  color: #ffe9d0;
  border: 1px solid #c2622b;
  padding: 11px 34px; font-size: 14px; letter-spacing: 4px; font-weight: 700;
  border-radius: 4px; cursor: pointer; font-family: inherit;
  box-shadow: 0 6px 22px -8px rgba(255, 130, 50, .6);
  transition: .15s;
}
#elegirBtn:hover { filter: brightness(1.16); }

/* --- el paso 2 ---------------------------------------------------------- */
#volverBtn {
  position: absolute; top: 10px; left: 12px;
  background: none; border: none;
  color: var(--dim); font-family: inherit;
  font-size: 10.5px; letter-spacing: 2px; cursor: pointer;
  padding: 8px 6px;
}
#volverBtn:hover { color: var(--gold); }

.paso2-inner {
  width: min(560px, 92vw);
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
#paso2Quien {
  font-size: clamp(15px, 3.2vw, 22px);
  letter-spacing: 4px; font-weight: 800; color: #f4e6cf;
  text-shadow: 0 0 26px rgba(255, 140, 40, .3);
}
#paso2Quien b { color: var(--gold); }
#paso2Quien span { display: block; font-size: 10px; letter-spacing: 2px; color: var(--dim); margin-top: 5px; font-weight: 400; }

.fields { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.fields input {
  background: rgba(10, 11, 20, .9);
  border: 1px solid rgba(255, 179, 71, .22);
  color: var(--ink); padding: 8px 12px; width: 172px;
  border-radius: 3px; font-size: 13px; font-family: inherit;
  outline: none; letter-spacing: 1px; text-align: center;
}
.fields input:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(255, 179, 71, .1); }

/* Pantalla completa o ventana */
.modebtn {
  background: rgba(10, 11, 20, .9);
  border: 1px solid rgba(255, 179, 71, .22);
  color: var(--dim);
  padding: 8px 14px; border-radius: 3px; cursor: pointer;
  font-family: inherit; font-size: 11px; letter-spacing: 1.4px;
  transition: .15s;
}
.modebtn:hover { border-color: var(--gold); color: var(--ink); }

/* Que se va a hacer al pulsar, dicho en una linea */
.nethint {
  font-size: 10.5px; letter-spacing: .5px; color: var(--dim);
  min-height: 1.3em; line-height: 1.4;
}
.nethint b { color: var(--gold); letter-spacing: 1px; }
.nethint.err { color: #e8836f; }

/* ------------------------------------------------- rueda de personajes
   Uno grande en el centro y los vecinos escorados y encogidos. El nombre y la
   descripcion van ENCIMA del sprite, que es donde se mira. Con diez heroes una
   fila de miniaturas no luce ninguno; asi se ve uno de verdad. */
/* Ancha a proposito, para que quepan los vecinos del elegido. La centra el
   propio paso, que es un flex en columna con `align-items: center`; el apano de
   `left: 50%` + `translateX(-50%)` que habia aqui era de cuando la rueda colgaba
   de una columna de 560 px, y con el paso nuevo la corria 176 px a la derecha. */
#wheel {
  position: relative;
  width: min(900px, 96vw);
  user-select: none; touch-action: pan-y;
}
#wheelName {
  font-size: clamp(16px, 2.6vw, 24px);
  letter-spacing: 7px; font-weight: 800;
  text-shadow: 0 0 22px currentColor;
  line-height: 1.1;
}
#classDesc {
  min-height: 2.6em; margin: 4px auto 0; max-width: 46ch;
  font-size: 11.5px; letter-spacing: .6px; color: var(--dim);
  line-height: 1.35;
}

#wheelTrack {
  position: relative; height: 150px;
  display: flex; align-items: center; justify-content: center;
}
#classes { position: relative; width: 100%; height: 100%; }

.ccard {
  position: absolute; left: 50%; top: 8px;
  width: 128px; height: 128px;
  background: none; border: 0; padding: 0;
  cursor: pointer;
  filter: grayscale(.7) brightness(.6);
  transition: transform .24s cubic-bezier(.22, .61, .36, 1), opacity .24s, filter .24s;
}
.ccard canvas {
  width: 128px; height: 128px;
  image-rendering: pixelated; display: block;
}
.ccard:hover { filter: grayscale(.35) brightness(.85); }
/* El elegido va a color, con su halo y flotando un poco */
.ccard.sel {
  filter: grayscale(0) brightness(1.08) drop-shadow(0 0 16px var(--cc));
  animation: heroeFlota 3.2s ease-in-out infinite;
}
@keyframes heroeFlota {
  0%, 100% { top: 8px; }
  50% { top: 1px; }
}

.wheelarrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 34px; height: 46px;
  background: rgba(10, 11, 20, .6);
  border: 1px solid rgba(255, 179, 71, .22);
  border-radius: 4px;
  color: var(--gold); font-size: 13px; cursor: pointer;
  z-index: 20; transition: .15s;
}
#wheelPrev { left: 0; }
#wheelNext { right: 0; }
.wheelarrow:hover { background: rgba(30, 22, 12, .9); border-color: var(--gold); }

/* Puntitos: cuantos hay y por cual vas */
#wheelDots { display: flex; gap: 6px; justify-content: center; margin-top: 4px; }
#wheelDots i {
  width: 6px; height: 6px; border-radius: 50%;
  background: rgba(255, 255, 255, .18);
  cursor: pointer; transition: .16s;
}
#wheelDots i:hover { background: rgba(255, 255, 255, .4); }
#wheelDots i.on { background: var(--cc); box-shadow: 0 0 8px var(--cc); transform: scale(1.5); }

#wheelStats {
  display: flex; gap: 18px; justify-content: center; margin-top: 8px;
  font-size: 10px; letter-spacing: 1.6px; text-transform: uppercase;
  color: var(--dim);
}
#wheelStats b { color: var(--ink); font-size: 12px; letter-spacing: 0; }

#playBtn {
  background: linear-gradient(#c2661d, #8e3f10);
  color: #fff6e8; border: 1px solid #e0913f;
  padding: 11px 34px; font-size: 13px; letter-spacing: 3px; font-weight: 700;
  border-radius: 4px; cursor: pointer; font-family: inherit;
  box-shadow: 0 6px 22px -8px rgba(255, 130, 40, .7);
  transition: .15s;
}
#playBtn:hover { filter: brightness(1.14); }
#playBtn:disabled { opacity: .5; cursor: wait; }

.playrow { display: flex; align-items: center; justify-content: center; gap: 16px; flex-wrap: wrap; }
.offbox { display: flex; align-items: center; gap: 10px; }
/* Jugando sin servidor este es EL boton de bajar, no un apano de al lado, asi
   que tiene el mismo cuerpo que ENTRAR. */
#soloBtn {
  background: linear-gradient(#c2661d, #8e3f10);
  color: #fff6e8; border: 1px solid #e0913f;
  padding: 11px 34px; font-size: 13px; letter-spacing: 3px; font-weight: 700;
  border-radius: 4px; cursor: pointer; font-family: inherit;
  box-shadow: 0 6px 22px -8px rgba(255, 130, 40, .7);
  transition: .15s;
}
#soloBtn:hover { filter: brightness(1.14); }
#soloBtn:disabled { opacity: .5; cursor: wait; }
.offbox label {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; letter-spacing: 1.2px; text-transform: uppercase; color: var(--dim);
}
.offbox input[type=range] { width: 76px; accent-color: var(--ember); }
.offbox b { color: var(--gold); min-width: 14px; }

#status { font-size: 12px; min-height: 16px; color: var(--dim); }
#status.err { color: #ff7a7a; }

.controls { color: var(--dim); }
.controls summary {
  font-size: 10px; letter-spacing: 2.4px; text-transform: uppercase;
  cursor: pointer; opacity: .75; list-style: none;
}
.controls summary::-webkit-details-marker { display: none; }
.controls summary::before { content: '▸ '; }
.controls[open] summary::before { content: '▾ '; }
.controls summary:hover { opacity: 1; color: var(--gold); }
.controls ul {
  list-style: none; display: flex; flex-wrap: wrap;
  gap: 4px 16px; justify-content: center; margin-top: 10px;
}
.controls li { font-size: 11px; }
.controls p { font-size: 11px; margin-top: 8px; }
.controls b { color: var(--ink); }

/* ---------------------------------------------------------------- carga */
#loading {
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  background: #05050a;
}
.load-inner { text-align: center; width: 260px; }
.torch {
  width: 10px; height: 10px; margin: 0 auto 18px;
  border-radius: 50%;
  background: var(--ember);
  box-shadow: 0 0 26px 10px rgba(255, 122, 47, .55), 0 0 60px 22px rgba(255, 90, 20, .22);
  animation: flick .35s infinite alternate;
}
@keyframes flick {
  from { transform: scale(.85); opacity: .8; }
  to { transform: scale(1.15); opacity: 1; }
}
#loadText { font-size: 12px; color: var(--dim); letter-spacing: 2px; margin-bottom: 12px; }
#loadbar { height: 3px; background: #15161f; border-radius: 2px; overflow: hidden; }
#loadbar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--ember), var(--gold)); transition: width .2s; }

/* ==========================================================================
   PANTALLA ANTIGUA E INTERFAZ DE RPG                       (anadido, 16-8-2026)

   Dos cosas viven aqui abajo:

   1. Las capas del monitor CRT. El sombreador de js/crt.js solo puede con el
      canvas del juego —la interfaz es HTML y va por encima—, asi que la parte
      de la interfaz se hace con una capa de CSS. Sin ella se veria un juego
      metido en un tubo y un HUD nitido flotando fuera de el.

   2. La interfaz con aire de juego de rol. Lo que habia era lenguaje de
      aplicacion movil: rectangulos redondeados, bordes de un pixel y desenfoque
      por detras. Lo que hay ahora son placas de hierro con bisel, remaches en
      las esquinas y un canal picado donde se mete la vida. Todo dibujado con
      CSS —ni un asset nuevo—, asi que se ve igual en el movil, en el navegador
      y dentro del .exe.

      Lo que NO se toca: los cuadros que ya tenian personalidad propia (la barra
      de armas con el marco de madera del kit, el verde del Errante, el rojo del
      Carmesi). Uniformarlo todo a hierro habria sido perder informacion.

   Va al final del fichero a proposito: lo de aqui MANDA sobre lo de arriba, que
   es la interfaz vieja, y asi se ve de un vistazo que es lo nuevo.
   ========================================================================== */

:root {
  --hierro-1: #1d2029;
  --hierro-2: #10121a;
  --hierro-3: #070810;
  --oro-1: #c99a3f;
  --oro-2: #7a5a24;
  --hueso: #e8dcc0;
}

/* --------------------------------------------------------------- el tubo
   El canvas del filtro se pone justo encima del canvas del juego y con el
   mismo tamano. Cuando el filtro esta apagado lleva la clase `off` y no se
   dibuja nada: el juego se ve tal cual, sin coste ninguno. */
#crtview {
  position: fixed; inset: 0;
  display: block;
  width: 100%; height: 100%;
  pointer-events: none;
  z-index: 1;
}
#crtview.off { display: none; }

/* La capa que pone lineas de barrido y cristal sobre TODO lo demas: la
   interfaz, el menu, los rotulos. Va arriba del todo y no come clics. */
#crtdom {
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 90;
  --crt-lineas: .28;
  --crt-vineta: .35;
}
#crtdom.off { display: none; }

/* Las lineas. Tres pixeles de paso: uno que deja pasar y dos que apagan, que
   es lo que se ve de cerca en un tubo de verdad. */
#crtdom .crt-lineas {
  position: absolute; inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0px,
    rgba(0, 0, 0, 0) 2px,
    rgba(0, 0, 0, .55) 2px,
    rgba(0, 0, 0, .55) 3px);
  opacity: var(--crt-lineas);
}

/* El cristal: la mascara de fosforo, el reflejo del cuarto en la esquina de
   arriba y la vineta del borde del tubo. */
#crtdom .crt-vidrio {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 60% 45% at 22% 8%, rgba(190, 210, 255, .05), transparent 60%),
    radial-gradient(ellipse at center,
      rgba(0, 0, 0, 0) 52%, rgba(0, 0, 0, .16) 80%, rgba(0, 0, 0, .5) 100%),
    repeating-linear-gradient(to right,
      rgba(255, 60, 60, .045) 0px, rgba(255, 60, 60, .045) 1px,
      rgba(60, 255, 60, .045) 1px, rgba(60, 255, 60, .045) 2px,
      rgba(60, 60, 255, .045) 2px, rgba(60, 60, 255, .045) 3px);
  opacity: calc(var(--crt-vineta) + .3);
}

/* Sin WebGL el juego no pasa por el sombreador, asi que la capa de CSS carga
   ella sola con el ambiente y se le sube un poco la mano. */
#crtdom.sinwebgl .crt-lineas { opacity: calc(var(--crt-lineas) * 1.4); }

/* ==========================================================================
   La placa de hierro: la pieza de la que salen los cuadros del HUD
   ========================================================================== */
#topbar, #vitals, #questbox, #bossbar, #elitebar {
  border: 2px solid #05060a;
  border-radius: 0;
  backdrop-filter: none;
  background:
    linear-gradient(180deg, rgba(255, 235, 200, .07), rgba(0, 0, 0, 0) 38%),
    linear-gradient(180deg, var(--hierro-1), var(--hierro-2) 60%, var(--hierro-3));
  box-shadow:
    inset 0 0 0 1px rgba(201, 154, 63, .28),
    inset 0 1px 0 rgba(255, 226, 170, .16),
    inset 0 -3px 6px rgba(0, 0, 0, .55),
    0 3px 0 rgba(0, 0, 0, .5),
    0 7px 18px rgba(0, 0, 0, .6);
}

/* Los cuatro remaches. Se pintan como fondo del propio cuadro, encima del
   degradado, asi que no hace falta ni un elemento mas. */
#vitals, #questbox, #bossbar, #elitebar {
  background-image:
    radial-gradient(circle 1.6px at 6px 6px, rgba(224, 196, 140, .55) 55%, transparent 58%),
    radial-gradient(circle 1.6px at calc(100% - 6px) 6px, rgba(224, 196, 140, .55) 55%, transparent 58%),
    radial-gradient(circle 1.6px at 6px calc(100% - 6px), rgba(180, 150, 100, .4) 55%, transparent 58%),
    radial-gradient(circle 1.6px at calc(100% - 6px) calc(100% - 6px), rgba(180, 150, 100, .4) 55%, transparent 58%),
    linear-gradient(180deg, rgba(255, 235, 200, .07), rgba(0, 0, 0, 0) 38%),
    linear-gradient(180deg, var(--hierro-1), var(--hierro-2) 60%, var(--hierro-3));
}

/* --------------------------------------------------------------- el rotulo
   Piso, sala y ping dejan de ser una pastilla y pasan a ser el letrero clavado
   sobre la puerta: las puntas cortadas en pico, como un estandarte. */
#topbar {
  padding: 6px 26px 7px;
  letter-spacing: 3px;
  font-size: 10.5px;
  color: #9aa2b8;
  border: 0;
  box-shadow: none;
  clip-path: polygon(10px 0, calc(100% - 10px) 0, 100% 50%,
                     calc(100% - 10px) 100%, 10px 100%, 0 50%);
  text-shadow: 0 1px 0 #000;
}
#topbar #floorLabel {
  color: var(--oro-1);
  text-shadow: 0 0 8px rgba(201, 154, 63, .45), 0 1px 0 #000;
}

/* ------------------------------------------------------------- los vitales
   El bloque de abajo es el que mas se mira de todo el juego, asi que es el que
   mas trabajo lleva: chapa remachada, canal hundido para la vida y la barra
   partida en muescas, como los juegos de la epoca. */
#vitals {
  width: 300px;
  padding: 9px 13px 11px;
  bottom: 16px;
}
#vitals .vrow {
  font-size: 9.5px; letter-spacing: 2.5px;
  color: #8a8fa4;
  margin-bottom: 7px;
  text-shadow: 0 1px 0 #000;
}
#clsName {
  color: var(--hueso);
  text-shadow: 0 0 7px rgba(201, 154, 63, .35), 0 1px 0 #000;
}
#lvlLabel { color: var(--oro-1); }

/* El canal: un hueco picado en la chapa donde despues se mete el liquido. */
#hpwrap, #xpwrap, #downbar {
  background: linear-gradient(180deg, #05060a, #0d0f16);
  border-radius: 0;
  box-shadow:
    inset 0 2px 3px rgba(0, 0, 0, .9),
    inset 0 0 0 1px rgba(0, 0, 0, .8),
    0 1px 0 rgba(201, 154, 63, .18);
}

#hpwrap { height: 17px; }
#hpfill {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .38), rgba(255, 255, 255, 0) 42%),
    linear-gradient(180deg, #d8342f, #97161a 55%, #5d0d12);
  box-shadow: 0 0 10px rgba(216, 52, 47, .45);
}
/* Aqui hubo muescas partiendo la barra en tramos, y se han quitado: la vida se
   lee mucho mejor de un vistazo cuando es UNA mancha roja que crece y mengua.
   Con las rayitas parecia una cuenta de cargas y no un liquido. */
#hpText {
  line-height: 17px; font-size: 10.5px; letter-spacing: 1px;
  color: var(--hueso);
  text-shadow: 0 0 4px #000, 0 1px 0 #000, 1px 0 0 #000, -1px 0 0 #000;
}

#xpwrap { height: 7px; margin-top: 4px; }
#xpText { line-height: 7px; }
#xpfill {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0) 45%),
    linear-gradient(90deg, #2c5a92, #64b9ff);
  box-shadow: 0 0 8px rgba(100, 185, 255, .55);
}
#stats { font-size: 9.5px; letter-spacing: 1.5px; margin-top: 6px; color: #7c8298; }
#defLabel { color: #93bbea; }

/* -------------------------------------------------------------- el minimapa
   Con marco de hierro, como el mapa clavado en la pared. */
#minimap {
  border: 2px solid #05060a;
  border-radius: 0;
  opacity: 1;
  box-shadow:
    inset 0 0 0 1px rgba(201, 154, 63, .35),
    0 0 0 1px rgba(0, 0, 0, .9),
    0 4px 16px rgba(0, 0, 0, .7);
}

/* ------------------------------------------------- jefes, elite y encargo
   Estos SI llevan la chapa, pero conservan su color: el rojo del jefe, el
   morado del jefe intermedio y el verde del encargo son informacion, no
   decoracion, y se quedan como estan. */
#bossbar, #elitebar { padding: 7px 16px 9px; }
#questbox {
  padding: 8px 12px 10px;
  border-left: 3px solid #b6ff7a;
}
#questbox.hecho { border-left-color: #6b7a5c; }

/* ==========================================================================
   La ventana de GRAFICOS
   ========================================================================== */
/* La ventana NO rueda entera: rueda solo su cuerpo.

   En el movil, `.uiwin` lleva `overflow: auto`, y eso recortaba la barra de
   titulo —que va colgada en `top: -33px`, fuera de la caja— con el aspa de
   cerrar dentro. Resultado: se abria esta ventana y no habia por donde salir.
   Aqui se le devuelve el `visible` y el rodar se lo queda el cuerpo. */
#gfx { z-index: 46; overflow: visible; }

/* Una sola columna: dos filas de botones y la tira de colores. Cabe en un movil
   apaisado sin rodar y sin apretar nada. */
.gfxuno { width: 300px; }

/* El pie con el CERRAR: fuera del cuerpo, asi que no se va nunca de la vista. */
.gfxpie {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 2px solid rgba(90, 60, 25, .25);
}
.gfxpie .uibtn { width: 100%; }

/* Los botones de preset y de paleta: pequenos, en fila, y el puesto encendido */
.gfxbtns { display: flex; flex-wrap: wrap; gap: 4px; }
.gfxbtns button {
  flex: 1 1 auto; min-width: 56px;
  padding: 6px 4px 7px;
  font-family: inherit; font-size: 9px; letter-spacing: 1.5px; font-weight: 700;
  color: #6b4a22;
  background: linear-gradient(180deg, rgba(255, 240, 210, .5), rgba(190, 160, 110, .25));
  border: 2px solid rgba(90, 60, 25, .35);
  cursor: pointer;
}
.gfxbtns button:hover { filter: brightness(1.08); }
.gfxbtns button.on {
  color: #23180a;
  background: linear-gradient(180deg, #f2cf7a, #b8862c);
  border-color: #7a5a24;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 0 10px rgba(201, 154, 63, .4);
}
.gfxbtns.pal button { min-width: 48px; }

.gfxpista {
  font-size: 9.5px; line-height: 1.4; color: #7a5a30;
  margin: 7px 0 0; min-height: 26px;
}

/* La tira con los 256 colores que puede pintar la pantalla. */
#gfxTira {
  display: block; width: 100%; height: 46px;
  margin-top: 9px;
  image-rendering: pixelated;
  border: 2px solid rgba(90, 60, 25, .35);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .4);
}

/* Las barras de aqui llevan una casilla mas a la izquierda que es APAGADO: se
   ve hundida y separada del resto para que no parezca un tramo mas. */
/* En NORMAL no se usa ninguna paleta, asi que la fila de colores se APAGA en
   vez de desaparecer: sigue diciendo cual esta elegida para cuando se vuelva a
   CLASICO, y el menu no da un salto al cambiar de modo. Se siguen pudiendo
   pulsar, y al pulsarlas se vuelve a CLASICO. */
.gfxbtns.apagada { opacity: .45; }
#gfxTira.apagada { opacity: .3; filter: grayscale(1); }

/* En una pantalla baja —un movil apaisado da 360 px de alto— la ventana esta
   centrada con `left: 50%`, asi que nunca puede pasar de media pantalla. Con
   una sola columna cabe de sobra: solo hay que dejarla rodar en vertical, y
   NUNCA de lado, que una ventana que se va por la derecha esta rota. */
@media (max-height: 620px) {
  .gfxuno { width: 264px; }
  /* Solo el cuerpo rueda, y NUNCA de lado: una ventana que se va por la
     derecha en un movil apaisado es una ventana rota. El titulo con su aspa
     queda arriba y el CERRAR abajo, los dos siempre a la vista. */
  #gfx .uibody { max-height: 46vh; overflow-y: auto; overflow-x: hidden; }
  .gfxbtns button { min-width: 44px; font-size: 8px; letter-spacing: 1px; }
  #gfxTira { height: 26px; }
  .gfxpista { min-height: 0; font-size: 8.5px; }
  .gfxpie { margin-top: 8px; padding-top: 8px; }
}

/* --------------------------------------------------------------- el sigilo
   Lo iluminado que estas, en el renglon de abajo. Tres palabras y tres colores:
   verde apagado si la oscuridad te tapa, gris si da igual y ambar encendido si
   te esta viendo media cripta. Es informacion de juego, no adorno: de esto
   depende de cuan lejos te ven y cuanto dano le haces a las criaturas de
   sombra. */
#sigiloLabel { letter-spacing: 1.5px; transition: color .25s; }
#sigiloLabel.oculto { color: #6f9e63; }
#sigiloLabel.media  { color: #8a8fa4; }
#sigiloLabel.visto  { color: #d8a63c; text-shadow: 0 0 8px rgba(216, 166, 60, .45); }
/* ==========================================================================
   CONTROLES  (solo en la version de PC)

   La ventana que dice que hace cada tecla. Reaprovecha el marco de pergamino
   de `.uiwin` y el pie de `.gfxpie`; lo unico propio es la rejilla de dos
   columnas y las teclas dibujadas.

   Estas reglas viajan tambien en la copia de Android porque el CSS es un solo
   fichero para las dos, pero alli no hay ningun `#controles` al que agarrarse
   y no pintan nada.                                                         */

/* Por lo mismo que #gfx: fuera de #hud, con su z-index de verdad, y el rodar se
   lo queda el cuerpo para no recortar la barra de titulo. */
#controles { z-index: 46; overflow: visible; }

/* Dos columnas. En una sola, la lista se iba muy por debajo del borde de la
   pantalla y habia que rodar para ver la mitad de las teclas, que en una pausa
   es justo lo que no se quiere hacer. */
.ctrlcols { display: flex; gap: 26px; align-items: flex-start; }
.ctrlcol { width: 292px; }

/* Cada renglon: las teclas a la izquierda en su columna fija —asi quedan todas
   alineadas y se leen de un vistazo— y a la derecha lo que hacen, con la
   explicacion debajo cuando hace falta. Las filas se fijan a mano en vez de
   dejar que el grid las coloque solo: sin eso, un renglon sin explicacion se
   descolocaba y metia el texto debajo de las teclas. */
.ctrl {
  display: grid;
  grid-template-columns: 116px 1fr;
  column-gap: 10px; row-gap: 2px;
  align-items: center;
  margin-bottom: 6px;
}
.ctrl .teclas { grid-column: 1; grid-row: 1; display: flex; flex-wrap: wrap; gap: 3px; }
.ctrl b { grid-column: 2; grid-row: 1; font-size: 10px; letter-spacing: .4px; color: #3a2a17; }
.ctrl i {
  grid-column: 2; grid-row: 2;
  font-style: normal; font-size: 9px; line-height: 1.35; color: #7a5a30;
}

/* La tecla dibujada: una tapa con luz arriba y sombra abajo, sin imagenes. */
.ctrl kbd {
  font-family: inherit; font-size: 9px; font-weight: 700; letter-spacing: .5px;
  color: #23180a;
  min-width: 20px; padding: 3px 5px 4px;
  text-align: center;
  background: linear-gradient(180deg, #f2e3bd, #c3a76f);
  border: 2px solid #7a5a24;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55), 0 2px 0 rgba(60, 40, 15, .35);
}
/* El raton no es una tecla: se distingue de lejos por el color. */
.ctrl kbd.raton {
  background: linear-gradient(180deg, #d9dfe6, #98a4b2);
  border-color: #4d5a68;
}

/* El mando fisico va de una tirada al pie: son ocho botones y en rejilla
   ocupaba media ventana para decir lo mismo. */
.ctrlpad {
  /* Del ancho de las dos columnas y ni un pixel mas. Sin este tope el parrafo
     se estira hasta donde le cabe y es EL quien decide el ancho de la ventana:
     en un monitor grande salia una ventana mucho mas ancha que en uno pequeno,
     con las dos columnas perdidas a la izquierda. */
  max-width: 610px;
  margin: 12px 0 0;
  font-size: 9px; line-height: 1.5; color: #7a5a30;
  border-top: 2px solid rgba(90, 60, 25, .25);
  padding-top: 10px;
}
.ctrlpad b { color: #6b4a22; }

/* Pantalla baja: la ventana esta centrada, asi que no puede pasar de media
   pantalla. Se deja rodar en vertical y NUNCA de lado. */
@media (max-height: 620px) {
  #controles .uibody { max-height: 62vh; overflow-y: auto; overflow-x: hidden; }
}
/* Y si ademas es estrecha, las dos columnas se ponen una encima de otra antes
   que salirse por los lados. */
@media (max-width: 760px) {
  .ctrlcols { flex-direction: column; gap: 0; }
  .ctrlcol { width: 100%; }
}

/* ============================ LOS PACTOS ============================
   Ver shared/pactos.js. Dos piezas: el aviso pequeno del HUD y el panel de
   elegir.

   EL PANEL NO TAPA LA PANTALLA, y esa es la decision de la que cuelga todo lo
   demas. Antes era un velo sobre el lienzo entero con una caja de 860 px en
   medio, y la partida NO se para mientras eliges: lo que hacia el velo era
   taparte los bichos que venian a matarte mientras leias. Ahora es una columna
   estrecha pegada al canto derecho, debajo del minimapa, y por el hueco que
   deja se sigue viendo la cripta y se sigue jugando.

   Lo unico que atrapa el raton es el propio panel: fuera de el se sigue
   apuntando y disparando como siempre. */

#pactoAviso {
  position: fixed; left: 50%; top: 74px; transform: translateX(-50%);
  z-index: 42;
  /* Se pulsa: con raton es el camino corto y con dedos es el unico, porque en
     una pantalla tactil no hay ni P ni Start. */
  pointer-events: auto; cursor: pointer;
  display: flex; align-items: center; gap: 8px;
  padding: 5px 13px;
  background: rgba(18, 12, 26, .88);
  border: 1px solid #b06bff;
  border-radius: 3px;
  box-shadow: 0 0 14px rgba(176, 107, 255, .45);
  animation: pactoLate 1.5s ease-in-out infinite;
}
#pactoAviso:hover { background: rgba(32, 20, 46, .95); }
#pactoAviso b {
  font-family: inherit; font-size: 12px; letter-spacing: 3px;
  color: #dcb6ff;
}
#pactoAviso span { font-size: 10px; letter-spacing: 1.5px; color: #9d8ab5; }

@keyframes pactoLate {
  0%, 100% { box-shadow: 0 0 10px rgba(176, 107, 255, .30); }
  50%      { box-shadow: 0 0 22px rgba(176, 107, 255, .70); }
}

/* La columna. Va a la derecha y arranca debajo del minimapa (12 + 160 + 14).
   `max-height` con desbordamiento propio para que en una pantalla baja se
   pueda rodar el panel sin que la pagina se mueva. */
#pactoElegir {
  position: fixed; right: 12px; top: 186px;
  z-index: 60;
  width: min(320px, 42vw);
  max-height: calc(100vh - 210px);
  overflow-y: auto;
  pointer-events: auto;
}
#pactoElegir.hidden { display: none; }

.pactoCaja {
  padding: 10px 11px 11px;
  background: rgba(14, 10, 20, .93);
  border: 1px solid #4b3a63;
  border-left: 3px solid #8a5fc4;
  border-radius: 4px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, .65);
}
.pactoCab { display: flex; align-items: baseline; gap: 7px; }
.pactoCaja h2 {
  margin: 0; font-family: inherit; font-size: 12px; letter-spacing: 4px;
  color: #e6d8ff;
}
/* De quien es el panel. En el sofa hay tres personas mirando la misma pantalla
   y un menu que no dice de quien es no vale para nada. */
#pactoQuien {
  font-size: 9px; letter-spacing: 1.6px; color: #9d8ab5;
}
#pactoCerrar {
  margin-left: auto;
  background: transparent; border: 1px solid #4b3a63; color: #8d7fa5;
  width: 20px; height: 18px; line-height: 1; border-radius: 2px;
  cursor: pointer; font-family: inherit; font-size: 11px;
}
#pactoCerrar:hover { color: #d8c8f0; border-color: #7a6396; }
.pactoPie {
  margin: 4px 0 9px; font-size: 10px; line-height: 1.4;
  color: #8d7fa5;
}

/* Las tres cartas, UNA DEBAJO DE OTRA. En fila no cabrian en 320 px sin
   partir las palabras, y lo que hay que leer de cada una es una frase entera:
   apilarlas deja la frase de un renglon o dos y se lee de un vistazo. */
#pactoCartas { display: flex; flex-direction: column; gap: 7px; }

/* Cada carta lleva el color de su patron en el borde y en el titulo. Es lo que
   deja saber de un vistazo si estas cogiendo dos del mismo sitio o mezclando,
   sin leer un solo nombre. */
.pactoCarta {
  display: block; width: 100%;
  padding: 8px 9px 9px;
  background: rgba(26, 20, 36, .95);
  border: 1px solid var(--tono, #5a4a72);
  border-left-width: 3px;
  border-radius: 3px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: transform .1s ease, box-shadow .1s ease, background .1s ease;
}
/* `marcada` es la del mando —la que se elige al dar a atacar— y va igual que el
   :hover del raton a proposito: las dos formas de elegir tienen que verse
   iguales o el que juega con mando no sabe donde esta. */
.pactoCarta:hover, .pactoCarta:focus-visible, .pactoCarta.marcada {
  transform: translateX(-3px);
  background: rgba(40, 31, 55, .98);
  box-shadow: 0 0 16px color-mix(in srgb, var(--tono) 40%, transparent);
  outline: none;
}
.pactoCarta .cab {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
}
.pactoCarta .patron {
  font-style: normal; font-size: 8.5px; letter-spacing: 2px;
  color: var(--tono, #9d8ab5);
}
/* Cuantas llevas de esa, en bolitas: se ve sin leer, que es lo que hace falta
   con la partida corriendo por detras. */
.pactoCarta .pips {
  font-style: normal; font-size: 8px; letter-spacing: 1px;
  color: var(--tono, #9d8ab5); opacity: .8;
}
.pactoCarta .nombre {
  display: block; margin: 4px 0 4px;
  font-family: inherit; font-size: 12px; letter-spacing: .8px;
  color: #f0e8ff;
}
.pactoCarta .que {
  display: block; font-size: 10.5px; line-height: 1.4; color: #b6a9c8;
}
/* LA LINEA QUE HACE FALTA. Dice que ese pacto cierra una pareja, y es lo unico
   que convierte dos cartas parecidas en una decision de verdad. Sin ella los
   dobles se descubrian por accidente, o no se descubrian nunca. */
.pactoCarta .une {
  display: block; margin-top: 6px; padding-top: 5px;
  border-top: 1px dashed color-mix(in srgb, var(--doble, #c8a0ff) 45%, transparent);
  font-size: 9.5px; line-height: 1.35;
  color: var(--doble, #d8b8ff);
}

/* Los dobles a los que les falta UN pacto. Lo mismo que la linea de la carta
   pero mirando hacia adelante: para lo que llevas puesto, esto es lo que
   estarias buscando en el proximo sorteo. */
#pactoCombos {
  margin-top: 9px; padding-top: 7px;
  border-top: 1px solid #2e2440;
}
#pactoCombos.hidden { display: none; }
#pactoCombos b {
  display: block; font-family: inherit; font-size: 8.5px; letter-spacing: 2px;
  color: #6b5f80; margin-bottom: 4px;
}
#pactoCombos .casi {
  display: block; font-size: 9.5px; line-height: 1.5; color: #8d7fa5;
}
#pactoCombos .casi i {
  font-style: normal; color: var(--doble, #d8b8ff); letter-spacing: .5px;
}

/* Lo que ya llevas puesto. Va abajo y pequeno: es para consultarlo, no para
   leerlo entero cada vez. */
#pactoTuyos {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-top: 9px; padding-top: 7px;
  border-top: 1px solid #2e2440;
  min-height: 16px;
}
#pactoTuyos .yaTengo {
  font-size: 9px; letter-spacing: .5px;
  padding: 2px 6px; border-radius: 2px;
  border: 1px solid var(--tono, #4b3a63);
  color: var(--tono, #b6a9c8);
  background: rgba(0, 0, 0, .3);
}
/* Los dobles se marcan distinto: son lo unico que no se elige, aparece. */
#pactoTuyos .yaTengo.doble {
  border-style: dashed;
  background: rgba(120, 70, 180, .22);
  color: #e0c8ff;
}
#pactoTuyos .nada { font-size: 9px; color: #6b5f80; letter-spacing: 1px; }

/* Que vale para elegir. Se escribe desde el codigo con el aparato del que esta
   eligiendo: un invitado con mando no quiere leer "pulsa 1, 2 o 3". */
#pactoTeclas {
  margin: 8px 0 0; text-align: center;
  font-size: 8.5px; letter-spacing: 1px; color: #6b5f80;
}

/* En una pantalla estrecha o apaisada de movil, el panel se lleva abajo y se
   estira: a la derecha se comeria media cripta. */
@media (max-width: 700px), (max-height: 520px) {
  #pactoElegir {
    right: 8px; left: 8px; top: auto; bottom: 8px;
    width: auto; max-height: 64vh;
  }
  #pactoCartas { flex-direction: row; }
  .pactoCarta { flex: 1 1 0; min-width: 0; }
}


/* ======================= EL ACEITE Y LA OSCURIDAD =======================
   Ver P.ACEITE en shared/protocol.js. */

#oilwrap {
  position: relative; height: 7px; margin-top: 3px;
  background: rgba(0, 0, 0, .55);
  border: 1px solid #3a3348; border-radius: 2px;
  overflow: hidden;
}
#oilfill {
  height: 100%; width: 100%;
  background: linear-gradient(180deg, #ffcc66, #d18a2a);
  transition: width .2s linear, background .25s ease, opacity .25s ease;
}
/* Con el farol apagado la barra se apaga con el. Es lo que separa "no tengo
   aceite" de "lo tengo y no lo estoy gastando", que se juegan muy distinto. */
#oilfill.apagado { opacity: .3; filter: saturate(.3); }
/* Y por debajo de un cuarto late. Un cambio de color solo no se ve en mitad de
   una pelea, y quedarse sin luz aqui no es quedarse sin un adorno. */
#oilfill.poco {
  background: linear-gradient(180deg, #ff7a4a, #b83c1e);
  animation: oilPoco .9s ease-in-out infinite;
}
@keyframes oilPoco {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.7); }
}
#oilText {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  font-size: 8px; letter-spacing: .5px; color: #f0e0c0;
  text-shadow: 0 1px 2px #000;
  pointer-events: none;
}

#oscuridad {
  position: fixed; left: 50%; top: 108px; transform: translateX(-50%);
  z-index: 41; pointer-events: none;
  width: 210px;
  text-align: center;
}
#oscuridad.hidden { display: none; }
#oscuridad i {
  display: block; height: 3px; width: 0%;
  background: linear-gradient(90deg, #4a2a6a, #a050d0);
  border-radius: 2px;
  transition: width .25s linear;
}
#oscuridad span {
  display: block; margin-top: 3px;
  font-size: 9px; letter-spacing: 2.4px; color: #8a6ab0;
}
/* Pasado el 70% cambia de tono y late: a partir de ahi ya falta poco para que
   salga algo, y el aviso tiene que dejar de ser informacion y pasar a ser prisa. */
#oscuridad.alta i { background: linear-gradient(90deg, #7a2a6a, #e050b0); }
#oscuridad.alta span { color: #e0a0d0; animation: oscLate .7s ease-in-out infinite; }
@keyframes oscLate {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}

/* El sello de cada arma, en la barra de accion. Ver shared/afijos.js.
   Va con el color del sello y en un recuadro pequeno debajo del nombre: lo que
   hay que ver de un vistazo en mitad de una pelea es "esta lleva algo y esta
   no", no leer lo que hace. Lo que hace se lee en el title, parado. */
.wslot .wsello {
  position: absolute; left: 3px; right: 3px; bottom: 2px;
  font-size: 7px; letter-spacing: .6px; text-align: center;
  padding: 1px 0;
  border: 1px solid; border-radius: 2px;
  background: rgba(0, 0, 0, .45);
  text-transform: uppercase;
  pointer-events: none;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}

/* ===================== El trato entre jugadores =====================
   Dos columnas dentro de la ventana del kit: lo tuyo se teclea, lo del otro
   solo se mira. El sello LISTO/ESPERANDO por lado y un aviso rojo cuando la
   oferta cambia y los aceptares se reinician (2026-08-29). */
#trade .uibody { min-width: 340px; }
.tradecols { display: flex; gap: 18px; }
.tradecol { flex: 1; display: flex; flex-direction: column; gap: 6px; }
.tradecol.ajena { opacity: .95; }
.tradecol label {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; font-size: 10px; color: #4a3418;
}
.tradecol input {
  width: 72px; padding: 3px 4px;
  font-family: inherit; font-size: 11px; text-align: right;
  color: #3a2a17; background: rgba(255, 246, 224, .75);
  border: 2px solid #8a6a3a; border-radius: 3px;
}
.tradelinea {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 10px; color: #4a3418;
}
.tradelinea b { font-size: 12px; }
.tradesello {
  margin-top: 8px; text-align: center;
  font-size: 9px; letter-spacing: 2.5px; font-weight: 700;
  color: #8a6a3a;
}
.tradesello.listo { color: #1d6b32; text-shadow: 0 0 6px rgba(60, 200, 100, .35); }
.tradebotones {
  margin-top: 14px; display: flex; gap: 10px; justify-content: center;
}
#tradeAviso {
  margin: 0 0 10px; text-align: center;
  font-size: 10px; font-weight: 700; color: #7a1616;
}
#tradeAviso.hidden { display: none; }
#tradePedido p { margin: 0 0 6px; font-size: 11px; text-align: center; }

/* ==================== HASTA TRES EN EL MISMO SOFA ====================
   Ver js/local.js y js/vistas.js. */

/* "Se puede unir otro". Arriba a la izquierda, apartado del piso y la sala.
   Late despacio para que se vea de reojo sin robar la vista: es una invitacion,
   no un aviso de peligro. */
#unirse {
  position: fixed; left: 14px; top: 14px;
  z-index: 41; pointer-events: none;
  padding: 5px 11px;
  background: rgba(14, 18, 26, .88);
  border: 1px solid #7ed66a;
  border-radius: 3px;
  animation: unirseLate 2.1s ease-in-out infinite;
}
#unirse.hidden { display: none; }
#unirse b {
  display: block;
  font-family: inherit; font-size: 10px; letter-spacing: 2.2px; color: #b8f0a8;
}
#unirse span {
  display: block; margin-top: 2px;
  font-size: 9px; letter-spacing: 1px; color: #7f9a78;
}
@keyframes unirseLate {
  0%, 100% { box-shadow: 0 0 8px rgba(126, 214, 106, .22); }
  50%      { box-shadow: 0 0 20px rgba(126, 214, 106, .58); }
}

/* Los recuadros de los invitados. Van abajo a la izquierda, en fila, y por
   encima de la barra del jugador 1 para no taparla. */
#sofa {
  position: fixed; left: 14px; bottom: 92px;
  z-index: 40; pointer-events: none;
  display: flex; gap: 8px;
}
#sofa.hidden { display: none; }

.sofaCaja {
  min-width: 104px;
  padding: 4px 8px 5px;
  background: rgba(12, 10, 18, .86);
  border: 1px solid var(--tono, #4b3a63);
  border-left-width: 3px;
  border-radius: 3px;
}
.sofaCaja b {
  font-family: inherit; font-size: 10px; letter-spacing: 1.5px;
  color: var(--tono, #d8c8f0);
}
.sofaCaja .quien {
  margin-left: 5px; font-size: 9px; letter-spacing: .5px; color: #a89ab8;
}
.sofaCaja .barra {
  display: block; height: 4px; margin: 3px 0 2px;
  background: rgba(0, 0, 0, .6);
  border-radius: 2px; overflow: hidden;
}
.sofaCaja .barra u {
  display: block; height: 100%; width: 100%;
  background: linear-gradient(180deg, #d84a4a, #8e2020);
  transition: width .18s linear;
}
.sofaCaja .mando {
  font-size: 8px; letter-spacing: 1px; color: #6b5f80;
}
/* El NIVEL del invitado. Esta aqui porque el que entra lo hace al nivel del
   jugador 1 —ver `addPlayer` en shared/room.js— y sin verlo escrito en algun
   sitio no hay forma de saber que eso ha pasado; uno se queda con la duda de
   si acaba de meter a un nivel 1 en el piso doce. */
.sofaCaja .nivel {
  margin-left: 5px; font-size: 8.5px; letter-spacing: .5px; color: var(--gold, #ffb347); opacity: .85;
}
/* Su pacto sin coger. Va en SU recuadro y no en el rotulo grande de arriba, que
   es del jugador 1: con tres personas delante de la misma pantalla, un aviso
   que no dice de quien es no sirve para nada. */
.sofaCaja .pactoYa {
  display: block; margin-top: 2px;
  font-size: 8px; letter-spacing: 1.2px; color: #dcb6ff;
  animation: pactoLate 1.5s ease-in-out infinite;
}
.sofaCaja .pactoYa.hidden { display: none; }
/* Caido: la caja se apaga y la barra se pone al minimo. Muerto: se tacha. */
.sofaCaja.caido { opacity: .72; border-color: #a04040; }
.sofaCaja.caido .barra u { background: #6a2020; }
.sofaCaja.muerto { opacity: .42; }
.sofaCaja.muerto b { text-decoration: line-through; }


/* --- El recuadro mientras ELIGE personaje --------------------------------
   Es la misma caja de abajo a la izquierda, con otra cara: el sprite del heroe
   en vez de la barra de vida. Se elige aqui y no en una ventana aparte porque
   una ventana que se abre sola taparia la partida de los que ya estan jugando;
   asi, el que llega elige en su rincon sin parar a nadie. */
.sofaCaja.eligiendo {
  border-style: dashed;
  animation: eligeLate 1.4s ease-in-out infinite;
}
@keyframes eligeLate {
  0%, 100% { box-shadow: 0 0 6px rgba(255, 226, 148, .18); }
  50%      { box-shadow: 0 0 18px rgba(255, 226, 148, .52); }
}
.sofaCaja .retrato {
  display: block;
  width: 48px; height: 48px;
  margin: 3px auto 2px;
  image-rendering: pixelated;
}
.sofaCaja .comoElegir {
  display: block; text-align: center;
  font-size: 8px; letter-spacing: 1px; color: #b6a98a;
}
