/* Lesky's Shop — estilos de escena (capas sobre un escenario 16:9). */
/* Gradio centra y limita el ancho por defecto: usar pantalla completa. */
.gradio-container {
max-width: 100% !important;
width: 100% !important;
padding: 0 !important;
}
/* ---- Escenario ----
SIEMPRE 16:9 (igual que el calibrador). El ancho manda (min entre el contenedor
y el 16:9 de 82vh) y la altura se deriva por aspect-ratio. Así la imagen del
tablero (object-fit) llena el stage sin bandas y las capas/rejilla en % cuadran
con lo pintado en CUALQUIER tamaño de ventana. (Antes: height fija 82vh ->
en ventanas estrechas el stage salía más alto que 16:9 y la rejilla bailaba.) */
.stage {
position: relative !important;
/* Caja 16:9. width manda (min entre contenedor y el 16:9 de 82vh); la altura
sale por aspect-ratio. flex:0 0 auto evita que el flex de Gradio estire la
caja y la deje "chata". --sw también disponible por si hace falta calc. */
--sw: min(100vw, calc(82vh * 16 / 9));
width: min(100%, calc(82vh * 16 / 9)) !important;
aspect-ratio: 16 / 9 !important;
height: auto !important;
flex: 0 0 auto !important;
align-self: center !important;
margin: 0 auto;
overflow: hidden;
}
/* Neutralizar los wrappers que Gradio mete dentro de .stage (.block tiene
position:relative + fondo + padding). Así .stage es el único ancestro
posicionado y las capas absolutas se miden respecto a él. */
.stage .block,
.stage .form,
.stage .html-container,
.stage > .column,
.stage > .row {
position: static !important;
background: transparent !important;
border: none !important;
box-shadow: none !important;
padding: 0 !important;
margin: 0 !important;
min-width: 0 !important;
overflow: visible !important;
}
/* Capas: fondo / personaje / marco, apiladas sobre el escenario. */
.stage .layer {
position: absolute !important;
inset: 0;
width: 100%;
height: 100%;
object-fit: contain;
pointer-events: none; /* no roban clicks */
}
/* Personaje: más pequeño y anclado abajo-centro, para quedar detrás de la mesa
delantera (.layer.front, que va después en el DOM y lo tapa por abajo). */
.stage .layer.sprite {
inset: auto;
left: 50%;
bottom: 1%;
transform: translateX(-50%);
width: 46%;
height: 82%;
object-fit: contain;
object-position: center bottom;
}
/* Flash de revelación (monster_reveal): destello blanco que cubre el stage una vez. */
.stage .flash {
position: absolute !important;
inset: 0;
z-index: 20;
background: #fff;
pointer-events: none;
animation: revealflash 0.65s ease-out forwards;
}
@keyframes revealflash {
0% { opacity: 0; }
12% { opacity: 0.96; }
100% { opacity: 0; }
}
/* Pantalla loading: gris con spinner mientras el LLM calcula el saludo. */
.stage.loading-stage {
background: #2b2b2b;
display: flex;
align-items: center;
justify-content: center;
}
.loading-box { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.loading-spinner {
width: 46px; height: 46px;
border: 5px solid rgba(255, 255, 255, 0.18);
border-top-color: #e8e8e8;
border-radius: 50%;
animation: lspin 0.9s linear infinite;
}
@keyframes lspin { to { transform: rotate(360deg); } }
.loading-text { color: #cfcfcf; font-size: 1.15rem; letter-spacing: 2px; }
/* Brazo del jugador entrando al tablero. Encima de la rejilla (z>5) pero sin
robar clicks (.layer ya trae pointer-events:none). Anclado arriba, reaching in. */
.stage .layer.hand {
inset: auto;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100%;
height: 100%;
object-fit: contain;
object-position: center top;
z-index: 6;
}
/* Texto del LLM dentro del pergamino de CHAT.PNG (anclado abajo-derecha). */
/* Texto del LLM dentro del papel del pergamino (CHAT.PNG, lado derecho).
Zona estrecha -> fuente pequeña + scroll vertical. Ajustar % a ojo. */
.stage .chat-text {
position: absolute;
left: 78%;
top: 33%;
width: 14.5%;
height: 38%;
overflow-y: auto;
padding: 2px 6px;
color: #2e2113;
font-size: 0.7rem;
line-height: 1.25;
text-align: left;
z-index: 7;
}
/* Listas/briefing compactos dentro del pergamino. Forzar color OSCURO en TODOS
los descendientes: Gradio (tema oscuro) pinta
/
casi blancos por defecto. */
.stage .chat-text,
.stage .chat-text li,
.stage .chat-text p,
.stage .chat-text span,
.stage .chat-text i,
.stage .chat-text em,
.stage .chat-text ul { color: #2e2113 !important; }
.stage .chat-text b,
.stage .chat-text strong { color: #4a2e10 !important; }
.stage .chat-text ul { margin: 3px 0 5px 14px; padding: 0; }
.stage .chat-text li { margin-bottom: 2px; }
/* monster_reveal: TODAS las letras negro puro (máx. contraste) incl. divs/b. */
.stage .chat-text.reveal-text,
.stage .chat-text.reveal-text * { color: #000 !important; }
/* Barra de scroll fina y discreta dentro del pergamino. */
.stage .chat-text::-webkit-scrollbar { width: 5px; }
.stage .chat-text::-webkit-scrollbar-thumb {
background: rgba(70, 50, 25, 0.5); border-radius: 3px;
}
/* Bloque de entrada (nombre / chat) sobre la tabla de madera de CHAT.PNG. */
.stage .wood-input {
position: absolute !important;
left: 76.5%;
top: 79.5%;
width: 20%;
z-index: 8;
gap: 3px !important;
flex-direction: column !important; /* 2 filas: textbox arriba, botón abajo */
align-items: stretch !important;
}
.stage .wood-input > * { width: 100% !important; }
.stage .wood-input button { width: 100% !important; flex: 0 0 auto !important; }
/* Forzar ancho 100% por toda la cadena interna de Gradio (colapsa a 0 si no). */
.stage .wood-input .block,
.stage .wood-input .form,
.stage .wood-input .container,
.stage .wood-input .input-container,
.stage .wood-input .scroll-hide {
width: 100% !important;
min-width: 0 !important;
}
/* Gradio deja el .container interno en display:none y los wrappers a alto 0. */
.stage .wood-input .container { display: block !important; }
.stage .wood-input .form,
.stage .wood-input .input-container,
.stage .wood-input .scroll-hide {
height: auto !important;
min-height: 1.9rem !important;
overflow: visible !important;
}
.stage .wood-input label { display: none !important; } /* sin etiqueta, ahorra alto */
.stage .wood-input input,
.stage .wood-input textarea {
width: 100% !important;
/* Crema translúcido sobre la madera (se mimetiza) + texto OSCURO legible. */
background: rgba(232, 218, 188, 0.45) !important;
border: 1px solid rgba(70, 50, 25, 0.5) !important;
color: #2e2113 !important;
font-size: 0.9rem !important;
text-align: center;
min-height: 2.1rem !important; /* evita que Gradio lo colapse a 0 */
height: 2.1rem !important;
padding: 3px 6px !important;
}
.stage .wood-input input::placeholder,
.stage .wood-input textarea::placeholder { color: rgba(60, 42, 22, 0.6) !important; }
.stage .wood-input button { min-height: 1.8rem !important; padding: 2px 8px !important; }
/* GIF "tap to start" animado, centrado abajo sobre la portada. */
.stage .tap-gif {
position: absolute;
bottom: 6%;
left: 50%;
transform: translateX(-50%);
width: 82%;
pointer-events: none;
z-index: 6;
}
/* Host de la música (img oculta que dispara __setMusic): sin hueco en el layout.
La img igual carga y su onload se ejecuta aunque el contenedor esté display:none. */
.music-host { display: none !important; }
/* Botón "tap to start" invisible cubriendo toda la portada.
OJO: gr.Button pone elem_classes en el