/* ==========================================================================
   TEMA: PIXEL RETRO (Game Boy)
   Uso: index.php?theme=gameboy
   Paleta DMG de 4 verdes (#0f380f, #306230, #8bac0f, #9bbc0f). Como solo hay
   un tono "claro", los estados (válido, error, fijo, colocado) se distinguen
   por inversión de colores, bordes (sólido/discontinuo) y parpadeos.
   ========================================================================== */

/* Fuentes alojadas en el propio proyecto (carpeta fonts/, subconjunto latino: cubre el español). Así funcionan sin conexión
   y no se piden a Google. Licencia OFL (ver fonts/LEEME.md). */
@font-face {
    font-family: "Press Start 2P";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../../fonts/press-start-2p-latin.woff2") format("woff2");
}
@font-face {
    font-family: "VT323";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../../fonts/vt323-latin.woff2") format("woff2");
}

:root {
    --bg: #0f380f;
    --surface: rgba(139, 172, 15, .08);
    --surface-hover: rgba(155, 188, 15, .2);
    --border: #306230;
    --text: #9bbc0f;
    --muted: #6f9712;

    --accent: #9bbc0f;
    --accent-2: #8bac0f;
    --good: #9bbc0f;
    --bad: #9bbc0f;
    --warn: #9bbc0f;
    --on-accent: #0f380f;

    --radius: 0;
    --radius-sm: 0;
    --font-display: "Press Start 2P", "Courier New", monospace;
    --font-body: "VT323", "Courier New", monospace;
    --backdrop: rgba(15, 56, 15, .88);
    --backdrop-reward: rgba(15, 56, 15, .7);

    --confetti-1: #9bbc0f;
    --confetti-2: #8bac0f;
    --confetti-3: #306230;
    --confetti-4: #9bbc0f;
    --confetti-5: #8bac0f;
}

/* Variante gris (blanco y negro): mismas variables con grises de luminosidad parecida a cada verde, para que los estados sigan distinguiéndose */
html.gris {
    --bg: #0d0d0d;
    --surface: rgba(200, 200, 200, .08);
    --surface-hover: rgba(212, 212, 212, .2);
    --border: #555555;
    --text: #d4d4d4;
    --muted: #8c8c8c;

    --accent: #d4d4d4;
    --accent-2: #bcbcbc;
    --good: #d4d4d4;
    --bad: #d4d4d4;
    --warn: #d4d4d4;
    --on-accent: #0d0d0d;

    --backdrop: rgba(13, 13, 13, .88);
    --backdrop-reward: rgba(13, 13, 13, .7);

    --confetti-1: #d4d4d4;
    --confetti-2: #bcbcbc;
    --confetti-3: #555555;
    --confetti-4: #d4d4d4;
    --confetti-5: #bcbcbc;
}

/* ---------- Base pixelada ---------- */
body {
    font-size: 1.35rem;
    -webkit-font-smoothing: none;
    font-smooth: never;
    text-rendering: optimizeSpeed;
}
* { border-radius: 0 !important; }   /* nada redondeado */
*, *::before, *::after { transition-timing-function: steps(3) !important; }

/* Rejilla LCD sobre toda la pantalla */
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 100;
    pointer-events: none;
    background-image:
        linear-gradient(rgba(0, 0, 0, .16) 1px, transparent 1px),
        linear-gradient(90deg, rgba(0, 0, 0, .16) 1px, transparent 1px);
    background-size: 3px 3px;
}

/* ---------- Cabecera ---------- */
.logo {
    font-size: clamp(.65rem, 2.4vw, 1rem);
    line-height: 1.5;
    letter-spacing: 0;
    text-shadow: 3px 3px 0 var(--border);
}
.logo span { color: var(--text); }

.icon-btn {
    border-width: 3px;
    box-shadow: 3px 3px 0 var(--border);
    background: var(--bg);
}
@media (hover: hover) { .icon-btn:hover { background: var(--surface-hover); box-shadow: 3px 3px 0 var(--border); } }
.icon-btn:active { transform: translate(3px, 3px); box-shadow: none; }
.icon-btn[aria-pressed="true"] { background: var(--text); color: var(--on-accent); border-color: var(--text); }
.icon-btn svg { shape-rendering: crispEdges; }
.modal-x { border: 3px solid var(--border); box-shadow: 3px 3px 0 var(--border); background: var(--bg); }
@media (hover: hover) { .modal-x:hover { background: var(--surface-hover); } }
.modal-x:active { transform: translate(3px, 3px); box-shadow: none; }
.modal-x svg { shape-rendering: crispEdges; }

/* ---------- Estadísticas ---------- */
.stat { border-width: 3px; background: var(--surface); }
.stat-label { font-size: 1.05rem; letter-spacing: .04em; }
.stat-value { font-size: .85rem; line-height: 1.5; text-shadow: 2px 2px 0 var(--border); }
.stat-value.bump { animation-timing-function: steps(2); }

.progress { height: 18px; border-width: 3px; padding: 2px; background: var(--bg); }
.progress-bar { gap: 3px; }
.progress-bar { --seg-off: color-mix(in srgb, var(--accent) 15%, transparent); }
.progress-bar i { transition: none; background: var(--seg-off); }
/* el relleno encendido es una capa que crece de izquierda a derecha sobre el fondo tenue del segmento, que siempre se ve */
.progress-bar i.on { background: linear-gradient(var(--accent), var(--accent)) left / 100% 100% no-repeat, var(--seg-off); animation: gb-seg-on .35s steps(5); }
@keyframes gb-seg-on { from { background-size: 0% 100%, auto; } to { background-size: 100% 100%, auto; } }

/* ---------- Tarjeta del número ---------- */
.draw-card {
    border-width: 4px;
    border-color: var(--border);
    background: var(--surface);
    box-shadow: 6px 6px 0 var(--border);
}
.draw-label { font-size: 1.15rem; letter-spacing: .2em; }
.draw-value {
    font-size: clamp(2.2rem, 6vw, 3.6rem);
    text-shadow: 4px 4px 0 var(--border);
}
.draw-card.has-number { border-color: var(--text); background: var(--surface-hover); }
.draw-card.has-number .draw-value { animation-timing-function: steps(4); }
/* Glorioso: el número marcado, con la paleta invertida (fondo claro y cifras oscuras) y cuatro destellos que parpadean a saltos */
.draw-card.is-star { background: var(--text); border-color: var(--text); }
.draw-card.is-star .draw-value, .draw-card.is-star .draw-label, .draw-card.is-star .draw-note { color: var(--on-accent); text-shadow: none; }
.draw-card.is-star .star-spark { color: var(--on-accent); animation: gb-blink .8s steps(1) infinite; }
.draw-card.is-star .star-spark.tr, .draw-card.is-star .star-spark.bl { animation-delay: .4s; }
.draw-card.is-rolling { border-color: var(--text); }
.draw-card.is-rolling .draw-value { color: var(--text); animation: gb-blink .24s steps(1) infinite; }
.draw-card.is-stuck { border-style: dashed; border-color: var(--text); }
.draw-card.is-stuck .draw-value { animation: gb-blink .6s steps(1) infinite; }

.draw-card.is-won { border-color: var(--text); background: var(--surface-hover); }
.draw-card.is-won .draw-value { animation-timing-function: steps(4); }
.draw-card.is-won .draw-value svg {
    shape-rendering: crispEdges;
    filter: drop-shadow(4px 4px 0 var(--border));
    animation: gb-trophy 1.2s steps(1) infinite;   /* a saltos, como un sprite */
}
@keyframes gb-trophy {
    0% { transform: translateY(0) rotate(-6deg); }
    25% { transform: translateY(-3px) rotate(0); }
    50% { transform: translateY(-6px) rotate(6deg); }
    75% { transform: translateY(-3px) rotate(0); }
}

@keyframes gb-blink { 50% { opacity: .25; } }
/* Aviso de la ventana de recompensa (sustituir el Alquiler): parpadeo suave */
.reward-greed.is-alert { font-size: 1.45rem; line-height: 1.1; animation: gb-warn-blink 1.4s steps(1) infinite; }   /* mismo tamaño que .modal-text */
.reward-greed.is-alert svg { width: 1.7rem; height: 1.7rem; }
/* Atracción: el número elegido parpadea con un borde discontinuo mientras dura */
.slot.is-attract { outline: 2px dashed var(--text); outline-offset: -4px; animation: gb-blink 1s steps(1) infinite; }
/* Orgullo: indicador «+2 ♥» dentro del botón Renunciar */
.pride-tag { display: inline-flex; align-items: center; gap: .15rem; margin-left: .3rem; }
.pride-tag svg { width: 1.1em; height: 1.1em; }
@keyframes gb-warn-blink { 50% { opacity: .5; } }

/* ---------- Botones ---------- */
.btn {
    font-size: .8rem;
    letter-spacing: 0;
    line-height: 1.4;
    border: 0;
    background: var(--text);
    color: var(--on-accent);
    box-shadow: 0 6px 0 var(--border);
}
@media (hover: hover) { .btn:hover:not(:disabled) { filter: none; transform: translateY(2px); box-shadow: 0 4px 0 var(--border); } }
.btn:active:not(:disabled) { transform: translateY(6px); box-shadow: none; }
.btn:disabled { opacity: .45; box-shadow: 0 6px 0 var(--border); }


/* ---------- Power-ups: monocromo; el estado se marca por inversión de colores y bordes ---------- */
.inv-icon svg, .pu-icon svg { shape-rendering: crispEdges; }
.inv-icon, .pu-icon { filter: drop-shadow(2px 2px 0 var(--border)); }
.inv-slot { border-width: 3px; box-shadow: 3px 3px 0 var(--border); }
.inv-slot.is-empty { box-shadow: none; }
@media (hover: hover) { .inv-slot:not(.is-empty):not([aria-pressed="true"]):hover { border-color: var(--text); background: var(--surface-hover); } }
/* Seleccionado: colores invertidos (también con el cursor encima: la regla de hover de base.css tiene la misma especificidad) */
.inv-slot[aria-pressed="true"]:not(.is-empty),
.inv-slot[aria-pressed="true"]:not(.is-empty):hover { background: var(--text); border-color: var(--text); color: var(--on-accent); }
.inv-slot[aria-pressed="true"] .inv-icon { color: var(--on-accent); filter: none; }
.inv-slot.is-rescue { border-color: var(--text); animation: gb-blink .6s steps(1) infinite; }
.inv-name { font-size: 1.1rem; font-weight: 400; letter-spacing: 0; }
.inv-slot.is-empty .inv-name { font-size: 1.05rem; }

.inv-detail, .inv-stuck { border-width: 3px; box-shadow: 4px 4px 0 var(--border); }
.inv-stuck { border-style: dashed; }
.inv-detail h3 { font-size: .6rem; line-height: 1.5; letter-spacing: 0; }
.inv-detail p, .inv-stuck p { font-size: 1.2rem; line-height: 1.05; }
.inv-detail .inv-from { font-size: 1rem; opacity: .75; }   /* «Obtenido por Pedido»: de dónde ha llegado el power-up (solo los automáticos) */
.inv-detail .inv-why { color: var(--text); text-decoration: underline dashed; }
.inv-input { border-width: 3px; border-color: var(--text); border-radius: 0; box-shadow: inset 3px 3px 0 var(--border); font-size: 1rem; }
.inv-input::placeholder { color: var(--muted); opacity: 1; }
.inv-btn { border-width: 3px; font-size: 1.2rem; font-weight: 400; box-shadow: 3px 3px 0 var(--border); }
@media (hover: hover) { .inv-btn:hover:not(:disabled) { background: var(--text); color: var(--on-accent); } }
.inv-btn:active:not(:disabled) { transform: translate(3px, 3px); box-shadow: none; }
.inv-btn.danger { border-style: dashed; }
.inv-btn .inv-sub { display: block; margin-top: 4px; font-size: .85rem; letter-spacing: .05em; text-transform: uppercase; }

.reward-meter i { border-width: 2px; background: var(--bg); }
.reward-meter i.is-on { background: var(--text); border-color: var(--text); }
.reward-meter i.is-next { animation: gb-blink .8s steps(1) infinite; }

.rarity { font-size: .95rem; letter-spacing: .1em; }
h3 > .rarity { display: inline-block; vertical-align: middle; line-height: 1; position: relative; top: -1px; }   /* centrada con el nombre (si no, queda sobre su línea base y se ve más baja o más alta) */
.rarity[data-rarity="raro"] { padding: 0 4px; border: 2px solid var(--text); color: var(--text); }
.rarity[data-rarity="epico"] { padding: 0 4px; border: 2px solid var(--text); background: var(--text); color: var(--on-accent); }

.pu-card { border-width: 3px; box-shadow: 4px 4px 0 var(--border); }
@media (hover: hover) { .pu-card:hover { transform: translate(-2px, -2px); background: var(--surface-hover); box-shadow: 6px 6px 0 var(--border); } }
.pu-card[data-rarity="epico"] { border-style: double; border-width: 6px; }
.pu-name { font-size: .6rem; line-height: 1.5; }
/* Pedido: celdas del catálogo */
.cat-icon svg { shape-rendering: crispEdges; }
.cat-icon { filter: drop-shadow(2px 2px 0 var(--border)); }
.cat-item { border-width: 2px; box-shadow: 3px 3px 0 var(--border); }
.cat-item[data-rarity="epico"] { border-style: double; border-width: 4px; }
.cat-item.is-sel { outline-offset: 1px; }
.cat-name { font-size: .5rem; line-height: 1.5; }
.cat-head { font-size: .6rem; }
.pu-desc { font-size: 1.1rem; line-height: 1.05; }
/* Volcán en erupción: la lava sube y baja un punto desde la boca, apenas una vibración */
.volcano-lava { animation: gb-lava .5s steps(1) infinite; }
@keyframes gb-lava { 50% { transform: translateY(-1px); } }
.pu-warn { font-size: 1.1rem; line-height: 1.05; animation: gb-blink .8s steps(1) infinite; }   /* sustituir una pila: «¡Perderás tus 3 Vidas!» */
.btn.ghost { border: 3px solid var(--border); color: var(--text); box-shadow: none; }
@media (hover: hover) { .btn.ghost:hover:not(:disabled) { box-shadow: none; background: var(--surface-hover); } }

.draw-note { font-size: 1.1rem; color: var(--text); }
.draw-card.is-duo .draw-value { font-size: 1.4rem; text-shadow: none; }
.draw-card.is-multi .draw-value { font-size: 1.05rem; }
.draw-card.is-multi .duo-pick { padding: 2px 8px; border-width: 2px; box-shadow: 2px 2px 0 var(--border); }
.duo-pick { border-width: 3px; box-shadow: 3px 3px 0 var(--border); text-shadow: none; }
.duo-pick.is-previewed { background: var(--text); color: var(--on-accent); transform: none; }
@media (hover: hover) { .duo-pick:hover { background: var(--text); color: var(--on-accent); transform: none; } }

@media (max-width: 899px) {
    .draw-note { font-size: 1.05rem; }
    .draw-card.is-duo .draw-value { font-size: 1rem; }
    .inventory { border-top-width: 3px; }
    .inv-name { font-size: 1rem; }
}

/* ---------- Tablero ---------- */
.rail-track::before {
    width: 4px;
    right: 5px;
    background: repeating-linear-gradient(to bottom, var(--border) 0 6px, transparent 6px 12px);
}
.rail-marker { font-size: .5rem; line-height: 1.4; background: var(--text); box-shadow: 2px 2px 0 var(--border); }

.slot { border-width: 3px; border-color: var(--border); background: var(--surface); }
.slot-index { font-size: 1.15rem; }
.slot-value { font-size: .95rem; }

@media (hover: hover) { .slot.is-empty:hover { border-color: var(--text); background: var(--surface-hover); } }
.slot.is-fixed { background: var(--accent-2); border-color: var(--accent-2); }
.slot.is-fixed .slot-value,
.slot.is-fixed .slot-index { color: var(--on-accent); }
.slot.is-filled { background: var(--border); border-color: var(--text); }
.slot.is-filled .slot-index { color: var(--text); }
.slot.is-valid { border-style: dashed; border-color: var(--text); animation: gb-hint 1.6s ease-in-out infinite; }

/* Pista suave: pulsa entre dos verdes cercanos en vez de parpadear */
@keyframes gb-hint {
    0%, 100% { border-color: var(--text); background: color-mix(in srgb, var(--text) 16%, transparent); }
    50% { border-color: var(--muted); background: color-mix(in srgb, var(--text) 5%, transparent); }
}
/* El error manda sobre la pista (is-valid) y el objetivo (is-target), cuyas animaciones infinitas lo pisaban: sin su sacudida nunca había
   `animationend` y la casilla se quedaba oscura y parpadeando (sobre todo con un modo de power-up activo) */
.slot.is-wrong, .slot.is-valid.is-wrong, .slot.is-target.is-wrong { background: var(--text); border-color: var(--text); animation: shake .4s steps(1); }
.slot.is-wrong .slot-value,
.slot.is-wrong .slot-index { color: var(--on-accent); }
.slot.just-placed { animation-timing-function: steps(3); }

/* Power-ups sobre el tablero */
.slot.is-wild { background: var(--surface-hover); border-style: double; border-width: 6px; border-color: var(--text); }
.slot.is-target { border-style: dashed; border-color: var(--text); animation: gb-hint 1.6s ease-in-out infinite; }
.slot.is-magnet { border-style: dotted; border-color: var(--text); }
/* Centro de mesa: las casillas centrales libres llevan un segundo marco punteado por dentro (sin cambiar el tamaño de la fila) */
.slot.is-center { outline: 2px dotted var(--text); outline-offset: -6px; }
.slot.is-source { background: var(--text); border-color: var(--text); animation: gb-lift .8s steps(1) infinite; }
.slot.is-source .slot-value, .slot.is-source .slot-index { color: var(--on-accent); }
/* Número a mover: salta a trompicones sin parar, como un sprite */
@keyframes gb-lift {
    0%, 100% { transform: translateX(-6px) scale(1); }
    25% { transform: translateX(-12px) scale(1); }
    50% { transform: translateX(-4px) scale(1); }
    75% { transform: translateX(-10px) scale(1); }
}
/* Premio: regalo pixelado entre el índice y el "?", con un parpadeo de dos fotogramas; no toca el borde (lo usan Comodín, Imán y pistas) */
.slot-prize { color: var(--text); animation: gb-gift 1.6s steps(1) infinite; }
@keyframes gb-gift { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }
/* Trilero: el cubilete se mueve de lado a lado en las tres casillas marcadas */
.slot-cup { color: var(--text); shape-rendering: crispEdges; animation: gb-sway .5s steps(2) infinite; transform-origin: 50% 100%; }
/* Cupido: corazón pixelado que late (dos fotogramas) */
.slot-heart { color: var(--text); animation: gb-beat 1s steps(1) infinite; }
@keyframes gb-beat { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.18); } }
.slot-mole { color: var(--text); animation: gb-pop .7s steps(2) infinite; }   /* el topo asoma y se esconde, como en la recreativa */
@keyframes gb-pop { 0%, 100% { transform: translateY(2px); } 50% { transform: translateY(-3px); } }
/* Fantasma: casilla rayada y discontinua con el número atenuado; la cuenta atrás son fantasmitas */
.slot.is-ghost { border-style: dashed; border-color: var(--muted); cursor: default;
    background: repeating-linear-gradient(135deg, var(--surface) 0 5px, var(--surface-hover) 5px 10px); }
.slot.is-ghost .slot-value, .slot.is-ghost .slot-index { opacity: .6; }
.slot-ghosts { color: var(--text); }
/* Radiactivo: ondas pixeladas que se expanden desde la casilla, desfasadas, con la cuenta atrás en tréboles */
.slot.is-rad { border-color: var(--text); color: var(--text); }
.slot.is-rad::before, .slot.is-rad::after { animation: gb-wave 1.6s steps(6) infinite; }
.slot.is-rad::after { animation-delay: .8s; }
@keyframes gb-wave {
    0% { inset: 0; opacity: .9; }
    100% { inset: -16px; opacity: 0; }
}
/* Ídolo maldito: casilla maldita (bloqueada este turno): velo de ~25 %, borde discontinuo (para no parecerse a las fijas 0 y 1000),
   candado y dos capas de humo de puntitos que suben a distinto ritmo */
.slot.is-cursed { background: color-mix(in srgb, var(--text) 25%, transparent); border-color: var(--text); border-style: dashed; color: var(--text); cursor: not-allowed; }
.slot.is-cursed .slot-index { opacity: .6; }
.slot.is-cursed::before, .slot.is-cursed::after { content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.slot.is-cursed::before { background: radial-gradient(var(--text) 1.2px, transparent 1.5px) 0 0 / 9px 9px; opacity: .5; animation: gb-smoke-a .9s steps(6) infinite; }
.slot.is-cursed::after { background: radial-gradient(var(--text) 1px, transparent 1.3px) 4px 0 / 13px 13px; opacity: .3; animation: gb-smoke-b 1.6s steps(8) infinite; }
@keyframes gb-smoke-a { to { background-position: 0 -9px; } }
@keyframes gb-smoke-b { to { background-position: 4px -13px; } }
/* Semilla: casilla de tierra (borde punteado y fondo a puntos) con un brote por turno que falta; los brotes se mecen */
.slot.is-seed { border-style: dotted; border-color: var(--text); color: var(--text);
    background: radial-gradient(color-mix(in srgb, var(--muted) 30%, transparent) 1px, transparent 1.2px) 0 0 / 12px 12px, var(--surface); }
.slot.is-seed .slot-ghosts svg { animation: gb-sway 1.2s steps(2) infinite; transform-origin: 50% 100%; }
@keyframes gb-sway { 0% { transform: rotate(-8deg); } 100% { transform: rotate(8deg); } }
/* huevo: casilla de paja (borde discontinuo) con un huevo por turno que falta; los huevos se balancean y el último, agrietado, tiembla
   más rápido. Al eclosionar (.is-hatching) toda la casilla tiembla a trompicones */
/* Platillo volante: se balancea sobre su casilla vacía */
/* La fila por la que baja: cielo con estrellas (puntitos de tres tamaños que se desplazan a distinta velocidad, como si volara) y el mismo
   negro al 10 % que la telaraña; las estrellas al 35 % de opacidad, como la trama de la telaraña */
.slot.is-ufo {
    border-color: var(--text);
    --star: color-mix(in srgb, var(--text) 35%, transparent);
    background-image:
        linear-gradient(rgba(0, 0, 0, .1), rgba(0, 0, 0, .1)),
        radial-gradient(circle, var(--star) 1px, transparent 1.4px),
        radial-gradient(circle, var(--star) 1px, transparent 1.4px),
        radial-gradient(circle, var(--star) 1.2px, transparent 1.6px);
    background-size: auto, 37px 23px, 53px 31px, 71px 17px;
    background-position: 0 0, 5px 4px, 19px 11px, 40px 2px;
    animation: gb-stars 3s linear infinite;
}
@keyframes gb-stars { to { background-position: 0 0, -32px 4px, -34px 11px, -31px 2px; } }
/* Abducción: el platillo con la paleta invertida tapa la casilla; el número sube y se desvanece; al final parpadea y desaparece */
.ufo-fx { background: var(--text); color: var(--on-accent); font-family: var(--font-display); animation: gb-abduct 2.4s steps(1) forwards; }
.ufo-fx svg { animation: gb-sway .6s steps(2) infinite; }
.ufo-fx-num { font-size: 1.1rem; animation: gb-abduct-num 2.4s steps(12) forwards; }
@keyframes gb-abduct { 0% { opacity: 1; } 80% { opacity: .55; } 90% { opacity: 1; } 95% { opacity: .35; } 100% { opacity: 0; } }
@keyframes gb-abduct-num { 0% { transform: none; opacity: 1; } 100% { transform: translateY(-130%); opacity: 0; } }
.slot.is-ufo .slot-ghosts svg { animation: gb-sway .9s steps(2) infinite; transform-origin: 50% 50%; }
/* Wi-Fi: las casillas que alcanza llevan un icono pequeño y tenue; la del router, un icono por turno que parpadea y un borde más marcado */
.slot-mark { color: var(--text); opacity: .75; }   /* icono del power-up que puso el número o el comodín (Semilla, Correlativo, Espejo, Suerte, Compresor, Comodín, Parche, Goma…) */
.slot.is-wifi-range .wifi-pip { opacity: .5; }
.slot.is-wifi { outline: 2px solid var(--text); outline-offset: -4px; }
.slot.is-wifi .wifi-grp svg { animation: gb-wifi 1.2s steps(1) infinite; }
@keyframes gb-wifi { 0%, 70% { opacity: 1; } 70.01%, 100% { opacity: .3; } }
/* Mina: la fila se oscurece (negro al 10 %, como la telaraña) con borde macizo; las minas de la cuenta atrás parpadean y, en el último
   turno, parpadea también toda la casilla */
.slot.is-mine {
    border-color: var(--text);
    background-image: linear-gradient(rgba(0, 0, 0, .1), rgba(0, 0, 0, .1));
}
.slot.is-mine .slot-ghosts svg { animation: gb-mine-blink 1s steps(1) infinite; }
.slot.is-mine-last { animation: gb-mine-flash .4s steps(1) infinite; }
.slot.is-mine-last .slot-ghosts svg { animation-duration: .4s; }
@keyframes gb-mine-blink { 0%, 60% { opacity: 1; } 60.01%, 100% { opacity: .25; } }
@keyframes gb-mine-flash { 0%, 50% { transform: none; } 50.01%, 100% { transform: translateX(2px); } }
.slot.is-egg { border-style: dashed; border-color: var(--text); color: var(--text); }
.slot.is-egg .slot-ghosts svg { animation: gb-sway 1.6s steps(2) infinite; transform-origin: 50% 100%; }
.slot.is-egg[data-ghost^="e1"] .slot-ghosts svg, .slot.is-egg[data-ghost^="e0"] .slot-ghosts svg { animation-duration: .5s; }   /* el último huevo, agrietado */
.slot.is-hatching { animation: gb-hatch .3s steps(1) infinite; }
.slot.is-egg.is-hatching[data-ghost] .slot-ghosts svg { animation-duration: .15s; }
@keyframes gb-hatch {
    0% { transform: translateX(-3px); }
    50% { transform: translateX(3px); }
}
/* Telaraña: trama sutil sobre toda la fila y un icono por número que aún puede atrapar. Atascado, parpadea y tiembla (.is-alert);
   al atrapar un número (.is-trap) la fila da un pequeño bote y la trama se ve entera un instante */
.slot-web { color: var(--text); opacity: .35; }
.slot.is-web {
    border-color: var(--muted);
    background-image: linear-gradient(rgba(0, 0, 0, .1), rgba(0, 0, 0, .1));   /* negro al 10 %: la oscurece un poco */
}
.slot.is-web.is-alert { border-color: var(--text); animation: gb-web-shake .6s steps(1) infinite; }
.slot.is-web.is-alert .slot-web { animation: gb-web-blink .6s steps(1) infinite; }
@keyframes gb-web-shake {
    0% { transform: translateX(-1px); }
    20% { transform: translateX(1px); }
    40% { transform: translateX(-1px); }
    60% { transform: translateX(1px); }
    80%, 100% { transform: none; }
}
@keyframes gb-web-blink {
    0%, 50% { opacity: 1; }
    50.01%, 100% { opacity: .2; }
}
.slot.is-trap { animation: gb-trap .45s steps(1); }
.slot.is-trap .slot-web { opacity: 1; }
@keyframes gb-trap {
    0% { transform: scale(1.04); }
    30% { transform: scale(.96); }
    60% { transform: scale(1.02); }
    100% { transform: none; }
}
/* Zombie: borde doble y cuenta atrás en cabezas; la vecina mordida da un tirón a trompicones con el fondo invertido */
.slot.is-zombie { border-style: double; border-width: 4px; color: var(--text); }
/* Portal: los dos huecos enlazados, con borde de puntos y el remolino girando a saltos */
.slot.is-portal { border-style: dotted; }
.slot.is-portal .slot-ghosts svg { animation: gb-portal 2.4s steps(8) infinite; transform-origin: 50% 50%; }
@keyframes gb-portal { to { transform: rotate(360deg); } }
/* Virus: el número infectado lleva borde de puntos y su icono late; el recién contagiado pulsa con just-placed */
.slot.is-infected { border-style: dotted; border-width: 4px; }
.slot.is-infected .slot-ghosts svg { animation: gb-sway 1.2s steps(2) infinite; transform-origin: 50% 50%; }
/* Vecinas amenazadas: un breve temblor a trompicones y una pausa, en bucle (antes que .is-bitten para que el mordisco mande) */
.slot.is-threat { animation: gb-shiver 1.6s steps(1) infinite; }
@keyframes gb-shiver {
    0% { transform: translateX(-2px); }
    6% { transform: translateX(2px); }
    12% { transform: translateX(-2px); }
    18% { transform: translateX(2px); }
    24%, 100% { transform: none; }
}
.slot.is-bitten { background: var(--text); animation: gb-bite .4s steps(1); }
.slot.is-bitten .slot-value, .slot.is-bitten .slot-index { color: var(--on-accent); }
@keyframes gb-bite {
    0% { transform: translateX(-5px); }
    25% { transform: translateX(5px); }
    50% { transform: translateX(-3px); }
    75% { transform: translateX(2px); }
    100% { transform: none; }
}
.reward-gift { color: var(--text); animation: gb-gift 1.6s steps(1) infinite; }
/* Bomba: las casillas vaciadas tiemblan a trompicones un instante, con el fondo invertido */
.slot.is-blast { background: var(--text); border-color: var(--text); animation: gb-blast .45s steps(1); }
.slot.is-blast .slot-value, .slot.is-blast .slot-index { color: var(--on-accent); }
/* Baúl: al guardar, la casilla se encoge a saltos hacia la izquierda (el número «entra» en el baúl) y vuelve, sin explosión */
.slot.is-stored { animation: gb-stored .5s steps(1); }
@keyframes gb-stored {
    0% { transform: scaleX(.94) translateX(-10px); border-color: var(--text); opacity: .5; }
    25% { transform: scaleX(.96) translateX(-6px); border-color: var(--text); opacity: .65; }
    50% { transform: scaleX(.98) translateX(-3px); opacity: .8; }
    75% { transform: translateX(-1px); opacity: .9; }
    100% { transform: none; opacity: 1; }
}
/* Fénix: la casilla arde (parpadeo de llama a saltos) y se apaga */
.slot.is-burn { animation: gb-burn .9s steps(1); }
@keyframes gb-burn {
    0%, 40% { background: var(--text); border-color: var(--text); transform: translateY(-2px); }
    20%, 60% { background: var(--surface); border-color: var(--text); transform: translateY(1px); }
    80% { background: var(--text); border-color: var(--text); transform: translateY(0); }
    100% { background: var(--surface); border-color: var(--border); }
}
@keyframes gb-blast {
    0% { transform: translateX(-8px); }
    20% { transform: translateX(8px); }
    40% { transform: translateX(-6px); }
    60% { transform: translateX(5px); }
    80% { transform: translateX(-3px); }
    100% { transform: translateX(0); background: var(--surface); border-color: var(--border); }
}
.rail-magnet { border-width: 2px; background: repeating-linear-gradient(to bottom, var(--text) 0 4px, transparent 4px 8px); }


/* ---------- Toast y modales ---------- */
.toast { border-width: 3px; box-shadow: 4px 4px 0 var(--border); font-size: 1.35rem; }
.toast.bad { border-style: dashed; }

.modal { border-width: 4px; box-shadow: 8px 8px 0 var(--border); }
.modal::backdrop { backdrop-filter: none; }
.modal.reward::backdrop { background: var(--backdrop-reward); }   /* recompensa: más transparente para ver el inventario de debajo */
.modal[open] { animation-timing-function: steps(4); }
.modal.is-lose { border-style: dashed; }
.modal-title { font-size: 1.05rem; line-height: 1.5; letter-spacing: 0; text-shadow: 3px 3px 0 var(--border); }
.modal.is-lose .modal-title { animation: gb-blink 1s steps(1) infinite; }
.modal-text { font-size: 1.45rem; line-height: 1.1; }
.help-list { font-size: 1.4rem; line-height: 1.1; }

/* ---------- Móvil ---------- */
@media (max-width: 899px) {
    .stat { padding: 6px 4px; }
    .stat-label { font-size: .95rem; letter-spacing: 0; }
    .stat-value { font-size: .6rem; }
    .draw-label { font-size: .95rem; letter-spacing: .1em; }
    .draw-value { font-size: 1.8rem; }
    .btn { font-size: .5rem; padding: 10px 6px; box-shadow: 0 4px 0 var(--border); }
    .draw-actions .btn { font-size: .65rem; line-height: 1.5; }   /* el botón de empezar / jugar de nuevo, en dos líneas, al 35 % del ancho */
    .btn:disabled { box-shadow: 0 4px 0 var(--border); }
    .modal .btn { font-size: .65rem; padding: 14px 10px; line-height: 1.5; }   /* en las ventanas sobra sitio: botones más cómodos (los .small de Configuración conservan el suyo, abajo) */
    .logo { font-size: .6rem; }
    .slot-value { font-size: .8rem; }
}

/* ---------- Power-ups gastados, etiqueta de la tarjeta e iconos de efectos listos ---------- */
.inv-ghost { animation-timing-function: steps(6); background: var(--bg); box-shadow: 3px 3px 0 var(--border); }
.inv-ghost.is-life { animation-timing-function: steps(3); border-style: dashed; }
.draw-fx { font-size: .6rem; line-height: 1.5; letter-spacing: 0; color: var(--text); text-shadow: 2px 2px 0 var(--border); }
.draw-fx.show { animation-timing-function: steps(6); }
.draw-card.is-stuck.is-dismissing .draw-value { animation-timing-function: steps(4); }
.draw-badge { filter: drop-shadow(2px 2px 0 var(--border)); animation-timing-function: steps(2); }
.draw-badge svg { shape-rendering: crispEdges; }
@media (max-width: 899px) {
    .draw-fx { font-size: .5rem; }
}
/* ---------- Derrota: la pantalla parpadea con la paleta invertida y aparece GAME OVER ---------- */
html.is-lost .lose-fx { background: none; animation: gb-lose-fx var(--lose-ms, 1500ms) steps(1) forwards; }
html.is-lost .lose-fx::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--text);
    animation: gb-flash var(--lose-ms, 1500ms) steps(1) forwards;
}
html.is-lost .lose-fx::after {
    content: "GAME OVER";
    position: absolute;
    top: 44%;
    left: 50%;
    transform: translateX(-50%);
    padding: 14px 22px;
    background: var(--bg);
    border: 4px solid var(--text);
    color: var(--text);
    font-family: var(--font-display);
    font-size: clamp(.8rem, 3.2vw, 1.4rem);
    white-space: nowrap;
    box-shadow: 6px 6px 0 var(--border);
    animation: gb-blink .3s steps(1) infinite;
}
/* ---------- Disquete: al cargar la partida, la pantalla parpadea invertida, queda cubierta a la mitad (ahí cambia el tablero) y sale CARGANDO con su barra ---------- */
html.is-loading .lose-fx { background: none; animation: gb-load-fx var(--load-ms, 2200ms) steps(1) forwards; }
html.is-loading .lose-fx::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--text);
    animation: gb-load-flash var(--load-ms, 2200ms) steps(1) forwards;
}
html.is-loading .lose-fx::after {
    content: "CARGANDO...";
    position: absolute;
    top: 44%;
    left: 50%;
    transform: translateX(-50%);
    padding: 14px 22px 20px;
    background: linear-gradient(var(--text), var(--text)) no-repeat 22px calc(100% - 8px) / 0 6px, var(--bg);
    border: 4px solid var(--text);
    color: var(--text);
    font-family: var(--font-display);
    font-size: clamp(.8rem, 3.2vw, 1.4rem);
    white-space: nowrap;
    box-shadow: 6px 6px 0 var(--border);
    animation: gb-load-bar var(--load-ms, 2200ms) steps(12) forwards;
}
@keyframes gb-load-fx { 0%, 97% { opacity: 1; } 100% { opacity: 0; } }
@keyframes gb-load-flash {
    0%, 16%, 32%, 40%, 60%, 68%, 84% { opacity: 1; }
    8%, 24%, 36%, 76%, 92%, 100% { opacity: 0; }
}
@keyframes gb-load-bar { from { background-size: 0 6px; } to { background-size: calc(100% - 44px) 6px; } }
/* Disquete guardado (Respaldo): el icono se balancea de lado a lado como aviso */
/* Chistera: al sacar el mago un power-up, el icono vibra un instante (la clase la pone y quita game.js) */
.inv-slot.is-hat-shake .inv-icon svg { animation: gb-sway .09s steps(2) 8; transform-origin: 50% 100%; }
.inv-slot[data-entry="disquete:1"] .inv-icon svg { animation: gb-sway 1s steps(2) infinite; transform-origin: 50% 50%; }
@keyframes gb-lose-fx { 0%, 98% { opacity: 1; } 100% { opacity: 0; } }
@keyframes gb-flash {
    0%, 20%, 40% { opacity: 1; }
    10%, 30%, 50%, 100% { opacity: 0; }
}

/* ---------- Configuración (modo, dificultad, estadísticas) y etiqueta del modo ---------- */
.mode-tag { font-size: 1rem; letter-spacing: .04em; }
.modal.settings .set-group h3 { font-size: .6rem; line-height: 1.5; letter-spacing: 0; }
.seg button { border-width: 3px; box-shadow: 3px 3px 0 var(--border); font-size: 1.2rem; font-weight: 400; }
.seg button small { font-size: 1rem; }
.seg button[aria-pressed="true"] { background: var(--text); border-color: var(--text); color: var(--on-accent); }
.seg button[aria-pressed="true"] small { color: var(--on-accent); }
.set-desc, .set-now { font-size: 1.2rem; line-height: 1.05; }
.set-stats th { font-size: .95rem; letter-spacing: 0; }
.set-stats td { font-size: 1.25rem; }
.set-stats tr.is-selected td { color: var(--text); text-decoration: underline dashed; }
.btn.small { font-size: .55rem; box-shadow: 0 4px 0 var(--border); }
.btn:disabled { box-shadow: 0 6px 0 var(--border); }
/* Modo clásico: solo vidas (corazones) */
html[data-mode="classic"] .inv-slot.is-empty .inv-icon { opacity: .25; }
/* Teléfono: mientras suena (solo entonces el icono lleva .ph-ring), el auricular se agita a saltos */
.ph-ring { transform-box: fill-box; transform-origin: 50% 100%; animation: gb-ring .3s steps(2) infinite; }
@keyframes gb-ring { 0% { transform: translateY(0) rotate(-7deg); } 100% { transform: translateY(-1.5px) rotate(7deg); } }

/* Órdago: el premio dentro de la ficha (icono, nombre, rareza y descripción) */
.ordago-prize { display: flex; align-items: flex-start; gap: 10px; margin: 0; padding: 6px; background: rgba(0, 0, 0, .1); }
.ordago-prize .rarity { margin-left: 8px; }
.ordago-icon { flex: 0 0 auto; width: 32px; height: 32px; color: var(--pu, var(--text)); }
.ordago-icon svg { width: 100%; height: 100%; }
.ordago-prize p { margin: 4px 0 0; }
.inv-hint.is-center { text-align: center; }

/* ---------- Purga: un parpadeo breve de la pantalla con la paleta invertida ---------- */
html.is-purge body { animation: gb-purge .35s steps(1); }
@keyframes gb-purge { 0%, 40% { filter: invert(1); } 40.01%, 70% { filter: none; } 70.01%, 100% { filter: invert(1); } }

/* Jackpot: la cifra de los rodillos, grande y a bloque */
.jackpot-reel { min-width: 8rem; padding: 14px 22px; font-family: var(--font-display); font-size: 3rem; line-height: 1; color: var(--on-accent); background: var(--text); border: 4px solid var(--border); box-shadow: 6px 6px 0 var(--border); }

/* Catálogo de descubiertos: la casilla sin descubrir va punteada con el «?» pixelado; la ficha como la del inventario */
.cat-lock { border-width: 3px; font-size: 1.4rem; }
.modal.catalog .modal-title { font-size: 1.05rem; }
.pu-card.cat-tile { border-width: 2px; box-shadow: 3px 3px 0 var(--border); }
.pu-card.cat-tile[data-rarity="epico"] { border-width: 4px; }
.cat-tile .pu-name { font-size: .725rem; }   /* en el catálogo, el nombre 2 px mayor y la rareza 1 px mayor que en las demás tarjetas */
.cat-tile .rarity { font-size: 1.0125rem; }
