:root{
  --bg: #0f0018;
  --bg2: #1F1430;
  --gold: #FFD23F;
  --pink: #FF3D81;
  --lime: #B4FF39;
  --cream: #F5F0E8;
  --muted: #9C8BB5;
  --blue: #8FB8FF;
  --lilac: #B98EFF;
  /* Alto de la caja 3D de la arena de batalla (.battle-frame) — variable
     porque .bar-track (la barra de aura, hermana de .battle-frame y
     .arena) necesita este mismo número para calcular dónde cae la línea
     divisoria entre las dos y centrarse justo ahí; declararlo una sola
     vez evita que se desincronicen si se vuelve a ajustar el alto. */
  --battle-frame-height: 520px;
}
*{box-sizing:border-box; margin:0; padding:0;}
button, input, select, textarea{ font-family: inherit; }
/* Oculto solo visualmente (no display:none/visibility:hidden, que se
   descartan de la lectura semántica) — sigue en el DOM para lectores
   de pantalla y buscadores, aunque no se vea en pantalla. Usado en el
   único <h1> de la página: el logo estilizado ya hace de titular
   visual, esto es el mismo texto en formato que un buscador lee. */
.visually-hidden{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
/* El desplegable va en position:absolute (no como hijo normal del flex
   column que fue esto antes) — con visibility:hidden en vez de
   display:none para no perder la transición, un hijo EN FLUJO sigue
   ocupando su hueco entero aunque esté invisible, así que el propio
   widget se inflaba hasta abarcar botón + hueco del desplegable, y ESA
   caja entera (no solo el círculo) disparaba el :hover — bastaba con
   pasar por encima de donde iría el desplegable, sin verlo, para que
   saltara y se comiera clics pensados para lo que hubiera detrás o
   debajo. Absoluto no agranda la caja del padre, y el :hover del
   ancestro se sigue disparando al entrar en un descendiente aunque
   escape visualmente de su caja — así que sigue abriéndose igual de
   bien, solo que ahora sin esa zona muerta.
   El top del desplegable tiene que TOCAR el borde inferior del botón
   (mismo valor que la altura del botón, sin ningún hueco de por
   medio): con un hueco, aunque sean pocos píxeles, el ratón lo cruza
   al bajar hacia el desplegable y ahí no hay ni botón ni desplegable
   bajo el puntero — se pierde el :hover a media bajada y el
   desplegable se cierra antes de llegar a él. */
/* Selector de idioma: mismo patrón que el widget de sonido — el botón
   muestra el código del idioma activo y al pasar el ratón se revela
   debajo la lista de los demás idiomas disponibles, como un selector de
   verdad en vez de un simple interruptor — así añadir un tercer idioma
   el día de mañana es solo sumarlo a LANG_META, sin tocar esto. Sin
   bandera: el idioma ya se detecta solo al entrar, así que esto es solo
   el ajuste manual, y el código de dos letras es más claro que un
   símbolo que además no siempre representa bien el idioma. Círculo
   igual que el de sonido, a juego con el resto del grupo. */
.lang-widget{ position: fixed; top: 14px; right: 62px; z-index: 55; }
.lang-toggle{
  width: 40px; height: 40px; border-radius: 50%;
  background: rgba(255,255,255,0.06); border: 1.5px solid rgba(255,255,255,0.15);
  color: var(--cream); font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 12px; cursor: pointer;
  display:flex; align-items:center; justify-content:center;
  transition: border-color 0.15s ease, background 0.15s ease;
  flex: none;
}
.lang-toggle:hover{ border-color: var(--gold); background: rgba(255,210,63,0.1); }
.lang-dropdown{
  position: absolute; top: 40px; right: 0;
  min-width: 40px;
  display:flex; flex-direction:column; gap: 4px;
  background: var(--bg2); border: 1.5px solid rgba(255,255,255,0.15); border-radius: 14px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4); padding: 6px;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.15s ease;
}
.lang-widget:hover .lang-dropdown{
  opacity: 1; visibility: visible; pointer-events: auto;
}
.lang-option{
  display:flex; align-items:center; gap: 8px; width:100%; padding: 6px 8px;
  background:none; border:none; border-radius: 8px; cursor:pointer;
  color: var(--cream); font-family:'Tomorrow', sans-serif; font-weight:600; font-size: 11px; white-space:nowrap;
  transition: background 0.15s ease;
}
.lang-option:hover{ background: rgba(255,255,255,0.08); }
.lang-option.active{ color: var(--gold); }

.sound-widget{ position: fixed; top: 14px; right: 14px; z-index: 55; }
.sound-toggle{
  width: 40px; height: 40px; border-radius: 50%;
  background: rgba(255,255,255,0.06); border: 1.5px solid rgba(255,255,255,0.15);
  color: var(--cream); font-size: 17px; cursor: pointer;
  display:flex; align-items:center; justify-content:center;
  transition: border-color 0.15s ease, background 0.15s ease;
  flex: none;
}
.sound-toggle:hover{ border-color: var(--gold); background: rgba(255,210,63,0.1); }
.sound-toggle.muted{ opacity: 0.5; }
/* Se revela solo con el ratón encima (del botón o del propio indicador,
   ya que ambos son parte continua del mismo contenedor) — clicar el
   botón ya no abre nada, ahora silencia/restaura directamente. */
.volume-dropdown{
  position: absolute; top: 40px; right: 0;
  width: 44px; height: 140px;
  display:flex; align-items:center; justify-content:center;
  background: var(--bg2); border: 1.5px solid rgba(255,255,255,0.15); border-radius: 14px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.15s ease;
}
.sound-widget:hover .volume-dropdown{
  opacity: 1; visibility: visible; pointer-events: auto;
}
.volume-dropdown input[type="range"]{
  width: 100px; accent-color: var(--gold); cursor: pointer;
  transform: rotate(-90deg);
}
body{
  position:relative;
  background: var(--bg);
  color: var(--cream);
  font-family: 'Tomorrow', sans-serif;
  min-height:100vh;
  display:flex;
  flex-direction:column;
  align-items:center;
  padding: 20px 14px 40px;
  overflow-x:hidden;
}
/* Atmósfera de fondo: campo de estrellas + nebulosas de color, para que
   se sienta como el interior de un juego y no una página en blanco. */
body::before{
  content:""; position:fixed; inset:0; z-index:-2; pointer-events:none;
  background-image:
    radial-gradient(1.6px 1.6px at 12% 22%, rgba(255,255,255,0.55), transparent),
    radial-gradient(1.4px 1.4px at 78% 12%, rgba(255,255,255,0.45), transparent),
    radial-gradient(1.2px 1.2px at 62% 68%, rgba(255,255,255,0.5), transparent),
    radial-gradient(1.2px 1.2px at 28% 82%, rgba(255,255,255,0.35), transparent),
    radial-gradient(1.6px 1.6px at 92% 58%, rgba(255,255,255,0.4), transparent),
    radial-gradient(1px 1px at 45% 38%, rgba(255,255,255,0.3), transparent),
    radial-gradient(1px 1px at 8% 55%, rgba(255,255,255,0.3), transparent);
  background-repeat: repeat;
  background-size: 340px 340px;
  opacity: 0.65;
}
body::after{
  content:""; position:fixed; inset:-40px; z-index:-1; pointer-events:none;
  background:
    radial-gradient(520px 380px at 50% 0%, rgba(190,110,255,0.20), transparent 65%),
    radial-gradient(440px 320px at 10% 6%, rgba(255,61,129,0.16), transparent 70%),
    radial-gradient(400px 320px at 90% 16%, rgba(143,184,255,0.14), transparent 70%),
    radial-gradient(440px 360px at 50% 100%, rgba(180,255,57,0.08), transparent 70%);
  animation: nebulaDrift 50s ease-in-out infinite;
}
/* Deriva muy lenta de las nebulosas de fondo, para que la atmósfera se
   sienta viva sin que se note como una animación "activa" — de ahí que
   inset sea -40px en vez de 0: así el desplazamiento nunca deja ver un
   borde vacío. */
@keyframes nebulaDrift{
  0%, 100%{ transform: translate(0, 0); }
  50%{ transform: translate(18px, -14px); }
}
.logo-btn{
  display:block; width: min(81vw, 414px); margin: 0 auto 4px;
  padding:0; border:none; background:none; cursor:pointer; position:relative;
}
.logo{
  display:block; width:100%; height:auto;
}
/* Chispitas mágicas muy sutiles sobre el logo — aparecen y desaparecen
   en bucle, cada una con su propio retraso/duración (fijados inline en
   el HTML) para que no se note el patrón. */
.logo-particles{ position:absolute; inset:0; pointer-events:none; }
.logo-particles .particle{
  position:absolute; width:3px; height:3px; border-radius:50%;
  background: var(--gold); box-shadow: 0 0 6px 1px var(--gold);
  opacity:0; animation-name: particleTwinkle; animation-timing-function: ease-in-out; animation-iteration-count: infinite;
}
.logo-particles .particle:nth-child(2),
.logo-particles .particle:nth-child(4){ background: var(--lilac); box-shadow: 0 0 6px 1px var(--lilac); }
.logo-particles .particle:nth-child(6){ background: var(--cream); box-shadow: 0 0 5px 1px var(--cream); }
@keyframes particleTwinkle{
  0%, 100%{ opacity:0; transform: translateY(0) scale(0.7); }
  50%{ opacity:0.85; transform: translateY(-6px) scale(1); }
}
.tagline{ color: var(--muted); font-size: 15.5px; margin: -6px 0 22px; text-align:center; font-weight: 400; }
/* position:relative: las dos barras de aura cuelgan directamente de aquí
   (hermanas de .battle-frame y .arena, no hijas de ninguna de las dos —
   ver el comentario junto a .you-bar/.rival-bar) para poder colocarlas
   justo a caballo de la línea que separa ambas cajas sin que el
   clip-path de ninguna se las coma por la mitad. */
.arena-screen{ position:relative; width:100%; max-width: 520px; }
.arena{
  position:relative; width:100%;
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.015));
  border: 2px solid rgba(255,210,63,0.22);
  /* Sin recorte arriba a la izquierda (a diferencia de antes) — esta caja
     va pegada justo debajo de .battle-frame, así que el borde de arriba
     tiene que quedar recto de punta a punta: solo así las dos cajas se
     leen como un único marco partido por una sola línea, no como dos
     paneles con un hueco triangular en la unión. */
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 18px), calc(100% - 18px) 100%, 0 100%);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.3), 0 20px 50px rgba(0,0,0,0.4), inset 0 0 30px rgba(255,61,129,0.05);
  /* El borde de arriba (la línea divisoria con .battle-frame — ver
     comentario justo encima) va en lila intenso, no en el dorado del
     resto del marco: junto con el borde de .bar-track (mismo lila),
     forma una única línea continua que une visualmente el bloque de aura
     (barra + % en .battle-frame + esta línea), en vez de leerse como dos
     cosas sueltas. */
  border-top-color: var(--lilac);
  /* padding-top más pequeño que el resto a propósito: la barra de aura ya
     se mete 10.5px dentro de esta caja (ver .bar-track), así que el hueco
     real hasta el % de aura era mayor de lo que parecía a simple vista —
     pedido explícitamente más pegado tras verlo en escritorio (y una
     segunda vez, junto con el resto de márgenes internos de este bloque
     — ver .energy-group/.attack-row/.result-row/.turn-timer-row/.moves —
     comparándolo con la imagen de referencia, donde todo el bloque va
     más compacto). */
  padding: 2px 16px 13px;
}
/* Antes eran dos cajas .fighter separadas (una por avatar 2D/svg) — ahora
   los dos personajes viven en un único canvas 3D compartido (avatar3d.js
   createBattleArena3D), así que el marco es UN rectángulo. Mismo estilo de
   borde/fondo/recorte de esquinas que .arena (justo debajo, pegada sin
   margen) para que las dos cajas se lean como un único panel partido en
   dos, no como dos tarjetas flotantes con estilos distintos. */
.battle-frame{
  position:relative; width:100%; height: var(--battle-frame-height); margin-bottom: 0;
  background: linear-gradient(180deg, rgba(185,142,255,0.14), rgba(46,31,82,0.32));
  border: 2px solid rgba(255,210,63,0.22);
  border-bottom: none;
  /* Solo la esquina de arriba a la izquierda recortada (no las 4, ni la de
     abajo-derecha que si lleva .arena) - el borde de abajo tiene que
     quedar recto de punta a punta para que encaje pegado con .arena sin
     dejar un hueco triangular justo en la union. */
  clip-path: polygon(18px 0, 100% 0, 100% 100%, 0 100%, 0 18px);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.3), 0 20px 50px rgba(0,0,0,0.4), inset 0 0 30px rgba(255,61,129,0.05);
}
.battle-canvas-wrap{
  position:relative; width:100%; height:100%;
  overflow:hidden;
}
.battle-canvas-wrap canvas{ position:absolute; inset:0; width:100% !important; height:100% !important; touch-action:none; }
.battle-frame .vs{
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
  font-family:'Tomorrow', sans-serif; font-weight:800; font-size: 14px; letter-spacing:1px;
  color: var(--cream); text-shadow: 0 2px 6px rgba(0,0,0,0.7);
  opacity:0.8; pointer-events:none; z-index:3;
}
/* Arrancaba pegado al borde de arriba de .fighter (top:-4px) y encima
   flotaba hacia arriba (translateY negativo) — el propio clip-path de
   .arena recorta justo por ahí, así que a los pocos fotogramas ya
   estaba fuera de la zona visible y prácticamente no daba tiempo a
   leerlo. Ahora arranca bastante más abajo (dentro del avatar) y solo
   sube un poco, así el recorrido entero queda dentro de la zona
   visible; y dura bastante más (2.2s en vez de 1.2s), con la mayor
   parte de ese tiempo a opacidad plena antes de desvanecerse al final. */
.bonus-pop{
  position:absolute; top: 30%; left:50%;
  font-family:'Tomorrow', sans-serif; font-weight:800; font-size: 20px;
  color: var(--lime); text-shadow: 0 0 10px rgba(180,255,57,0.8);
  opacity:0; pointer-events:none; z-index:5;
}
/* Cada personaje vive a un lado del mismo canvas ahora (antes cada uno
   tenía su propia caja al 50%, por eso bastaba con left:50% común) — estos
   dos anchors sustituyen a ese left compartido. */
.bonus-pop.you{ left:27%; }
.bonus-pop.rival{ left:73%; }
.bonus-pop.show{ animation: bonusFloat 2.2s ease-out forwards; }
@keyframes bonusFloat{
  0%{ opacity:0; transform: translateX(-50%) translateY(0) scale(0.7); }
  10%{ opacity:1; transform: translateX(-50%) translateY(-6px) scale(1.25); }
  75%{ opacity:1; transform: translateX(-50%) translateY(-24px) scale(1); }
  100%{ opacity:0; transform: translateX(-50%) translateY(-32px) scale(1); }
}
/* Nombres de los luchadores: ahora se superponen sobre la caja 3D (antes
   estaban encima de la barra de vida, dentro de .stats-col) — así toda la
   fila de abajo queda solo para barra+energía y se gana bastante más alto
   para ver el personaje entero. */
/* La barra de aura vive a caballo de la línea divisoria (ver más abajo,
   .bar-track — hermana de .battle-frame y .arena, no hija de ninguna de
   las dos) — el nombre se queda justo encima de ella. */
.battle-frame .fighter-name{
  position:absolute; bottom: 30px; z-index: 2;
  font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 16px;
  color: var(--cream); text-shadow: 0 2px 6px rgba(0,0,0,0.85), 0 0 10px rgba(0,0,0,0.5);
  pointer-events:none; max-width: 42%;
}
.battle-frame .fighter-name.you{ left: 14px; }
.battle-frame .fighter-name.rival{ right: 14px; text-align:right; }
/* % de aura — antes vivía en .stats-col, dentro de .arena. Se mueve aquí
   (encima de la barra, debajo del nombre) porque ese tramo del marco 3D
   quedaba vacío, y de paso deja sitio para subir la fila de energía en
   .arena (ver .stats-row más abajo). */
.battle-frame .aura-label{
  position:absolute; bottom: 10px; z-index: 2;
  font-size: 13px; color: var(--lilac); text-transform: uppercase;
  letter-spacing: 0.4px; font-weight: 700;
  text-shadow: 0 2px 6px rgba(0,0,0,0.85), 0 0 10px rgba(0,0,0,0.5);
  pointer-events:none;
}
.battle-frame .aura-label.you{ left: 14px; }
.battle-frame .aura-label.rival{ right: 14px; text-align:right; }
/* Puntuación de precisión del golpe (antes iba dentro de .attack-text,
   p.ej. "Nombre 82% ⚡300") — ahora es su propio marcador grande, también
   superpuesto en la caja 3D, más fácil de leer de un vistazo. Mismo ciclo
   de entrada/salida que .attack-text (clases enter/leave, ver JS). */
.timing-score{
  position:absolute; bottom: 62px; z-index: 2;
  font-family:'Tomorrow', sans-serif; font-weight:800; font-size: 26px;
  opacity: 0; pointer-events:none;
  text-shadow: 0 2px 8px rgba(0,0,0,0.85);
}
.timing-score.you{ left: 27%; transform: translateX(-50%); color: var(--blue); }
.timing-score.rival{ right: 27%; transform: translateX(50%); color: var(--pink); }
.timing-score.enter{ animation: attackTextIn 0.3s ease forwards; }
.timing-score.leave{ animation: attackTextOut 0.65s ease 1s both; }
/* Fondo SÓLIDO (no rgba con alpha) a propósito: la barra vive a caballo de
   la línea divisoria entre .battle-frame y .arena (dos fondos distintos
   detrás), y con un fondo semitransparente esa línea se veía a través del
   tramo ya gastado de la barra. Un lila muy oscuro opaco tapa lo que hay
   detrás sin desentonar con la paleta. */
.bar-track{ width:100%; height: 15px; background: #1c1130; border-radius: 999px; overflow:hidden; border: 1.5px solid var(--lilac); box-shadow: inset 0 2px 5px rgba(0,0,0,0.55); }
.bar-fill{ height:100%; border-radius: 999px; transition: width 0.5s cubic-bezier(.2,.8,.2,1); box-shadow: 0 0 10px rgba(255,255,255,0.25); }
#youBar{ background: linear-gradient(90deg, var(--blue), #5B8DEF); }
#rivalBar{ background: linear-gradient(90deg, var(--pink), #C22860); }
/* Hermana de .battle-frame y .arena (ver HTML), NO hija de ninguna de las
   dos — ambas llevan clip-path, que recorta también a los hijos que se
   salgan de su propia caja, así que una barra a caballo entre las dos
   siempre perdía la mitad que caía fuera de la que la contuviera (se
   probó como hija de .battle-frame con bottom negativo, y luego con
   bottom positivo — las dos veces se comía media barra). Como hermana de
   las dos, posicionada respecto a .arena-screen (position:relative), no
   hay ningún clip-path que la afecte. .battle-frame mide siempre
   --battle-frame-height de alto (misma variable que usa .battle-frame,
   así los dos no se pueden desincronizar si se reajusta), así que top
   puede calcularse directamente contra esa variable: centrada en la línea
   de separación (300px), no por encima ni por debajo. */
.bar-track{
  position:absolute; top: calc(var(--battle-frame-height) - 4.5px); z-index: 2;
  width: calc(50% - 22px);
}
.you-bar{ left: 14px; }
.rival-bar{ right: 14px; }

/* Energía, debajo de su propio personaje (dos columnas, no un bloque
   compartido en medio de la tarjeta) — así cada jugador tiene toda su
   mitad de la tarjeta para sí solo, sin competir con el otro lado por el
   mismo ancho. El % de aura vive ahora en .battle-frame (encima de la
   barra, debajo del nombre — ver .battle-frame .aura-label): con esta
   fila pegada justo debajo de la barra (margin-top:4px) quedaba
   demasiado cerca de ese %, y se leían como un solo bloque — "94%
   ENERGÍA" en vez de dos datos distintos. Más margen para separarlos. */
.stats-row{ display:flex; gap:14px; margin-top: 24px; position:relative; }
/* min-width:0 (no el "auto" por defecto de flex) — si no, la columna
   nunca se encoge por debajo del ancho de su contenido y se sale del
   recuadro en pantallas muy estrechas, aunque diga flex:1. */
.stats-col{ flex:1; min-width: 0; }
/* Puntuación de aura del golpe (antes iba pegada al nombre en
   .attack-text) — ninguna de las dos columnas de arriba ocupa su propio
   centro (el % de aura y la energía se leen pegados a su lado exterior),
   así que ese hueco central de .stats-row se aprovecha para este dato en
   vez de sumar una línea nueva. Anclado al centro exacto (50%) igual que
   .attack-text — cada lado crece HACIA el centro (right:50% + text-align
   right para el tuyo, left:50% + text-align left para el rival), no cada
   uno centrado por separado en su propio punto — así los dos números
   quedan alineados el uno contra el otro, igual que el nombre/aura de
   abajo. Fundido propio en vez de reusar @keyframes attackTextIn/Out a
   propósito: esas animan `transform`, que aquí ya se usa para centrar
   verticalmente (translateY) — compartirlas pisaría ese centrado
   mientras dura la animación. Solo opacidad: no hay ese conflicto.
   Dos @keyframes independientes (powerTextIn/Out) en vez de una sola
   con "direction:reverse" para el .leave — con reverse, el fill-mode
   "backwards" durante el retraso (1s) NO mantenía opacity:1 como con
   .attack-text (mismo retraso, misma duración): el texto caía a
   opacity:0 casi al instante en vez de esperar el segundo completo,
   así que power-text y attack-text se desincronizaban pese a tener
   exactamente los mismos números. Confirmado midiendo opacity en vivo
   (getComputedStyle) — a los 206ms del disparo, attack-text seguía en
   1 pero power-text ya estaba en 0. Con dos keyframes normales (mismo
   patrón que attackTextIn/Out, sin "reverse") el fill-mode se comporta
   igual que en .attack-text: no hay ambigüedad de dirección. */
.power-text{
  position:absolute; top:50%; z-index:1; width: 80px;
  font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 13px;
  opacity:0; pointer-events:none; white-space:nowrap;
  transform: translateY(-50%);
}
.power-text.you{ right:50%; padding-right: 6px; text-align:right; color: var(--blue); }
.power-text.rival{ left:50%; padding-left: 6px; text-align:left; color: var(--pink); }
.power-text.enter{ animation: powerTextIn 0.3s ease forwards; }
.power-text.leave{ animation: powerTextOut 0.65s ease 1s both; }
@keyframes powerTextIn{ 0%{ opacity:0; } 100%{ opacity:1; } }
@keyframes powerTextOut{ 0%{ opacity:1; } 100%{ opacity:0; } }

/* Etiqueta encima, pilas debajo a todo el ancho de la columna — así la
   palabra "energía" no le quita sitio a las 8 pilas en el mismo renglón
   (competían por el mismo ancho y se cortaban). Ya no se atenúa el lado
   del rival: incluso su energía tiene que leerse tan claro como la tuya. */
.energy-group{ margin-top: 0; }
.energy-group.rival{ text-align:right; }
.energy-label{ display:block; font-size: 12.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.6px; font-weight: 600; margin-bottom: 0; }
.energy-group.rival .energy-dots{ justify-content:flex-end; }
/* El emoji 🔋 traía su propio relleno interno invisible dentro de la
   fuente, así que por mucho que se bajara el gap a 0 siempre quedaba
   hueco entre pilas. Este SVG propio (ENERGY_PIP, icons.js) no tiene ese
   margen: con gap:1px se pegan casi del todo y se leen como un único
   bloque de energía, no como iconos sueltos. */
.energy-dots{ display:flex; gap: 1px; }
.energy-dot{
  display:block; width: 8px; height: 16px; color: var(--lime);
  opacity: 0.3; filter: grayscale(1);
  transition: opacity 0.3s ease, filter 0.3s ease;
}
.energy-dot.filled{ opacity: 1; filter: none; }
.energy-icon{ display:block; }
.energy-dot .energy-icon{ width:100%; height:100%; }
/* Mismo icono de pila reutilizado a tamaño de texto — en el coste de
   movimiento y en el texto de "cómo funciona" — para que se lea como el
   mismo recurso que la barra de energía de arriba. */
.icon-energy{
  width: 0.55em; height: 1.05em; display:inline-block; flex-shrink:0;
  vertical-align: -0.15em; color: var(--lime);
}

/* Golpe perfecto (score redondeado = 100): confeti en el marcador de
   ejecución y un "+25" que sube flotando sobre quien lo consigue — se
   entienden solos, sin explicación (reaccionas al momento). Hubo
   también un contador de 3 estrellas que regalaba energía extra, pero
   sin ningún tutorial ni pista de qué significaba era imposible de
   descubrir jugando, así que se ha quitado (feedback del 3 sept. 2026,
   ver Notas en Notion) — puede que vuelva más adelante con una
   explicación de verdad, pero de momento solo queda lo que se entiende
   a simple vista. */

/* Tres líneas separadas, cada una con su propio papel, para que se
   entienda de un vistazo: 1) qué movimiento ejecuta cada uno (junto a
   su energía, mismo color que su barra de aura), 2) cuánto se ha
   llevado cada uno esa ronda, como un marcador — un badge/pastilla
   bien visible, no texto suelto — y 3) la frase de sabor ("el público
   está a tu favor"...), en un tono más discreto porque es solo un
   detalle. */
/* Fila del ataque: ancho fijo en cada lado (no al contenido) para que
   ninguno se mueva si el otro está todavía vacío a mitad de ronda. Sin
   hueco entre los dos (gap:0, igual que .result-row) para que el borde
   interior de cada bloque de ataque quede justo encima del borde
   interior de su marcador. El texto va alineado hacia dentro (el tuyo
   a la derecha de su caja, el del rival a la izquierda de la suya) —
   las dos cajas de cada jugador (ataque y marcador) comparten el mismo
   lado, así el texto de las dos queda alineado entre sí verticalmente,
   no solo las cajas.
   Antes se recortaba con "…" si no cabía en una sola línea — pero con
   nombres de movimiento largos + el número de aura ahora en cientos
   (displayPower, ver data.js) el texto entero deja de caber bastante
   más a menudo de lo que parece a simple vista, así que se veía
   cortado incluso con sitio de sobra alrededor. Se permite envolver a
   una segunda línea en vez de truncar (el ancho fijo de cada lado
   sigue evitando que los dos textos se toquen entre sí, solo que ahora
   crecen hacia abajo en vez de perder texto) — PERO sin nowrap en el
   texto entero, el punto de corte caía donde el navegador encontrara
   el primer hueco, que muchas veces era justo entre el icono de aura y
   su número ("✦" en una línea, "300" solo en la siguiente). Por eso
   el nombre (<b>) y el bloque "icono + número" llevan su propio
   nowrap cada uno — pueden envolver ENTRE esos dos trozos si hace
   falta, nunca dentro de ellos. */
.attack-row{ display:flex; justify-content:center; gap:0; margin: 0; position:relative; }
.attack-text{ width: 190px; font-size: 14.5px; font-weight: 400; line-height:1.3; min-height: 18px; opacity: 0; }
.attack-text b{ font-weight: 600; white-space: nowrap; }
/* Padding hacia el centro (no margin/gap en la fila) para que el
   propio borde de la caja —con el que se alinea el marcador de
   debajo— no se mueva; solo se aparta el texto de dentro, así los dos
   lados dejan de tocarse sin perder la alineación. */
.attack-text.you{ text-align:right; padding-right: 10px; color: var(--blue); }
.attack-text.rival{ text-align:left; padding-left: 10px; color: var(--pink); }
/* El icono de aura quedaba pegado al % que tiene al lado — un poco de
   aire a los dos lados para que se lea como un dato aparte. nowrap para
   que el icono y su número (p.ej. "✦ 300") viajen siempre juntos si el
   texto tiene que envolver a una segunda línea — ver la nota grande de
   .attack-row más arriba. */
.attack-text .icon-aura{ margin: 0 3px; white-space: nowrap; }
/* Entra con un fundido en cuanto se fija el texto (setAttackText, en
   battle.js/localBattle.js) y se va del todo al final de la ronda
   (hideAttackText) — con el mismo retraso y duración que .round-badge
   tarda en empezar a aparecer (ver más abajo), para que el recuento
   entre justo cuando este texto ha terminado de irse, no antes ni
   mucho después. Así no se queda el ataque de la ronda anterior a la
   vista mientras se elige el siguiente. El fill-mode de .leave tiene
   que ser "both", no solo "forwards": con "forwards" el 0% (opacity:1)
   no se aplica durante el retraso, así que en cuanto se quita .enter el
   texto caía al opacity:0 base y solo "reaparecía" de golpe cuando
   arrancaba de verdad la animación — un parpadeo doble (entra, sale,
   vuelve a entrar, vuelve a salir). Con "both" se queda en opacity:1
   todo el retraso, sin saltos. */
.attack-text.enter{ animation: attackTextIn 0.3s ease forwards; }
.attack-text.leave{ animation: attackTextOut 0.65s ease 1s both; }
@keyframes attackTextIn{
  0%{ opacity:0; transform: translateY(-6px); }
  100%{ opacity:1; transform: translateY(0); }
}
@keyframes attackTextOut{
  0%{ opacity:1; transform: translateY(0); }
  100%{ opacity:0; transform: translateY(8px); }
}

/* El marcador ya no tiene su propia línea (.result-row) — comparte sitio
   con .attack-text, superpuesto en la misma posición (position:absolute,
   mismo ancla al 50% central que .attack-text logra vía flex) para que
   ronda tras ronda solo se gaste una línea: primero se lee el nombre del
   ataque, y cuando ese texto ya se ha desvanecido del todo entra el
   recuento en su sitio — nunca los dos a la vez. El retraso de la
   animación (ver .show más abajo) es justo la duración completa del
   ciclo de .attack-text (1.65s: 0.3s entrada + 1s quieto + 0.65s
   salida — acortado de 2.6s/1.95s: con el retraso largo el recuento
   tardaba demasiado en aparecer), así que no se dispara hasta que el
   nombre ha desaparecido de verdad, pero tampoco deja pasar más tiempo
   del necesario. Duración también acortada a la par (2.6s -> 1.65s),
   mismo reparto proporcional entre entrada/quieto/salida. El
   desplazamiento vertical de esta animación (antes translateY(-10px)/
   10px sin más) se combina con translateY(-50%) vía calc() — la propia
   animación pisaría ese -50% de centrado si no, igual que se documentó
   para .power-text. */
.round-badge{
  position:absolute; top:50%; z-index:1;
  display:flex; align-items:center;
  width: 128px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  font-family:'Tomorrow', sans-serif; font-weight:600; font-size: 17px;
  opacity: 0; transform: translateY(-50%);
}
/* justify-content en vez de centrar el texto — igual que el ataque de la
   misma línea, tuyo pegado a la derecha de su caja, del rival a la
   izquierda de la suya, para que el número quede alineado con el ataque
   que ocupaba ese mismo sitio un instante antes. */
.round-badge.you{ right:50%; justify-content: flex-end; padding-right: 10px; color: var(--blue); }
.round-badge.rival{ left:50%; justify-content: flex-start; padding-left: 10px; color: var(--pink); }
.round-badge.show{ animation: scoreFade 1.65s ease 1.65s forwards; }
@keyframes scoreFade{
  0%{ opacity:0; transform: translateY(calc(-50% - 10px)); }
  12%{ opacity:1; transform: translateY(-50%); }
  75%{ opacity:1; transform: translateY(-50%); }
  100%{ opacity:0; transform: translateY(calc(-50% + 10px)); }
}

/* La frase de sabor comparte sitio con los avisos generales (elige
   movimiento, se acaba el tiempo...) — de ahí el lila fino por
   defecto, pero <b> (fin de duelo) sigue destacando en dorado. */
.log{ text-align:center; min-height: 22px; display:flex; align-items:center; justify-content:center; font-size: 14.5px; font-weight: 300; padding: 2px 10px; color: var(--lilac); }
/* :not(.draft-player-name) para no pisar el color propio con el que ya
   se distingue de quién es el turno en el draft/"Turno de X" local. */
.log b:not(.draft-player-name){ color: var(--gold); font-weight: 700; font-size: 15px; }
/* El aviso de "elige tu movimiento" es la instrucción más importante
   para quien empieza a jugar — más grande, menos apagada y parpadeando
   para que llame la atención, a diferencia de las frases de sabor de
   después (esas no llevan .log-prompt, así que no parpadean). */
.log.log-prompt{ font-size: 17px; font-weight: 500; color: var(--cream); animation: logPromptBlink 1.3s ease-in-out infinite; }
@keyframes logPromptBlink{
  0%, 100%{ opacity: 1; }
  50%{ opacity: 0.4; }
}

.turn-timer-row{ display:flex; justify-content:flex-end; margin-top: 3px; }
.turn-timer{
  font-family:'Tomorrow', sans-serif; font-weight:600; font-size: 13px;
  color: var(--gold); background: rgba(255,210,63,0.1); border: 1.5px solid rgba(255,210,63,0.35);
  border-radius: 999px; padding: 4px 12px;
  transition: color 0.2s ease, background 0.2s ease, border-color 0.2s ease;
}
.turn-timer.urgent{
  color: var(--pink); background: rgba(255,61,129,0.14); border-color: rgba(255,61,129,0.5);
  animation: turnTimerPulse 0.6s ease-in-out infinite;
}
@keyframes turnTimerPulse{ 0%, 100%{ transform: scale(1); } 50%{ transform: scale(1.08); } }
.moves{ display:grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 2px; }
.move-btn{
  background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
  border: 2px solid rgba(255,255,255,0.14);
  clip-path: polygon(10px 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 10px);
  padding: 10px 11px; color: var(--cream);
  font-family: 'Tomorrow', sans-serif; text-align:left; cursor:pointer;
  transition: transform 0.15s ease, border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
  position:relative;
}
.move-btn:hover:not(:disabled){ border-color: var(--gold); transform: translateY(-2px); background: rgba(255,210,63,0.1); box-shadow: 0 0 16px rgba(255,210,63,0.25); }
.move-btn:disabled{ opacity: 0.3; cursor: default; }
.pass-turn-btn{
  grid-column: 1 / -1;
  background: rgba(255,210,63,0.08); border: 2px dashed rgba(255,210,63,0.4);
  border-radius: 12px; padding: 14px; margin-top: 2px;
  color: var(--gold); font-family:'Tomorrow', sans-serif; font-weight:600; font-size: 14px;
  text-align:center; cursor:pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.pass-turn-btn:hover{ background: rgba(255,210,63,0.16); border-color: var(--gold); }
.move-top{ display:flex; justify-content:space-between; align-items:center; }
.move-emoji{ font-size: 22px; }
.move-badges{ display:flex; gap: 5px; }
.move-power{ font-size: 12.5px; color: var(--lilac); font-weight:700; background: rgba(185,142,255,0.14); border: 1px solid rgba(185,142,255,0.35); padding: 2px 8px; border-radius: 4px; white-space:nowrap; display:inline-flex; align-items:center; gap:3px; }
.move-energy{ font-size: 12.5px; color: var(--lime); font-weight:700; background: rgba(180,255,57,0.14); border: 1px solid rgba(180,255,57,0.35); padding: 2px 8px; border-radius: 4px; white-space:nowrap; display:inline-flex; align-items:center; gap:3px; }
.move-name{ font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 16px; margin-top: 5px; }
.move-cat{ font-size: 11.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 2px; font-weight: 300; }
.cat-pose .move-cat{ color: var(--gold); }
.cat-dance .move-cat{ color: var(--lime); }
.cat-meme .move-cat{ color: var(--pink); }
.cat-wild .move-cat{ color: var(--blue); }

/* Animaciones "sprite" en los emojis de movimiento de la Colección: cada
   una imita a su manera lo que representa el emoji (la mano saluda, la
   bailarina se contonea, el remolino gira...) en vez de un rebote genérico
   igual para todas. Las tarjetas bloqueadas usan un tintineo neutro del
   candado en su lugar. */
#collectionGrid .move-emoji{ display:inline-block; }

@keyframes emojiLockJiggle{ 0%, 85%, 100%{ transform: rotate(0deg); } 90%{ transform: rotate(-8deg); } 95%{ transform: rotate(8deg); } }
#collectionGrid .draft-card.locked .move-emoji{ animation: emojiLockJiggle 3.4s ease-in-out infinite; }

@keyframes emojiStare{ 0%, 100%{ transform: rotate(0deg); } 50%{ transform: rotate(-6deg); } }
.move-sigma_stare:not(.locked) .move-emoji{ animation: emojiStare 2.8s ease-in-out infinite; }

@keyframes emojiPoint{ 0%, 100%{ transform: translateX(0) rotate(0deg); } 50%{ transform: translateX(4px) rotate(-10deg); } }
.move-rizz_point:not(.locked) .move-emoji{ animation: emojiPoint 1.6s ease-in-out infinite; transform-origin: 30% 70%; }

@keyframes emojiFly{ 0%, 100%{ transform: translateY(0) rotate(0deg); } 50%{ transform: translateY(-5px) rotate(7deg); } }
.move-siuuu_leap:not(.locked) .move-emoji{ animation: emojiFly 1.7s ease-in-out infinite; }

@keyframes emojiRegalBob{ 0%, 100%{ transform: translateY(0) rotate(0deg); } 50%{ transform: translateY(-3px) rotate(-4deg); } }
.move-emperors_pose:not(.locked) .move-emoji{ animation: emojiRegalBob 3.2s ease-in-out infinite; }

@keyframes emojiWiggle{ 0%, 100%{ transform: translateX(0) rotate(0deg); } 25%{ transform: translateX(-3px) rotate(-9deg); } 75%{ transform: translateX(3px) rotate(9deg); } }
/* ohio_wiggle, aura_shuffle y six_seven ahora usan el mini-sprite propio
   (ver sprites.js) en vez de esta animación de transformar el emoji entero. */

@keyframes emojiStep{ 0%, 100%{ transform: translateX(0) translateY(0); } 25%{ transform: translateX(-4px) translateY(-2px); } 75%{ transform: translateX(4px) translateY(-2px); } }
.move-griddy_step:not(.locked) .move-emoji{ animation: emojiStep 1.4s ease-in-out infinite; }

@keyframes emojiSpin{ 0%{ transform: rotate(0deg); } 100%{ transform: rotate(360deg); } }

@keyframes emojiFlicker{ 0%, 100%{ transform: scale(1) rotate(0deg); } 50%{ transform: scale(1.12) rotate(-5deg); } }
.move-fanum_flow:not(.locked) .move-emoji{ animation: emojiFlicker 1.1s ease-in-out infinite; }

@keyframes emojiAlert{ 0%, 100%{ transform: rotate(0deg); opacity:1; } 50%{ transform: rotate(10deg); opacity:0.7; } }
.move-gyatt_alert:not(.locked) .move-emoji{ animation: emojiAlert 0.9s ease-in-out infinite; }

@keyframes emojiGlitch{ 0%, 90%, 100%{ transform: translate(0,0); } 92%{ transform: translate(-2px,1px); } 94%{ transform: translate(2px,-1px); } 96%{ transform: translate(0,0); } }
.move-npc_freeze:not(.locked) .move-emoji{ animation: emojiGlitch 4s linear infinite; }

@keyframes emojiWave{ 0%, 100%{ transform: rotate(0deg); } 25%{ transform: rotate(-16deg); } 75%{ transform: rotate(16deg); } }

@keyframes emojiToiletBob{ 0%, 100%{ transform: translateY(0) rotate(0deg); } 50%{ transform: translateY(-4px) rotate(5deg); } }
.move-skibidi_combo:not(.locked) .move-emoji{ animation: emojiToiletBob 1.4s ease-in-out infinite; }

@keyframes emojiFlash{ 0%, 45%, 100%{ transform: scale(1); opacity:1; } 50%{ transform: scale(1.2); opacity:0.65; } 55%{ transform: scale(1); opacity:1; } }
.move-chopped_flash:not(.locked) .move-emoji{ animation: emojiFlash 1.8s ease-in-out infinite; }

@keyframes emojiSparkle{ 0%, 100%{ transform: scale(1) rotate(0deg); } 50%{ transform: scale(1.15) rotate(10deg); } }
.move-aura_surge:not(.locked) .move-emoji{ animation: emojiSparkle 1.7s ease-in-out infinite; }

/* Mini-sprites SVG (ver sprites.js): dos fotogramas dibujados a mano que se
   alternan con un corte seco (steps, sin easing) en vez de una transformación
   continua — imita a un GIF de pocos fotogramas real. */
.move-emoji.sprite-icon{ display:inline-flex; align-items:center; justify-content:center; }
.sprite-svg{ width: 1em; height: 1em; display:block; overflow: visible; }
@keyframes spriteFrameA{ 0%, 49.9%{ opacity:1; } 50%, 100%{ opacity:0; } }
@keyframes spriteFrameB{ 0%, 49.9%{ opacity:0; } 50%, 100%{ opacity:1; } }
.sprite-frame-a{ animation: spriteFrameA 0.9s steps(1, end) infinite; }
.sprite-frame-b{ animation: spriteFrameB 0.9s steps(1, end) infinite; }

.footer-row{ display:flex; justify-content:center; gap: 10px; margin-top: 14px; }
.restart-btn, .home-btn{
  display:none; background: linear-gradient(90deg, var(--gold), var(--pink)); border: 2px solid rgba(255,255,255,0.25);
  clip-path: polygon(12px 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%, 0 12px);
  padding: 12px 28px; font-family:'Tomorrow', sans-serif; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px;
  font-size: 25px; line-height: 1; color: #1A1220; cursor:pointer;
  box-shadow: 0 0 20px rgba(255,210,63,0.3);
}
.home-btn{ background: rgba(255,255,255,0.08); color: var(--cream); border: 2px solid rgba(255,255,255,0.22); box-shadow:none; }
.rules{ max-width: 520px; width:100%; margin-top: auto; padding-top: 20px; font-size: 12.5px; color: var(--muted); line-height: 1.6; text-align:center; font-weight: 300; }
.rules b{ color: var(--cream); }
.site-footer{ max-width: 520px; width:100%; padding-top: 18px; text-align:center; }
.footer-link{ color: var(--muted); font-size: 13px; text-decoration: underline; text-underline-offset: 3px; transition: color 0.15s ease; }
.footer-link:hover{ color: var(--gold); }
.footer-sep{ color: var(--muted); font-size: 13px; margin: 0 8px; }

/* Draft / colección / pre-battle selection */
.draft-screen, .collection-screen, .home-screen, .mode-select-screen, .guest-setup-screen, .online-screen, .ranking-screen{ width:100%; max-width: 520px; }
.draft-header{ text-align:left; margin-bottom: 28px; }
.draft-header h2{
  font-family:'Tomorrow', sans-serif; font-weight:800; font-size: 25px; line-height: 1;
  text-transform: uppercase; letter-spacing: 0.5px;
}
/* Nombre del jugador cuyo turno es (draft de 2 jugadores y "Turno de..."
   en combate) — un color propio para distinguir de un vistazo a quién le
   toca, sin tener que leer el texto entero cada vez. */
.draft-player-name{ color: var(--pink); }
.draft-header p{ font-size: 14.5px; color: var(--muted); margin-top: 4px; font-weight: 400; }
.draft-counter{ font-family:'Tomorrow', sans-serif; color: var(--gold); font-weight:700; }
.draft-grid{ display:grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 18px; }
.draft-card{
  position: relative;
  background: linear-gradient(180deg, rgba(185,142,255,0.14), rgba(46,31,82,0.32));
  border: 2px solid rgba(255,255,255,0.14);
  clip-path: polygon(12px 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%, 0 12px);
  padding: 15px 13px; cursor:pointer; text-align:left;
  /* El brillo del hover (sombra/borde) va más lento que el
     levantamiento (transform) a propósito — así al pasar el ratón por
     varias tarjetas seguidas se ve un rastro de luz que tarda un
     momento en apagarse en cada una, en vez de encenderse/apagarse de
     golpe. */
  transition: border-color 0.3s ease, transform 0.15s ease, box-shadow 0.35s ease;
}
/* El degradado lila del hover y el de "seleccionado" NO se pueden
   animar cambiando la propiedad background directamente — un
   degradado no interpola con otro degradado (ni con un color plano),
   así que por mucho transition:background que se le ponga, el
   navegador lo cambia de golpe, sin fundido. Por eso cada uno vive en
   su propia capa (pseudo-elemento) siempre con el MISMO degradado fijo
   de principio a fin, y lo único que se anima es su opacidad — eso sí
   interpola de sobra. Dos capas independientes (no una compartida) para
   que un movimiento que esté a la vez en hover Y seleccionado no tenga
   que saltar de un degradado a otro tampoco. z-index negativo para que
   queden detrás del contenido (emoji/nombre) pero delante del fondo
   base de la tarjeta. */
.draft-card::before, .draft-card::after{
  content:''; position:absolute; inset:0; pointer-events:none;
  opacity:0; transition: opacity 0.35s ease;
}
.draft-card::before{
  background: linear-gradient(180deg, rgba(185,142,255,0.18), rgba(185,142,255,0.05));
  z-index: -2;
}
.draft-card::after{
  /* Estilo "cristal": solo el tono de ARRIBA sube un poco respecto al
     hover (0.18 → 0.26) — el de ABAJO se queda casi igual de tenue que
     en el hover (0.05 → 0.07, no 0.1 como antes), en vez de que el
     degradado entero se vea más claro/plano. Así el brillo se nota
     arriba y se transparenta enseguida hacia abajo, no un tinte lila
     uniforme de punta a punta. */
  background: linear-gradient(180deg, rgba(185,142,255,0.26), rgba(185,142,255,0.07));
  z-index: -1;
}
.draft-card:hover::before{ opacity: 1; }
.draft-card.selected::after{ opacity: 1; }
.draft-card:hover{
  transform: translateY(-2px);
  box-shadow: 0 0 20px rgba(185,142,255,0.3);
  border-color: rgba(185,142,255,0.5);
}
.draft-card .move-top{ display:flex; justify-content:space-between; align-items:center; }
.draft-card .move-emoji{ font-size: 25px; }
.draft-card .move-name{ font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 16px; margin-top: 5px; }
.draft-card .move-cat{ font-size: 11.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 2px; font-weight: 300; }
.draft-start-btn{
  display:block; width:100%; background: linear-gradient(90deg, var(--gold), var(--pink)); border: 2px solid rgba(255,255,255,0.25);
  clip-path: polygon(16px 0, 100% 0, 100% calc(100% - 16px), calc(100% - 16px) 100%, 0 100%, 0 16px);
  padding: 14px 28px; font-family:'Tomorrow', sans-serif; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px;
  font-size: 25px; line-height: 1; color: #1A1220; cursor:pointer;
  box-shadow: 0 0 24px rgba(255,210,63,0.35);
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.draft-start-btn:hover:not(:disabled){ transform: translateY(-2px); box-shadow: 0 0 32px rgba(255,210,63,0.5); }
.draft-start-btn:disabled{ opacity: 0.35; cursor: default; box-shadow:none; }
/* En pantallas de móvil/tablet (por debajo del punto en el que entra
   el layout de escritorio) la rejilla de 8 movimientos es más alta que
   la pantalla — "Empezar duelo" se desbloquea al llegar a 4/4 pero
   queda fuera de la vista, así que hay que volver a bajar para
   encontrarlo. Clavado al fondo del viewport (no solo del contenedor)
   siempre queda a mano sin necesidad de scroll. El degradado detrás
   evita que las tarjetas de debajo se corten en seco contra la barra. */
@media (max-width: 859px){
  #draftScreen{ padding-bottom: 108px; }
  .draft-cta-bar{
    position: fixed; left:0; right:0; bottom:0; z-index: 40;
    display:flex; justify-content:center;
    padding: 22px 14px calc(16px + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(180deg, rgba(15,0,24,0) 0%, var(--bg) 45%);
    pointer-events:none;
  }
  .draft-cta-bar .draft-start-btn{ max-width: 460px; pointer-events:auto; }
}
.hidden{ display:none !important; }

/* Transición entre pantallas: al avanzar (p.ej. "Farmear aura"), la
   pantalla actual sale un poco hacia la izquierda mientras se apaga, y
   la siguiente entra desde la derecha; al volver es al revés. Solo estas
   dos clases hacen falta porque el estado "recién salido hacia la
   izquierda" y el estado "a punto de entrar desde la izquierda" son el
   mismo aspecto (transparente, desplazado) — showScreen() en main.js
   las añade/quita en el momento justo. */
.customize-screen, .home-screen, .mode-select-screen, .guest-setup-screen,
.collection-screen, .draft-screen, .arena-screen, .online-screen{
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.slide-left{ opacity:0; transform: translateX(-24px); }
.slide-right{ opacity:0; transform: translateX(24px); }

/* Rareza */
.rarity-tag{ font-weight:700; }
.draft-card.rarity-common{ border-color: rgba(255,255,255,0.12); }
.draft-card.rarity-rare{ border-color: rgba(143,184,255,0.5); }
.draft-card.rarity-rare .rarity-tag{ color: var(--blue); }
.draft-card.rarity-legendary{ border-color: rgba(255,210,63,0.6); box-shadow: 0 0 14px rgba(255,210,63,0.15); }
.draft-card.rarity-legendary .rarity-tag{ color: var(--gold); }
/* .selected tiene que ir DESPUÉS de las reglas de rareza de arriba a
   propósito: con la misma especificidad (dos clases cada una), gana la
   que esté más abajo en el CSS — si esta regla estuviera antes (como
   estaba), un movimiento raro o legendario seleccionado mostraba el
   borde azul/dorado de su rareza en vez del contorno de selección,
   porque esa regla "ganaba" el empate por ir después. Lila en vez de
   dorado para no confundirse nunca con el dorado de "legendario". El
   degradado (no un color plano) lo pone el ::after de más arriba —
   aquí solo borde y sombra, que sí son colores sólidos y no tienen
   ningún problema en animarse con transition. */
.draft-card.selected{ border-color: var(--lilac); box-shadow: 0 0 20px rgba(185,142,255,0.45); }
.draft-card.locked{ opacity: 0.45; filter: grayscale(0.6); }


/* Barra superior persistente: el botón "Volver" a la izquierda y el
   panel de perfil a la derecha, siempre en la misma fila y posición en
   cualquier pantalla — se oculta (visibility, no display, para no mover
   el perfil) el botón cuando la pantalla actual no tiene a dónde volver. */
.top-bar{
  display:flex; align-items:center; justify-content:space-between; gap: 12px;
  width:100%; max-width: 520px; margin: 0 0 16px;
}
.top-bar .back-btn{ margin-bottom: 0; flex-shrink: 0; }
.top-bar .back-btn.hidden-slot{ visibility: hidden; pointer-events: none; }
.top-bar-left{ display:flex; align-items:center; gap: 10px; min-width:0; }
/* Nombre de la sección actual junto al botón "Volver" — a propósito
   discreto (tamaño pequeño, color apagado) para no competir con el
   propio título grande de cada pantalla; solo sirve de referencia de
   "dónde estoy", como un mapa del sitio en miniatura. */
.top-bar-title{
  font-family:'Tomorrow', sans-serif; font-weight:600; font-size: 13px;
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* Panel de perfil: pequeño, sin marco de tarjeta — como un típico
   account chip — reemplaza al antiguo título "Tu arena". Ya no necesita
   ancho propio: lo hereda de .top-bar. */
.profile-bar{
  display:flex; align-items:center; justify-content:flex-end; gap: 6px;
}
.profile-avatar{
  width: 28px; height: 34px; flex-shrink: 0; overflow: hidden;
  border-radius: 6px;
}
.profile-avatar svg{ width: 100%; height: 100%; overflow: visible; }
/* La insignia lleva también la clase genérica .avatar-wrap (para heredar el
   posicionamiento del canvas del visor 3D) — pero esa clase trae su propio
   width/height pensado para el visor grande, y al estar declarada más abajo
   en la hoja le ganaría a las medidas pequeñas de arriba por orden de
   cascada (misma especificidad). El id fuerza el tamaño de insignia real. */
#profileAvatarWrap{ width: 28px; height: 34px; }
/* Todo el bloque avatar+nombre es un único botón que abre el pop-up de
   perfil — el nombre subrayado (en vez de un lápiz al lado) ya es la
   pista visual de que se puede tocar, sin sugerir que se edita ahí
   mismo, sobre la marcha (la edición real vive en el pop-up). El
   rectángulo del hover mide lo mismo (alto y radio) que las tarjetas de
   Aura/Drip de al lado —padding vertical 4.5px sobre el avatar de 34px
   da los mismos 43px, padding horizontal 13px igual que .profile-stat—
   para que se lea como parte del mismo grupo de pastillas, pegado a
   ellas, no como un botón aparte y más pequeño. */
.profile-identity-btn{
  display:flex; align-items:center; gap: 8px;
  background:none; border:none; padding: 4.5px 13px; margin:0; font:inherit; color:inherit; cursor:pointer;
  border-radius: 14px; transition: background 0.15s ease;
}
.profile-identity-btn:hover{ background: rgba(255,255,255,0.06); }
.profile-name-row{ display:flex; align-items:center; gap: 4px; }
.profile-name{
  font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 14px; color: var(--cream);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width: 120px;
  text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(245,240,232,0.4);
}
.profile-identity-btn:hover .profile-name{ text-decoration-color: var(--cream); }
/* Dos estadísticas independientes en la barra de perfil: Aura (lila,
   prestigio — sube y baja con cada duelo, nunca se gasta) y Drip
   (dorado, la moneda — el color dorado la lee como "esto es dinero"
   sin necesidad de escribir la palabra "moneda"). */
.profile-stats{ display:flex; align-items:center; gap: 6px; }
.profile-stat{
  display:flex; flex-direction:column; align-items:center; line-height:1.15;
  border-radius: 14px; padding: 6px 13px;
}
.profile-stat-label{ font-size: 10px; opacity: 0.85; text-transform:uppercase; letter-spacing: 0.6px; font-weight: 300; }
.profile-stat-value{ font-family:'Tomorrow', sans-serif; font-weight:800; font-size: 17px; }
.profile-stat.aura{
  background: rgba(185,142,255,0.14); border: 1.5px solid rgba(185,142,255,0.45);
  box-shadow: 0 0 16px rgba(185,142,255,0.3);
}
.profile-stat.aura .profile-stat-label, .profile-stat.aura .profile-stat-value{ color: var(--lilac); }
.profile-stat.drip{
  background: rgba(255,210,63,0.14); border: 1.5px solid rgba(255,210,63,0.45);
  box-shadow: 0 0 16px rgba(255,210,63,0.3);
}
.profile-stat.drip .profile-stat-label, .profile-stat.drip .profile-stat-value{ color: var(--gold); }
/* Icono de Aura/Drip embebido en texto suelto (reglas, recompensas,
   tienda) — fuera de .profile-stat necesita su color a mano. */
.icon-aura{ color: var(--lilac); }
.icon-drip{ color: var(--gold); }
.stat-icon{ width: 0.85em; height: 0.85em; vertical-align: -0.12em; display:inline-block; flex-shrink:0; }
/* Menú de inicio inspirado en el selector de modos de TETR.IO: filas a
   todo el ancho casi pegadas, cada una con su propio color de acento y
   un bloque de icono grande cortado en diagonal, en vez de tarjetas
   idénticas con solo un emoji pequeño. */
.home-actions{ display:flex; flex-direction:column; gap: 5px; }
.home-action-btn{
  display:flex; align-items:stretch; gap: 0; padding: 0;
  background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
  border: 2px solid rgba(255,255,255,0.14);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
  clip-path: polygon(16px 0, 100% 0, 100% calc(100% - 16px), calc(100% - 16px) 100%, 0 100%, 0 16px);
  color: var(--cream); cursor:pointer; text-align:left;
  transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.home-action-btn:hover{ transform: translateY(-2px); }
.home-action-btn.locked{ opacity: 0.45; cursor: default; filter: grayscale(0.5); }
.home-action-btn.locked:hover{ transform: none; }
/* Marca sutilmente la opción más rápida para jugar (Farmear aura → Jugar
   online → Jugar ahora), para que quien entra por primera vez sepa por
   dónde empezar. El borde usa el mismo tono que ya tiene cada botón (su
   icono y su :hover más abajo), no un dorado genérico que desentonaba.
   El :hover normal de cada botón (más abajo) pone el borde a 0.4 de
   opacidad — menos que el reposo "featured" — así que sin un :hover
   propio aquí el borde se apagaba justo al pasar el ratón, al revés de
   lo esperado. Estas reglas .featured:hover ganan por especificidad
   (id + clase + pseudo-clase) y suben la intensidad en vez de bajarla. */
#homePlayBtn.featured{
  border-color: rgba(255,61,129,0.55);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 0 18px rgba(255,61,129,0.18);
}
#homePlayBtn.featured:hover{
  border-color: rgba(255,61,129,0.95);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 0 26px rgba(255,61,129,0.35);
}
#modeOnlineBtn.featured{
  border-color: rgb(156,139,181);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 0 22px rgba(156,139,181,0.45);
}
#modeOnlineBtn.featured:hover{
  border-color: rgb(192,178,214);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 0 30px rgba(156,139,181,0.7);
}
#onlineQuickMatchBtn.featured{
  border-color: rgba(180,255,57,0.55);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 0 18px rgba(180,255,57,0.18);
}
#onlineQuickMatchBtn.featured:hover{
  border-color: rgba(180,255,57,0.95);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 0 26px rgba(180,255,57,0.35);
}
.home-action-emoji{
  display:flex; align-items:center; justify-content:center; flex-shrink:0;
  width: 78px; font-size: 30px; margin-right: -16px;
  clip-path: polygon(0 0, 100% 0, calc(100% - 16px) 100%, 0 100%);
  transition: background 0.15s ease;
}
.home-action-btn > span:last-child{ padding: 24px 18px 24px 30px; }
/* Un pelín menos blanco en reposo que al pasar el ratón — así el hover
   también se nota en el propio título, no solo en el borde/fondo. */
.home-action-title{
  font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 25px; line-height: 1; text-transform: uppercase; letter-spacing: 0.4px;
  color: rgba(245,240,232,0.78); transition: color 0.15s ease;
}
.home-action-btn:hover .home-action-title{ color: var(--cream); }
.home-action-sub{ font-size: 13.5px; color: var(--muted); margin-top: 2px; font-weight: 400; }

/* Ranking — lista simple de filas, sin la pastilla partida en dos colores
   de .home-action-btn (aquí lo que importa es escanear rápido nombre +
   aura, no invitar a tocar cada fila). */
.ranking-list{ display:flex; flex-direction:column; gap: 6px; }
.ranking-row{
  display:flex; align-items:center; gap: 12px; padding: 10px 14px;
  background: linear-gradient(180deg, rgba(185,142,255,0.14), rgba(46,31,82,0.32));
  border: 1.5px solid rgba(255,255,255,0.1); border-radius: 10px;
}
.ranking-row.is-me{ border-color: rgba(185,142,255,0.5); background: linear-gradient(180deg, rgba(185,142,255,0.14), rgba(185,142,255,0.04)); }
.ranking-rank{ width: 26px; flex-shrink:0; text-align:center; font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 15px; color: var(--muted); }
.ranking-row:nth-child(1) .ranking-rank{ color: var(--gold); }
.ranking-row:nth-child(2) .ranking-rank{ color: #d8d8e0; }
.ranking-row:nth-child(3) .ranking-rank{ color: #c98756; }
.ranking-avatar{ width: 30px; height: 38px; flex-shrink:0; overflow:hidden; border-radius: 6px; }
.ranking-avatar svg{ width:100%; height:100%; overflow:visible; }
/* Miniatura estática del personaje 3D (avatar3d.js renderThumbnail) — no es
   un visor en vivo, es una imagen (toDataURL de un único renderer offscreen
   reusado fila a fila) para no montar hasta 50 contextos WebGL a la vez. */
.ranking-avatar-thumb{ width:100%; height:100%; object-fit:contain; display:block; background: transparent; }
.ranking-name{ flex:1; font-weight:600; font-size: 14.5px; color: var(--cream); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ranking-aura{ display:flex; align-items:center; gap: 4px; font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 15px; color: var(--lilac); flex-shrink:0; }
.ranking-empty{ text-align:center; color: var(--muted); font-size: 14px; padding: 30px 0; }
.ranking-me-gap{ text-align:center; color: var(--muted); font-size: 18px; letter-spacing: 3px; margin: 2px 0; }

/* Configuración del invitado (multijugador local) */
.guest-setup-row{ margin: 18px 0 22px; }
.guest-name-input{
  width:100%; font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 18px; color: var(--cream);
  background: rgba(255,255,255,0.06); border: 1.5px solid rgba(255,255,255,0.22);
  border-radius: 10px; padding: 12px 16px;
}
.guest-name-input:focus{ outline:none; border-color: var(--lime); box-shadow: 0 0 12px rgba(180,255,57,0.25); }
.guest-name-input::placeholder{ color: var(--muted); }

/* Multijugador online: pantalla de sala (crear/unirse/esperar). Los tres
   pasos son divs hermanos dentro de #onlineScreen que main.js muestra/
   oculta con .hidden — solo uno visible cada vez, como el resto de flujos
   de varios pasos del juego (p.ej. el pop-up de bienvenida). */
.online-code-input{ text-align:center; letter-spacing: 6px; text-transform: uppercase; font-size: 22px; }
.online-error{ color: var(--pink); font-size: 13.5px; margin: -10px 0 16px; }
.online-wait-box{ display:flex; flex-direction:column; align-items:center; text-align:center; padding: 36px 20px; }
.online-wait-spinner{
  width: 40px; height: 40px; border-radius: 50%;
  border: 3px solid rgba(255,255,255,0.18); border-top-color: var(--gold);
  animation: onlineSpin 0.9s linear infinite; margin-bottom: 18px;
}
@keyframes onlineSpin{ to{ transform: rotate(360deg); } }
.online-wait-status{ font-size: 14.5px; color: var(--cream); max-width: 320px; }
.online-room-code{ margin-top: 22px; display:flex; flex-direction:column; align-items:center; gap: 6px; }
.online-room-code-label{ font-size: 12px; color: var(--muted); text-transform:uppercase; letter-spacing: 0.6px; }
.online-room-code-value{
  font-family:'Tomorrow', sans-serif; font-weight:800; font-size: 34px; letter-spacing: 8px;
  color: var(--gold); background: rgba(255,210,63,0.1); border: 1.5px solid rgba(255,210,63,0.35);
  border-radius: 10px; padding: 10px 22px;
}
/* El overlay de "esperando al rival" en la arena reutiliza .reveal-overlay
   (mismo fondo oscuro, misma tarjeta) — aquí solo el spinner necesita su
   propio margen porque en el resto de usos de .reveal-card el primer hijo
   es un emoji grande, no un círculo girando. */
#onlineWaitOverlay .online-wait-spinner{ margin: 0 auto 18px; }

#homePlayBtn .home-action-emoji{ background: linear-gradient(135deg, rgba(255,61,129,0.5), rgba(194,40,96,0.5)); }
#homeCollectionBtn .home-action-emoji{ background: linear-gradient(135deg, rgba(255,210,63,0.5), rgba(255,176,32,0.5)); }
#homeCustomizeBtn .home-action-emoji{ background: linear-gradient(135deg, rgba(143,184,255,0.5), rgba(92,143,224,0.5)); }
#homeRankingBtn .home-action-emoji{ background: linear-gradient(135deg, rgba(185,142,255,0.5), rgba(130,90,214,0.5)); }
#homePlayBtn:hover{
  border-color: rgba(255,61,129,0.4);
  background: linear-gradient(180deg, rgba(255,61,129,0.14), rgba(255,61,129,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -14px 18px rgba(255,61,129,0.12), 0 4px 14px rgba(255,61,129,0.16);
}
#homeCollectionBtn:hover{
  border-color: rgba(255,210,63,0.4);
  background: linear-gradient(180deg, rgba(255,210,63,0.14), rgba(255,210,63,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -14px 18px rgba(255,210,63,0.12), 0 4px 14px rgba(255,210,63,0.16);
}
#homeCustomizeBtn:hover{
  border-color: rgba(143,184,255,0.4);
  background: linear-gradient(180deg, rgba(143,184,255,0.14), rgba(143,184,255,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -14px 18px rgba(143,184,255,0.12), 0 4px 14px rgba(143,184,255,0.16);
}
#homeRankingBtn:hover{
  border-color: rgba(185,142,255,0.4);
  background: linear-gradient(180deg, rgba(185,142,255,0.14), rgba(185,142,255,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -14px 18px rgba(185,142,255,0.12), 0 4px 14px rgba(185,142,255,0.16);
}
#homePlayBtn:hover .home-action-emoji{ background: linear-gradient(135deg, rgba(255,61,129,0.85), rgba(194,40,96,0.85)); }
#homeCollectionBtn:hover .home-action-emoji{ background: linear-gradient(135deg, rgba(255,210,63,0.85), rgba(255,176,32,0.85)); }
#homeCustomizeBtn:hover .home-action-emoji{ background: linear-gradient(135deg, rgba(143,184,255,0.85), rgba(92,143,224,0.85)); }
#homeRankingBtn:hover .home-action-emoji{ background: linear-gradient(135deg, rgba(185,142,255,0.85), rgba(130,90,214,0.85)); }

/* Selector de modo de juego (IA / local / online) */
#modeAiBtn .home-action-emoji{ background: linear-gradient(135deg, rgba(255,61,129,0.5), rgba(194,40,96,0.5)); }
#modeLocalBtn .home-action-emoji{ background: linear-gradient(135deg, rgba(180,255,57,0.5), rgba(124,216,56,0.5)); }
#modeOnlineBtn .home-action-emoji{ background: linear-gradient(135deg, rgba(156,139,181,0.5), rgba(100,86,120,0.5)); }
#modeAiBtn:hover{
  border-color: rgba(255,61,129,0.4);
  background: linear-gradient(180deg, rgba(255,61,129,0.14), rgba(255,61,129,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -14px 18px rgba(255,61,129,0.12), 0 4px 14px rgba(255,61,129,0.16);
}
#modeLocalBtn:hover{
  border-color: rgba(180,255,57,0.4);
  background: linear-gradient(180deg, rgba(180,255,57,0.14), rgba(180,255,57,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -14px 18px rgba(180,255,57,0.12), 0 4px 14px rgba(180,255,57,0.16);
}
#modeAiBtn:hover .home-action-emoji{ background: linear-gradient(135deg, rgba(255,61,129,0.85), rgba(194,40,96,0.85)); }
#modeLocalBtn:hover .home-action-emoji{ background: linear-gradient(135deg, rgba(180,255,57,0.85), rgba(124,216,56,0.85)); }
/* #modeOnlineBtn se quedó sin su estado :hover cuando el botón estaba
   bloqueado (no hacía falta) — al desbloquearlo, nadie añadió el color
   propio que sí tienen sus dos hermanos de arriba. Mismo patrón exacto,
   con el tono lila que ya usa su icono en reposo. */
#modeOnlineBtn:hover{
  border-color: rgba(156,139,181,0.4);
  background: linear-gradient(180deg, rgba(156,139,181,0.14), rgba(156,139,181,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -14px 18px rgba(156,139,181,0.12), 0 4px 14px rgba(156,139,181,0.16);
}
#modeOnlineBtn:hover .home-action-emoji{ background: linear-gradient(135deg, rgba(156,139,181,0.85), rgba(100,86,120,0.85)); }

/* Sala online: crear (azul) / unirse (dorado) — mismo patrón otra vez,
   ninguno de los dos tenía color propio ni en reposo. */
#onlineCreateBtn .home-action-emoji{ background: linear-gradient(135deg, rgba(143,184,255,0.5), rgba(91,141,239,0.5)); }
#onlineJoinBtn .home-action-emoji{ background: linear-gradient(135deg, rgba(255,210,63,0.5), rgba(255,176,32,0.5)); }
#onlineQuickMatchBtn .home-action-emoji{ background: linear-gradient(135deg, rgba(180,255,57,0.5), rgba(124,216,56,0.5)); }
#onlineCreateBtn:hover{
  border-color: rgba(143,184,255,0.4);
  background: linear-gradient(180deg, rgba(143,184,255,0.14), rgba(143,184,255,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -14px 18px rgba(143,184,255,0.12), 0 4px 14px rgba(143,184,255,0.16);
}
#onlineJoinBtn:hover{
  border-color: rgba(255,210,63,0.4);
  background: linear-gradient(180deg, rgba(255,210,63,0.14), rgba(255,210,63,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -14px 18px rgba(255,210,63,0.12), 0 4px 14px rgba(255,210,63,0.16);
}
#onlineQuickMatchBtn:hover{
  border-color: rgba(180,255,57,0.4);
  background: linear-gradient(180deg, rgba(180,255,57,0.14), rgba(180,255,57,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -14px 18px rgba(180,255,57,0.12), 0 4px 14px rgba(180,255,57,0.16);
}
#onlineCreateBtn:hover .home-action-emoji{ background: linear-gradient(135deg, rgba(143,184,255,0.85), rgba(91,141,239,0.85)); }
#onlineJoinBtn:hover .home-action-emoji{ background: linear-gradient(135deg, rgba(255,210,63,0.85), rgba(255,176,32,0.85)); }
#onlineQuickMatchBtn:hover .home-action-emoji{ background: linear-gradient(135deg, rgba(180,255,57,0.85), rgba(124,216,56,0.85)); }

/* Colección */
.collection-header{ display:flex; justify-content:space-between; align-items:center; margin-bottom: 22px; flex-wrap:wrap; gap: 10px; }
.pack-btn{
  background: linear-gradient(90deg, var(--gold), var(--pink)); border: 2px solid rgba(255,255,255,0.25);
  clip-path: polygon(10px 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 10px);
  padding: 12px 20px; font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 15px; text-transform: uppercase; letter-spacing: 0.4px;
  color: #1A1220; cursor:pointer;
  box-shadow: 0 0 18px rgba(255,210,63,0.3);
}
.pack-btn:disabled{ opacity: 0.35; cursor: default; box-shadow:none; }
.back-btn{
  display:inline-flex; align-items:center; gap: 6px;
  background: rgba(255,255,255,0.06); border: 1.5px solid rgba(255,255,255,0.18);
  color: var(--cream); border-radius: 999px; padding: 8px 16px; font-size: 13px; cursor:pointer;
  margin-bottom: 14px;
  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.back-btn:hover{
  border-color: rgba(255,210,63,0.5);
  background: linear-gradient(180deg, rgba(255,210,63,0.16), rgba(255,210,63,0.05));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), 0 0 10px rgba(255,210,63,0.18);
}

/* Reveal overlay (abrir sobre) */
.reveal-overlay{
  display:none; position: fixed; inset:0; background: rgba(10,6,16,0.9);
  align-items:center; justify-content:center; z-index: 25; padding: 20px;
}
.reveal-card{
  position:relative;
  background: linear-gradient(180deg, var(--bg2), var(--bg));
  border: 2px solid rgba(255,255,255,0.18);
  clip-path: polygon(20px 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%, 0 20px);
  padding: 32px 26px; width: 100%; max-width: 360px; text-align:center;
  animation: revealPop 0.4s cubic-bezier(.2,.9,.3,1.3);
}
.reveal-card.rarity-rare{ border-color: var(--blue); box-shadow: 0 0 30px rgba(143,184,255,0.35); }
.reveal-card.rarity-legendary{ border-color: var(--gold); box-shadow: 0 0 40px rgba(255,210,63,0.5); }
@keyframes revealPop{ 0%{ transform: scale(0.7); opacity:0; } 100%{ transform: scale(1); opacity:1; } }
/* X para cerrar pop-ups que, a diferencia del de abrir sobre (que exige
   pulsar "¡Genial!" para confirmar que lo has visto) o el de bienvenida
   (login), no tienen nada que confirmar — solo son un estado de espera
   del que a veces hace falta salir a mano (ver onlineWaitOverlay en
   main.js: si el rival tarda o no vuelve, quedarse sin forma de cerrar
   este pop-up encierra al jugador). Mismo lenguaje visual que
   .move-info-close (esquina redonda, mismo tamaño), reutilizable en
   cualquier .reveal-card que la necesite. */
.reveal-close{
  position:absolute; top: 10px; right: 10px; width: 30px; height: 30px; z-index: 2;
  border-radius: 50%; background: rgba(10,6,16,0.55); border: 1.5px solid rgba(255,255,255,0.25);
  color: var(--cream); font-size: 13px; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.reveal-close:hover{ background: rgba(255,61,129,0.3); border-color: var(--pink); }
.reveal-emoji{ font-size: 56px; margin-bottom: 8px; }
/* .move-emoji trae su propio font-size (25px, para las tarjetas
   pequeñas) que si no pisaría el 56px de aquí y encogería el icono
   animado del pop-up de info de movimiento. */
.reveal-emoji .move-emoji{ font-size: 56px; }
.reveal-name{ font-family:'Tomorrow', sans-serif; font-weight:800; font-size: 20px; }
/* La frase de "pásale el dispositivo" es una oración entera, no un
   nombre corto como el resto de usos de .reveal-name — con el mismo
   peso extra-grueso se hacía pesada de leer. */
#passDeviceTitle{ font-weight: 500; font-size: 19px; }
.reveal-rarity{ font-size: 12px; letter-spacing: 1px; color: var(--muted); margin-top: 4px; font-weight: 300; }
.reveal-status{ font-size: 13px; color: var(--cream); margin: 14px 0 20px; }

/* Pop-up de bienvenida (nombre / invitado / cuenta) — por encima de
   cualquier otra cosa (incluido el widget de sonido), ya que es lo
   primero que se ve al entrar por primera vez. */
.identity-overlay{ z-index: 50; }
.identity-card{ max-width: 400px; text-align:left; }
.identity-header{ text-align:center; margin-bottom: 6px; }
.identity-header p{ margin-top: 6px; }
.identity-card .draft-start-btn{ font-size: 19px; padding: 12px 24px; margin-top: 4px; }
.identity-link{
  display:block; width:100%; background:none; border:none; color: var(--muted);
  font-size: 13px; margin-top: 14px; padding: 4px; cursor:pointer;
  text-decoration: underline; text-underline-offset: 3px;
  transition: color 0.15s ease;
}
.identity-link:hover{ color: var(--cream); }
.identity-error{ color: var(--pink); font-size: 12.5px; margin: -10px 0 14px; text-align:left; }

/* Botón de "Iniciar sesión con Google" — sigue al pie de la letra las
   guías de marca de Google (fondo blanco, borde gris, logo de 4 colores,
   tipografía Roboto/Arial) en vez de nuestro estilo de tarjeta habitual,
   porque es justo ese aspecto reconocible el que genera confianza aquí. */
.google-signin-block{ margin: 6px 0 14px; }
.google-signin-btn{
  display:flex; align-items:center; justify-content:center; gap: 10px;
  width:100%; height: 44px; padding: 0 16px;
  background:#fff; border: 1px solid #747775; border-radius: 8px;
  color:#1f1f1f; cursor:pointer;
  font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  font-size: 15px; font-weight: 500; letter-spacing: 0.15px;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
.google-signin-btn:hover{ background:#f8f9fa; box-shadow: 0 1px 2px rgba(60,64,67,0.3), 0 1px 3px 1px rgba(60,64,67,0.15); }
.google-signin-btn:active{ background:#f1f3f4; }
.google-signin-icon{ display:flex; flex-shrink:0; }
.google-signin-icon svg{ width:18px; height:18px; display:block; }
.google-signin-sub{ font-size: 11.5px; color: var(--muted); text-align:center; margin-top: 8px; font-weight: 400; }

.identity-options{ display:flex; flex-direction:column; gap: 10px; margin: 6px 0 18px; }
.identity-option-btn{
  display:flex; align-items:center; gap: 14px; width:100%; padding: 13px 16px; text-align:left;
  background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
  border: 2px solid rgba(255,255,255,0.14);
  clip-path: polygon(12px 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%, 0 12px);
  color: var(--cream); cursor:pointer;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.identity-option-btn:hover:not(.locked){ transform: translateY(-1px); border-color: rgba(255,255,255,0.35); }
.identity-option-btn.locked{ opacity: 0.45; cursor: default; filter: grayscale(0.4); }
.identity-option-icon{ font-size: 21px; flex-shrink:0; width: 26px; text-align:center; }
.identity-option-title{ font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 15px; }
.identity-option-sub{ font-size: 11.5px; color: var(--muted); margin-top: 1px; font-weight: 400; }
.identity-divider{
  text-align:center; color: var(--muted); font-size: 11.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 1.5px; margin: 2px 0 10px;
}
/* En la pantalla online, el divisor separa "Jugar ahora" de las dos
   opciones de sala privada — con el margen por defecto quedaba pegado al
   primer botón y parecía describirlo a él, en vez de a los dos de abajo. */
#onlineChooseStep .identity-divider{ margin-top: 22px; }

/* Pop-up de perfil (avatar en grande, renombrar, cerrar sesión) */
.profile-card{ position:relative; max-width: 360px; padding-top: 40px; text-align:center; }
.profile-modal-name-input{ text-align:center; margin: 4px 0 16px; }
/* Solo queda de solo lectura un instante, mientras se confirma el cambio
   de nombre con el servidor (rename_user) — el opacado hace de indicador
   de "guardando" sin necesitar un spinner aparte. */
.profile-modal-name-input:read-only{ opacity: 0.7; cursor: default; }
.profile-modal-name-input:read-only:focus{ box-shadow:none; border-color: rgba(255,255,255,0.14); }
.profile-modal-name-hint{ font-size: 11px; color: var(--muted); margin: -12px 0 12px; }
.profile-modal-name-confirm{
  width:auto; display:inline-block; margin: 0 0 14px; padding: 8px 22px;
  font-weight: 600; font-size: 14px; text-transform: none; letter-spacing: normal;
  box-shadow: 0 0 16px rgba(255,210,63,0.3);
}
.profile-modal-name-confirm:hover{ box-shadow: 0 0 22px rgba(255,210,63,0.45); }
.profile-card .identity-error{ text-align:center; }
.profile-modal-stats{ justify-content:center; margin-bottom: 18px; }
.profile-logout-link{ color: var(--pink); }
.profile-logout-link:hover{ color: var(--cream); }
/* El aviso de "¿cerrar sesión?" es una confirmación, no la llamada a la
   acción principal de una pantalla — se queda con el mismo tratamiento
   que el resto de títulos/botones pero bastante menos cargado (nada de
   mayúsculas ni el peso extra-grueso de .draft-header/.draft-start-btn). */
.profile-card .identity-header h2{
  font-weight: 600; font-size: 19px; text-transform: none; letter-spacing: normal;
}
.profile-logout-danger{
  background: linear-gradient(90deg, var(--pink), #C22860); color: var(--cream);
  box-shadow: 0 0 24px rgba(255,61,129,0.35);
  font-weight: 500; font-size: 16px; text-transform: none; letter-spacing: normal;
  padding: 12px 24px;
}
.profile-logout-danger:hover{ box-shadow: 0 0 32px rgba(255,61,129,0.5); }

/* Ficha de info/lore de un movimiento (Colección) — dos áreas separadas,
   mismo patrón que la arena de batalla: un marco 3D (.move-info-frame) y,
   pegada justo debajo sin margen, la ficha de texto (.move-info-card).
   Antes era un único .reveal-card con el visor 3D metido a presión dentro
   de su padding — se leía como un recuadro cortado, no como una ventana
   propia. */
.move-info-wrap{ width:100%; max-width: 320px; }
.move-info-frame{
  position:relative; width:100%; height: 210px;
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.015));
  border: 2px solid rgba(255,255,255,0.18);
  border-bottom: none;
  animation: revealPop 0.4s cubic-bezier(.2,.9,.3,1.3);
  /* Solo la esquina de arriba a la izquierda recortada — el borde de abajo
     queda recto de punta a punta para encajar pegado con .move-info-card
     sin dejar un hueco triangular en la unión (mismo motivo que
     .battle-frame/.arena en la arena de batalla). */
  clip-path: polygon(16px 0, 100% 0, 100% 100%, 0 100%, 0 16px);
}
.move-info-frame.rarity-rare{ border-color: var(--blue); }
.move-info-frame.rarity-legendary{ border-color: var(--gold); }
.move-info-canvas-wrap{ position:relative; width:100%; height:100%; overflow:hidden; }
.move-info-canvas-wrap canvas{ position:absolute; inset:0; width:100% !important; height:100% !important; touch-action:none; }
.move-info-close{
  position:absolute; top: 10px; right: 10px; width: 30px; height: 30px; z-index: 2;
  border-radius: 50%; background: rgba(10,6,16,0.55); border: 1.5px solid rgba(255,255,255,0.25);
  color: var(--cream); font-size: 13px; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.move-info-close:hover{ background: rgba(255,61,129,0.3); border-color: var(--pink); }
/* Encaja pegada debajo de .move-info-frame — sin recorte arriba (a
   diferencia del resto de usos de .reveal-card) para que el borde de
   arriba quede recto y la unión se lea como una sola línea. */
.move-info-card{
  position:relative; max-width: none; width:100%;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 16px), calc(100% - 16px) 100%, 0 100%);
  padding: 22px 24px 26px;
}
.move-info-badges{ display:flex; justify-content:center; gap: 8px; margin-top: 10px; }
.move-info-lore{
  text-align:left; font-size: 14px; line-height: 1.55; color: var(--cream);
  margin: 18px 0 4px; font-weight: 400;
}
.move-info-locked-hint{
  font-size: 12.5px; color: var(--gold); margin-top: 16px; text-align:center; font-weight: 400;
}

/* Avatar rig */
.avatar-stage{ display:flex; justify-content:center; margin: 8px 0 20px; }
.avatar-wrap{ width: 148px; height: 185px; position: relative; overflow: hidden; }
.avatar-wrap svg{ width:100%; height:100%; overflow: visible; }
/* Visor 3D (avatar3d.js) — el canvas se monta dentro de .avatar-wrap igual
   que antes iba el <svg>, pero necesita position:absolute (el div ya es
   position:relative de la regla de arriba) para llenar el hueco en vez de
   empujar el layout con su tamaño intrínseco. touch-action:none evita que
   arrastrar para orbitar la cámara también haga scroll de la página en
   móvil. */
.avatar-wrap canvas{ position: absolute; inset: 0; width: 100% !important; height: 100% !important; touch-action: none; }
/* Marco de la vista previa en Personalizar — mismo diseño que se afinó en
   el lab (lab/character-customize.html): bastante más grande que el
   .avatar-wrap base (que se queda con su tamaño normal para luchadores,
   perfil, popup de movimiento…), con borde redondeado en degradado lila.
   Escopado a .avatar-frame .avatar-wrap para no tocar ningún otro sitio
   donde se usa avatar-wrap. */
.avatar-frame{
  width: min(78vw, 300px); height: min(108vw, 430px);
  border-radius: 18px; padding: 1px;
  background: linear-gradient(to bottom, rgba(160,118,222,0.65), rgba(84,54,132,0.35));
  box-shadow: 0 0 20px rgba(120,84,170,0.28);
}
.avatar-frame .avatar-wrap{
  width: 100%; height: 100%;
  border-radius: 17px;
  box-shadow: inset 0 0 30px rgba(0,0,0,0.35);
}
.avatar-root{ animation: idleBob 1.8s ease-in-out infinite; transform-box: fill-box; transform-origin: 50% 100%; }
.part-armL, .part-armR, .part-legL, .part-legR, .part-torso, .part-head{
  transform-box: fill-box;
}
.part-armL{ transform-origin: 50% 5%; }
.part-armR{ transform-origin: 50% 5%; }
.part-legL{ transform-origin: 50% 0%; }
.part-legR{ transform-origin: 50% 0%; }
.part-torso{ transform-origin: 50% 100%; }
.part-head{ transform-origin: 50% 100%; }

@keyframes idleBob{ 0%,100%{ transform: translateY(0);} 50%{ transform: translateY(-2px);} }

/* Cada movimiento tiene su propia coreografía (no 4 genéricas por
   categoría) — la parte del cuerpo que se anima tiene que corresponder
   a lo que el movimiento representa de verdad: Rizz Point mueve un
   brazo porque es señalar con el dedo, Mewing mueve el brazo hacia la
   mandíbula, NPC Freeze se queda literalmente congelado, etc. La
   duración total de cada una respeta ANIM_DURATION por categoría en
   battle.js/localBattle.js (pose 1.8s, baile 2.1s, meme 1.6s,
   wildcard 1.4s), para que el JS no la corte a media animación.
   Aplicado vía la clase move-<id> (ver playAttackAnimation). */

/* --- POSE (1.8s) --- */
@keyframes sigmaArmL{ 0%{transform:rotate(0);} 30%,70%{transform:rotate(-18deg);} 100%{transform:rotate(0);} }
@keyframes sigmaArmR{ 0%{transform:rotate(0);} 30%,70%{transform:rotate(18deg);} 100%{transform:rotate(0);} }
@keyframes sigmaHead{ 0%,100%{transform:rotate(0);} 35%,75%{transform:rotate(-5deg);} }
.move-sigma_stare .part-armL{ animation: sigmaArmL 1.8s ease; }
.move-sigma_stare .part-armR{ animation: sigmaArmR 1.8s ease; }
.move-sigma_stare .part-head{ animation: sigmaHead 1.8s ease; }

@keyframes rizzPointArm{ 0%{transform:rotate(0);} 30%,70%{transform:rotate(-100deg);} 100%{transform:rotate(0);} }
.move-rizz_point .part-armR{ animation: rizzPointArm 1.8s ease; }

@keyframes mewingArm{ 0%{transform:rotate(0) translateY(0);} 35%,70%{transform:rotate(-130deg) translateY(-4px);} 100%{transform:rotate(0) translateY(0);} }
@keyframes mewingHead{ 0%,100%{transform:rotate(0);} 40%,70%{transform:rotate(4deg);} }
.move-mewing .part-armR{ animation: mewingArm 1.8s ease; }
.move-mewing .part-head{ animation: mewingHead 1.8s ease; }

@keyframes poseArmL{ 0%{transform:rotate(0);} 35%{transform:rotate(-70deg);} 100%{transform:rotate(0);} }
@keyframes poseArmR{ 0%{transform:rotate(0);} 35%{transform:rotate(70deg);} 100%{transform:rotate(0);} }
@keyframes poseLegs{ 0%{transform:translateY(0);} 30%{transform:translateY(-10px);} 55%{transform:translateY(2px);} 100%{transform:translateY(0);} }
@keyframes poseHop{ 0%{transform:translateY(0);} 30%{transform:translateY(-14px);} 60%{transform:translateY(0);} 100%{transform:translateY(0);} }
.move-siuuu_leap .part-armL{ animation: poseArmL 0.9s ease 2; }
.move-siuuu_leap .part-armR{ animation: poseArmR 0.9s ease 2; }
.move-siuuu_leap .part-legL{ animation: poseLegs 0.9s ease 2; }
.move-siuuu_leap .part-legR{ animation: poseLegs 0.9s ease 2; }
.move-siuuu_leap .avatar-root{ animation: poseHop 0.9s ease 2; }

@keyframes emperorArmL{ 0%{transform:rotate(0);} 40%,80%{transform:rotate(-100deg);} 100%{transform:rotate(0);} }
@keyframes emperorArmR{ 0%{transform:rotate(0);} 40%,80%{transform:rotate(100deg);} 100%{transform:rotate(0);} }
@keyframes emperorHead{ 0%,100%{transform:translateY(0);} 40%,80%{transform:translateY(-4px);} }
.move-emperors_pose .part-armL{ animation: emperorArmL 1.8s ease; }
.move-emperors_pose .part-armR{ animation: emperorArmR 1.8s ease; }
.move-emperors_pose .part-head{ animation: emperorHead 1.8s ease; }

/* --- DANCE (2.1s) --- */
@keyframes danceHip{ 0%,100%{transform:rotate(0);} 25%{transform:rotate(8deg);} 75%{transform:rotate(-8deg);} }
@keyframes danceArmL{ 0%,100%{transform:rotate(0);} 25%{transform:rotate(25deg);} 75%{transform:rotate(-15deg);} }
@keyframes danceArmR{ 0%,100%{transform:rotate(0);} 25%{transform:rotate(-25deg);} 75%{transform:rotate(15deg);} }
.move-ohio_wiggle .part-torso{ animation: danceHip 0.7s ease-in-out 3; }
.move-ohio_wiggle .part-armL{ animation: danceArmL 0.7s ease-in-out 3; }
.move-ohio_wiggle .part-armR{ animation: danceArmR 0.7s ease-in-out 3; }

@keyframes griddyLegL{ 0%,100%{transform:translateX(0) rotate(0);} 25%{transform:translateX(6px) rotate(15deg);} 75%{transform:translateX(-6px) rotate(-15deg);} }
@keyframes griddyLegR{ 0%,100%{transform:translateX(0) rotate(0);} 25%{transform:translateX(-6px) rotate(-15deg);} 75%{transform:translateX(6px) rotate(15deg);} }
@keyframes griddyArmL{ 0%,100%{transform:rotate(0);} 25%{transform:rotate(-20deg);} 75%{transform:rotate(20deg);} }
@keyframes griddyArmR{ 0%,100%{transform:rotate(0);} 25%{transform:rotate(20deg);} 75%{transform:rotate(-20deg);} }
.move-griddy_step .part-legL{ animation: griddyLegL 0.42s ease-in-out 5; }
.move-griddy_step .part-legR{ animation: griddyLegR 0.42s ease-in-out 5; }
.move-griddy_step .part-armL{ animation: griddyArmL 0.42s ease-in-out 5; }
.move-griddy_step .part-armR{ animation: griddyArmR 0.42s ease-in-out 5; }

@keyframes shuffleSpin{ 0%{transform:rotate(0);} 100%{transform:rotate(360deg);} }
@keyframes shuffleLegs{ 0%,100%{transform:translateX(0);} 50%{transform:translateX(3px);} }
.move-aura_shuffle .avatar-root{ animation: shuffleSpin 2.1s linear; }
.move-aura_shuffle .part-legL{ animation: shuffleLegs 0.3s ease-in-out 7; }
.move-aura_shuffle .part-legR{ animation: shuffleLegs 0.3s ease-in-out 7 reverse; }

@keyframes fanumArm{ 0%,100%{transform:rotate(0) translateY(0);} 30%,60%{transform:rotate(-110deg) translateY(-6px);} 45%{transform:rotate(-90deg) translateY(-4px);} }
@keyframes fanumBounce{ 0%,100%{transform:translateY(0);} 50%{transform:translateY(-3px);} }
.move-fanum_flow .part-armR{ animation: fanumArm 0.7s ease-in-out 3; }
.move-fanum_flow .avatar-root{ animation: fanumBounce 0.7s ease-in-out 3; }

/* --- MEME (1.6s) --- */
@keyframes gyattArmL{ 0%,100%{transform:rotate(0);} 30%,60%{transform:rotate(-150deg);} }
@keyframes gyattArmR{ 0%,100%{transform:rotate(0);} 30%,60%{transform:rotate(150deg);} }
@keyframes gyattHead{ 0%,100%{transform:translateY(0) rotate(0);} 30%,60%{transform:translateY(-3px) rotate(-8deg);} }
.move-gyatt_alert .part-armL{ animation: gyattArmL 1.6s ease; }
.move-gyatt_alert .part-armR{ animation: gyattArmR 1.6s ease; }
.move-gyatt_alert .part-head{ animation: gyattHead 1.6s ease; }

/* Al contrario que el resto: la gracia de "congelarse" es precisamente
   dejar de moverse — un par de saltos erráticos (el "bug") y luego
   quieto del todo, en vez de una coreografía continua. */
@keyframes npcFreezeEffect{
  0%{transform:translate(0,0); filter:grayscale(0);}
  8%{transform:translate(-3px,1px); filter:grayscale(0.6);}
  16%{transform:translate(3px,-2px); filter:grayscale(0);}
  24%{transform:translate(-2px,2px); filter:grayscale(0.6);}
  32%{transform:translate(2px,-1px); filter:grayscale(0);}
  40%,100%{transform:translate(0,0); filter:grayscale(0);}
}
.move-npc_freeze .avatar-root{ animation: npcFreezeEffect 1.6s ease; }

/* "6 7": los dos brazos hacen EXACTAMENTE el mismo giro (misma
   magnitud, mismo ritmo) — solo cambia el signo del ángulo entre lado
   L y R para que sea un espejo real, no dos animaciones distintas como
   antes (un lado giraba -100deg, el otro solo 20deg, nada simétrico).
   Un retraso negativo de media vuelta en el brazo derecho (-0.2s sobre
   un ciclo de 0.4s) hace que arranque ya a mitad de su recorrido, así
   los dos quedan en contrafase: cuando uno sube el otro baja, todo el
   rato — el vaivén que describe el gesto real. */
@keyframes sixSevenArmL{ 0%, 100%{ transform: rotate(0deg); } 50%{ transform: rotate(-55deg); } }
@keyframes sixSevenArmR{ 0%, 100%{ transform: rotate(0deg); } 50%{ transform: rotate(55deg); } }
.move-six_seven .part-armL{ animation: sixSevenArmL 0.4s ease-in-out 4; }
.move-six_seven .part-armR{ animation: sixSevenArmR 0.4s ease-in-out 4; animation-delay: -0.2s; }

@keyframes skibidiHead{ 0%,100%{transform:translateY(0) rotate(0);} 20%{transform:translateY(-5px) rotate(-10deg);} 40%{transform:translateY(2px) rotate(8deg);} 60%{transform:translateY(-5px) rotate(-10deg);} 80%{transform:translateY(2px) rotate(8deg);} }
.move-skibidi_combo .part-head{ animation: skibidiHead 1.6s ease-in-out; }

/* --- WILDCARD (1.4s) --- */
@keyframes choppedArm{ 0%{transform:rotate(0);} 20%{transform:rotate(-130deg);} 40%{transform:rotate(20deg);} 100%{transform:rotate(0);} }
@keyframes choppedFlash{ 0%,100%{filter:drop-shadow(0 0 0 rgba(255,210,63,0));} 30%{filter:drop-shadow(0 0 22px rgba(255,210,63,1));} }
.move-chopped_flash .part-armR{ animation: choppedArm 0.5s ease-out; }
.move-chopped_flash .avatar-root{ animation: choppedFlash 1.4s ease-out; }

@keyframes wildSpin{ 0%{transform:rotate(0);} 100%{transform:rotate(360deg);} }
@keyframes wildGlow{ 0%,100%{ filter: drop-shadow(0 0 0 rgba(255,210,63,0)); } 50%{ filter: drop-shadow(0 0 18px rgba(255,210,63,0.9)); } }
.move-aura_surge .avatar-root{ animation: wildSpin 1.4s ease, wildGlow 1.4s ease-in-out 2; }


/* Customization */
.customize-screen{ width:100%; max-width: 420px; }
.customize-screen .avatar-stage{ margin-top: 10px; }
.customize-row{ display:flex; align-items:center; gap: 16px; margin-bottom: 14px; }
/* 50px cabía con las etiquetas cortas de siempre (piel/pelo/tipo) pero
   "superior"/"inferior" no entraban — el texto se recortaba pegado a los
   swatches, casi sin hueco. Más ancho para las dos, con más aire detrás. */
.customize-label{ width: 74px; font-size: 12.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; font-weight: 300; }
.swatch-group{ display:flex; gap: 9px; }
.swatch{
  width: 36px; height: 36px; border-radius: 7px; border: 2px solid rgba(255,255,255,0.18);
  cursor: pointer; transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.swatch.selected{ border-color: var(--cream); transform: scale(1.12) rotate(3deg); box-shadow: 0 0 10px rgba(255,255,255,0.4); }
.customize-row-accessories{ align-items:flex-start; flex-wrap:wrap; }
.slider-row input[type=range]{ flex:1; accent-color: var(--gold); cursor:pointer; }
.slider-row .slider-val{ font-size: 11px; color: var(--muted); width: 34px; text-align:right; flex: 0 0 auto; }
.customize-row-accessories .swatch-group{ flex-wrap:wrap; }
.customize-hint{ font-size: 12.5px; color: var(--muted); margin: -4px 0 14px; font-weight: 300; }
.accessory-btn{
  background: linear-gradient(180deg, rgba(255,255,255,0.08), rgba(255,255,255,0.02));
  border: 1.5px solid rgba(255,255,255,0.2);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
  color: var(--cream); padding: 8px 18px; font-size: 14px; cursor:pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, transform 0.15s ease;
}
.accessory-btn:hover:not(.locked){ transform: translateY(-1px); border-color: rgba(255,255,255,0.4); }
.accessory-btn.on{
  border-color: rgba(255,210,63,0.55);
  background: linear-gradient(180deg, rgba(255,210,63,0.2), rgba(255,210,63,0.05));
  color: var(--gold);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), inset 0 -10px 14px rgba(255,210,63,0.12), 0 3px 10px rgba(255,210,63,0.2);
}
.accessory-btn.locked{ opacity: 0.4; cursor: default; }

.preset-row{ display:flex; gap: 9px; flex-wrap:wrap; align-items:flex-start; align-content:flex-start; justify-content:center; margin: 4px 0 18px; }
.preset-btn{
  background: linear-gradient(180deg, rgba(255,255,255,0.09), rgba(255,255,255,0.02));
  border: 1.5px solid rgba(255,255,255,0.22);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.14);
  clip-path: polygon(10px 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 10px);
  color: var(--cream); padding: 10px 20px; font-size: 14.5px; text-transform: uppercase; letter-spacing: 0.3px;
  font-weight: 700; cursor:pointer; transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.preset-btn:hover{
  border-color: rgba(255,210,63,0.5); transform: translateY(-1px);
  background: linear-gradient(180deg, rgba(255,210,63,0.16), rgba(255,210,63,0.04));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), inset 0 -12px 16px rgba(255,210,63,0.12), 0 4px 12px rgba(255,210,63,0.2);
}

/* Tienda de cosméticos (Colección) */
.shop-layout{ display:flex; flex-direction:column; align-items:center; gap: 6px; }
.shop-avatar-stage{ margin: 24px 0 10px; }
.shop-card{
  background: linear-gradient(180deg, rgba(185,142,255,0.14), rgba(46,31,82,0.32));
  border: 2px solid rgba(255,255,255,0.14);
  clip-path: polygon(12px 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%, 0 12px);
  padding: 15px 13px; text-align:left; cursor:pointer;
  transition: border-color 0.15s ease, transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.shop-card:hover{ transform: translateY(-2px); border-color: rgba(255,210,63,0.4); box-shadow: 0 0 14px rgba(255,210,63,0.15); }
.shop-card.previewing{ border-color: var(--gold); background: rgba(255,210,63,0.08); box-shadow: 0 0 18px rgba(255,210,63,0.3); }
.shop-card .move-top{ display:flex; justify-content:space-between; align-items:center; }
.shop-card .move-emoji{ font-size: 27px; }
.shop-card .move-name{ font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 16px; margin-top: 7px; }
.shop-preview-tag{ display:block; margin-top: 5px; font-size: 12px; color: var(--muted); font-weight: 300; }
.shop-card.previewing .shop-preview-tag{ color: var(--gold); font-weight:600; }
.shop-buy-btn{
  width:100%; margin-top: 9px; background: linear-gradient(90deg, var(--gold), var(--pink)); border: 1.5px solid rgba(255,255,255,0.2);
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
  padding: 9px 12px; font-family:'Tomorrow', sans-serif; font-weight:700; text-transform: uppercase; letter-spacing: 0.3px;
  font-size: 14px; color: #1A1220; cursor:pointer;
}
.shop-buy-btn:disabled{ opacity: 0.35; cursor: default; background: rgba(255,255,255,0.1); color: var(--muted); }
.shop-owned-tag{ display:block; margin-top: 9px; text-align:center; font-size: 13px; color: var(--lime); font-weight:600; text-transform: uppercase; letter-spacing: 0.3px; }

/* Timing minigame */
.timing-overlay{
  display:none; position: fixed; inset:0; background: rgba(10,6,16,0.85);
  align-items:center; justify-content:center; z-index: 20; padding: 20px;
}
.timing-card{
  position:relative;
  background: linear-gradient(180deg, var(--bg2), var(--bg));
  border: 2px solid rgba(255,210,63,0.3);
  clip-path: polygon(20px 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%, 0 20px);
  box-shadow: 0 0 40px rgba(255,61,129,0.15);
  padding: 26px 22px; width: 100%; max-width: 420px; text-align:center;
}
/* Borde que se va "consumiendo" alrededor de la tarjeta mientras tienes
   tiempo para ejecutar el golpe — recorre exactamente el mismo contorno
   cortado en diagonal que el clip-path de la tarjeta (ver setupExecRing
   en battle.js, que calcula los puntos y el perímetro real). */
.exec-timer-ring{
  position:absolute; inset:0; width:100%; height:100%;
  pointer-events:none; z-index: 2; overflow: visible;
}
#execTimerPolygon{
  fill:none; stroke: var(--gold); stroke-width: 3;
  filter: drop-shadow(0 0 4px rgba(255,210,63,0.7));
}
#execTimerPolygon.urgent{ stroke: var(--pink); filter: drop-shadow(0 0 4px rgba(255,61,129,0.7)); }
.timing-title{ font-family:'Tomorrow', sans-serif; font-weight:700; font-size: 25px; line-height: 1; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
.timing-sub{ font-size: 14px; color: var(--muted); margin-bottom: 20px; font-weight: 400; }

.timing-track{
  position:relative; height: 54px; background: rgba(255,255,255,0.06);
  border-radius: 12px; border: 1px solid rgba(255,255,255,0.1); margin-bottom: 22px; overflow:hidden;
}
.timing-zone{
  position:absolute; top: 4px; bottom: 4px; border-radius: 9px;
  background: linear-gradient(180deg, rgba(255,210,63,0.55), rgba(255,176,32,0.5));
  border: 2px solid var(--gold);
  box-shadow: 0 0 16px rgba(255,210,63,0.55), inset 0 0 10px rgba(255,255,255,0.2);
}
.timing-zone-core{
  position:absolute; top: 4px; bottom: 4px; border-radius: 6px;
  background: rgba(255,255,255,0.75);
  box-shadow: 0 0 10px rgba(255,255,255,0.7);
}
/* Zona ya superada en una barra con dos paradas — se queda a la vista
   pero apagada, para que quede claro cuál toca ahora (la que sigue a
   todo brillo). */
.timing-zone.done{ opacity: 0.4; filter: saturate(0.4); }
.timing-marker{
  position:absolute; top: -4px; bottom:-4px; width: 5px; background: var(--pink);
  border-radius: 4px; box-shadow: 0 0 12px rgba(255,61,129,0.9); z-index: 2;
}
/* Marca fantasma de una parada ya hecha (movimientos con stops > 1): el
   marcador de verdad sigue corriendo su misma pasada sin reiniciarse —
   esto solo se queda fijo en el punto exacto donde se pulsó la primera
   vez, como si la línea se hubiera partido en dos ahí mismo. */
.timing-marker-ghost{
  background: var(--gold); box-shadow: 0 0 10px rgba(255,210,63,0.8); z-index: 1;
  opacity: 0.55; animation: timingGhostPop 0.3s cubic-bezier(.2,.9,.3,1.3);
}
@keyframes timingGhostPop{
  0%{ transform: scaleY(1.8); opacity: 0.9; }
  100%{ transform: scaleY(1); opacity: 0.55; }
}
.timing-btn{
  background: linear-gradient(90deg, var(--pink), var(--gold)); border: 2px solid rgba(255,255,255,0.25);
  clip-path: polygon(14px 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%, 0 14px);
  padding: 14px 40px; font-family:'Tomorrow', sans-serif; font-weight:800; font-size: 25px; line-height: 1; text-transform: uppercase; letter-spacing: 0.5px;
  color: #1A1220; cursor:pointer; width:100%;
  box-shadow: 0 0 26px rgba(255,61,129,0.4);
  transition: box-shadow 0.15s ease, transform 0.1s ease;
}
.timing-btn:hover{ box-shadow: 0 0 34px rgba(255,61,129,0.55); }
.timing-btn:active{ transform: scale(0.98); }
.timing-result{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding: 10px 0 2px; animation: revealPop 0.3s cubic-bezier(.2,.9,.3,1.3);
}
.timing-result-score{
  font-family:'Tomorrow', sans-serif; font-weight:800; font-size: 40px;
  background: linear-gradient(90deg, var(--gold), var(--pink));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.timing-result-label{ font-size: 14px; color: var(--cream); font-weight:600; margin-top: 2px; }
/* "100%" parpadea rápido un momento cuando el golpe es perfecto, y
   luego se queda fijo (a opacidad plena, igual que el resto del rato
   que dura el confeti) — steps(1) para un parpadeo seco, no un fundido
   suave, que se lee más como "¡ojo, esto es especial!". 6 parpadeos de
   0.15s = 0.9s, bastante menos que los 2s que dura el confeti, así que
   siempre le da tiempo a asentarse antes de que se cierre el overlay. */
@keyframes perfectScoreFlash{ 0%, 100%{ opacity:1; } 50%{ opacity:0.15; } }
.timing-result-score.perfect-flash{ animation: perfectScoreFlash 0.15s steps(1, end) 6; }

/* Confeti al acertar un 100 justo — piezas generadas por JS (una por
   .confetti-piece, con --dx/--dy/--rot al azar como variables inline),
   ancladas a .timing-card (ya tiene position:relative) para que
   revienten desde el centro de la tarjeta entera, no solo del texto. */
.confetti-burst{ position:absolute; inset:0; overflow:visible; pointer-events:none; z-index:6; }
.confetti-piece{
  position:absolute; top:50%; left:50%; width:6px; height:9px;
  animation: confettiFly 2s ease-out forwards;
}
/* Se queda a opacidad plena hasta bien entrada la animación (70%) y
   solo entonces empieza a desvanecerse — antes se apagaba desde el
   primer fotograma, así que con una animación tan corta (0.85s) casi no
   daba tiempo a verlo. */
@keyframes confettiFly{
  0%{ transform: translate(-50%,-50%) rotate(0deg); opacity:1; }
  70%{ transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) rotate(var(--rot)); opacity:1; }
  100%{ transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy) + 30px)) rotate(var(--rot)); opacity:0; }
}

/* Minijuego del "6 7" (ver js/mashMinigame.js) — alternativa a la barra
   de timing para este movimiento en concreto: en vez de parar un
   marcador en el momento justo, aquí se trata de arrastrar un
   deslizador vertical arriba y abajo lo más rápido posible (con el dedo
   en móvil, pulsar-y-arrastrar con el ratón en escritorio — el mismo
   gesto en los dos, a diferencia de un botón de clic). Reutiliza
   .timing-overlay/.timing-card (mismo fondo oscuro, misma tarjeta
   recortada) con su propio contenido dentro: un visor 3D del propio
   personaje (mismo patrón que .move-info-frame, un createAvatar3D
   aparte montado solo mientras dura el minijuego) junto al deslizador, y
   dos barras de estado — tiempo restante (arriba) y "energía" del ritmo
   de arrastre actual (abajo, sube al mover el deslizador y baja sola si
   se para, para que se note que hay que mantener el ritmo, no solo
   moverlo una vez).
   Un pelín más estrecha que la tarjeta de la barra de timing (380px
   frente a 420px) porque aquí no hace falta tanto ancho para una pista
   horizontal larga. */
.mash-card{ max-width: 380px; }
.mash-body{ display:flex; gap: 14px; align-items:stretch; margin-bottom: 16px; }
.mash-avatar-frame{
  position:relative; flex: 1 1 auto; min-width:0; height: 210px; overflow:hidden;
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.015));
  border: 2px solid rgba(255,210,63,0.3); border-radius: 12px;
}
.mash-avatar-frame canvas{ position:absolute; inset:0; width:100% !important; height:100% !important; touch-action:none; }

/* Columna del deslizador — ancho fijo (no flex:1 como el visor) para que
   el "palo" quede estrecho de verdad, con el dedo/flecha flotando encima
   sin empujar la pista hacia abajo (position:absolute respecto a esta
   columna, igual que el dedo del botón de clic que sustituye). */
.mash-slider-col{ position:relative; flex: 0 0 72px; display:flex; justify-content:center; }
.mash-slider-hint{
  position:absolute; top:-6px; left:50%; transform: translateX(-50%);
  font-size: 22px; color: var(--gold); line-height:1; z-index:2;
  animation: mashSliderHintPulse 0.8s ease-in-out infinite;
  pointer-events:none;
}
@keyframes mashSliderHintPulse{
  0%, 100%{ transform: translateX(-50%) translateY(0); opacity:1; }
  50%{ transform: translateX(-50%) translateY(-6px); opacity:0.55; }
}
/* touch-action:none es lo que deja arrastrar con el dedo en móvil sin que
   el navegador interprete el gesto como scroll de la página — sin esto,
   el primer arrastre se comería como un scroll en vez de mover el
   deslizador. cursor:grab/grabbing es el equivalente en escritorio (el
   propio cursor ya avisa de que esto se arrastra, no se clica). */
.mash-slider-track{
  position:relative; width: 54px; height: 210px; margin-top: 20px;
  border-radius: 999px; background: rgba(255,255,255,0.06);
  border: 2px solid rgba(255,255,255,0.14);
  touch-action: none; cursor: grab; user-select:none; -webkit-user-select:none;
}
.mash-slider-track:active{ cursor: grabbing; }
.mash-slider-thumb{
  position:absolute; left:50%; transform: translate(-50%, -50%);
  width: 42px; height: 42px; border-radius: 50%;
  background: linear-gradient(180deg, var(--pink), var(--gold));
  border: 2px solid rgba(255,255,255,0.35);
  box-shadow: 0 0 18px rgba(255,61,129,0.5);
  pointer-events:none; /* la pista entera captura el puntero — el thumb solo se mueve visualmente, JS le fija su `top` en cada frame */
}

.mash-timebar-track{
  height: 8px; border-radius: 999px; background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.12); overflow:hidden; margin-bottom: 16px;
}
.mash-timebar-fill{
  height:100%; width:100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--gold), var(--pink));
  transition: width 0.1s linear;
}
/* Últimos ~3s: mismo cambio a rosa/rojo que .exec-timer-ring.urgent en la
   barra de timing, para avisar de que se acaba el tiempo con el mismo
   lenguaje visual en los dos minijuegos. */
.mash-timebar-fill.urgent{ background: linear-gradient(90deg, var(--pink), #ff3d81); }

.mash-energy-track{
  height: 10px; border-radius: 999px; background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.12); overflow:hidden;
}
.mash-energy-fill{
  height:100%; width:0%; border-radius: 999px;
  background: linear-gradient(90deg, var(--blue), var(--lilac));
  transition: width 0.08s ease-out;
}

/* Resumen de fin de combate — lo que te llevas de la partida (aura y
   drip), así que tiene que leerse a primera vista, no como una nota al
   pie del mensaje de victoria/derrota. */
.end-summary{
  text-align:center; font-size: 22px; font-weight:700;
  font-family:'Tomorrow', sans-serif; color: var(--gold); margin-top: 10px; display:none;
}

/* Fin de combate: en vez de dejar el resultado como una línea más
   entre los botones de movimiento ya deshabilitados, se oscurece toda
   la tarjeta y el mensaje + los botones de menú/revancha aparecen como
   un pop-up encima — así se lee de un vistazo que el duelo terminó, en
   vez de convivir con los restos de la última ronda. Va dentro de
   .arena (no fuera) para heredar su propio clip-path — las esquinas
   recortadas del oscurecido quedan iguales que las de la tarjeta. */
.end-overlay{
  position:absolute; inset:0; z-index: 30;
  display:flex; align-items:center; justify-content:center; padding: 24px;
  background: rgba(8,4,18,0.88);
  opacity:0; pointer-events:none;
  transition: opacity 0.35s ease;
}
.end-overlay.show{ opacity:1; pointer-events:auto; }
.end-card{
  text-align:center; max-width: 320px;
  transform: translateY(10px) scale(0.96); opacity:0;
  transition: transform 0.35s ease, opacity 0.35s ease;
}
.end-overlay.show .end-card{ transform: translateY(0) scale(1); opacity:1; }
.end-title{ font-family:'Tomorrow', sans-serif; font-size: 19px; font-weight:600; color: var(--cream); line-height:1.4; }
/* El titular ("¡GANASTE EL DUELO!") y la frase de después ("Tu aura es
   imparable.") van seguidos en el mismo texto (ver t('youWon') en
   i18n.js) — en block para que el titular ocupe su propia línea
   siempre, en vez de fiarse de que el ancho de la tarjeta rompa la
   línea justo ahí (en pantallas estrechas se veía apretado, casi
   cortado). */
.end-title b{ display:block; margin-bottom: 3px; color: var(--gold); }

/* Móvil estrecho: el logo y la fila de energía están pensados con sitio
   de sobra en pantallas normales, pero en un teléfono estrecho (320-
   400px de ancho, menos el padding del body y de la tarjeta .arena) las
   8 pilas de energía de cada jugador (dos filas, 16 iconos en total)
   no caben y se cortan/superponen. Aquí se encogen icono y logo, no se
   rediseña el layout — sigue siendo la misma fila, solo más compacta. */
@media (max-width: 480px){
  /* En móvil la caja 3D a 520px de alto (ajustada para escritorio) se come
     media pantalla: el panel de movimientos queda tan abajo que hace falta
     scroll para llegar a él. Reduce solo esta variable — .battle-frame y
     .bar-track (que la usan para calcular dónde cae la línea divisoria, ver
     comentario junto a --battle-frame-height en :root) se reajustan solos. */
  :root{ --battle-frame-height: 220px; }
  .logo-btn{ width: min(52vw, 198px); margin-bottom: 0; }
  .energy-dot{ width: 7px; height: 14px; }

  /* Menos margen por encima del logo y menos hueco entre él y el resto del
     contenido — en un móvil ese margen de escritorio (20px de body +
     16px bajo .top-bar) se nota como espacio muerto y empuja todo hacia
     abajo sin necesidad. Apretado una segunda vez (ver .top-bar más abajo,
     que además reduce el gap entre sus dos filas): en las pantallas sin
     tagline (todas menos el inicio) ese hueco entre logo y contenido
     todavía sobraba. */
  body{ padding-top: 2px; }
  .top-bar{ margin-bottom: 2px; }
  /* El marco de combate (.battle-frame/.arena, con su borde dorado) llega
     hasta el borde mismo de la pantalla en móvil — sin el margen lateral
     de 14px de body, que aquí solo se nota como aire muerto a los lados.
     Se hace SOLO en .arena-screen (no en body, que dejaría sin margen
     también títulos/texto suelto de otras pantallas, que sí lo necesitan)
     con margen negativo en vez de tocar el padding de body — así
     .bar-track (position:absolute, left/right:14px respecto a
     #arenaScreen) sigue cayendo exactamente donde debe: 14px desde el
     borde real de la pantalla, que ahora coincide con el borde de la
     caja porque las dos comparten el mismo contenedor ensanchado. */
  .arena-screen{ margin-left: -14px; margin-right: -14px; width: calc(100% + 28px); }

  /* La frase bajo el logo es solo un adorno de marca y se repite en la
     cabecera de TODAS las pantallas — en el resto (donde ya aparece el
     botón "Volver", así que queda claro que no estás en el inicio)
     sobra y solo quita sitio. Se queda únicamente en el inicio, y en
     vez de texto fijo entra con un pequeño gesto de bienvenida — con
     menos margen debajo para acercar el logo a los botones. */
  .tagline{ display:none; }
  body[data-screen="home"] .tagline{
    display:block; margin-bottom: 6px;
    animation: taglineIntro 0.7s ease 0.25s both;
  }
  @keyframes taglineIntro{
    0%{ opacity:0; transform: translateY(-6px); }
    100%{ opacity:1; transform: translateY(0); }
  }

  /* Solo un recordatorio discreto de "dónde estoy" junto al botón
     Volver — cada pantalla ya tiene su propio título grande debajo, así
     que en móvil es redundante y solo quita sitio. */
  .top-bar-title{ display:none; }

  /* La barra superior entera en una sola línea (Volver + título +
     avatar + nombre + Aura + Drip) no cabe en un teléfono — se parte
     en dos filas, cada una a todo el ancho, como la cabecera de una
     app en vez de una barra de escritorio encogida. */
  .top-bar{ flex-direction: column; align-items: stretch; gap: 4px; }
  .profile-bar{ justify-content: space-between; }
  /* Los números de AURA/DRIP van a font-weight:800 en escritorio — un
     trazo pensado para un badge más grande. En móvil ese mismo grosor en
     una caja mucho más pequeña se ve desproporcionado y encima obliga a
     dejar más padding del que hace falta para no verse apretado. Un peso
     más ligero deja leerse igual de claro con menos aire alrededor, así
     el badge entero puede encogerse. */
  .profile-stat{ padding: 4px 8px; }
  .profile-stat-value{ font-weight: 600; font-size: 15px; }
  .profile-stats{ gap: 5px; }
  /* Etiqueta + número en la misma línea (no apilados) — probando a ver si
     así el badge entero queda más bajo/compacto. Solo en la barra
     superior (.profile-stats), no en el modal de perfil (.profile-modal-
     stats), que tiene más sitio y se queda en columna. */
  .profile-stats .profile-stat{ flex-direction: row; gap: 4px; }

  /* El botón Volver pasa a fijo arriba a la IZQUIERDA (idioma y sonido
     se quedan a la derecha, cada grupo en su esquina, no los tres
     juntos) en vez de vivir dentro del contenido con scroll — así
     siempre está a mano sin ocupar sitio en la cabecera de cada
     pantalla. .top-bar-left NO se oculta con display:none — un padre
     con display:none se lleva por delante también a los hijos
     position:fixed, así que el botón desaparecería del todo en vez de
     solo "escapar" del flujo normal. Sin el título (ya oculto) y con
     el botón fuera de flujo, el contenedor queda vacío por sí solo,
     sin necesidad de ocultarlo aparte. */
  .top-bar .back-btn{
    position: fixed; top: 14px; left: 14px; z-index: 55;
    height: 40px; padding: 0 16px; margin: 0;
    border-radius: 20px; justify-content:center;
    /* Más opaco que el sonido/idioma de la derecha (que comparten el
       mismo fondo tenue) para que se note su propia esquina, distinta
       de ese grupo. */
    background: rgba(255,255,255,0.14); border-color: rgba(255,255,255,0.32);
  }
}

/* Escritorio: usar el ancho disponible en vez de quedarnos en una
   columna estrecha de móvil, y más columnas en las rejillas de tarjetas
   para acortar el scroll (sobre todo en la Colección). */
@media (min-width: 860px){
  .arena-screen, .draft-screen, .collection-screen, .home-screen, .rules, .top-bar, .mode-select-screen, .guest-setup-screen, .online-screen, .ranking-screen{ max-width: 820px; }
  /* .attack-text es un ancho fijo (no crece con el contenido, ver la
     nota grande junto a .attack-row) para que los dos lados nunca se
     toquen — pero al quedarse siempre en 190px (el valor pensado para
     el móvil más estrecho) sin escalar con estos mismos saltos que
     ensanchan el resto de la pantalla, en escritorio el texto seguía
     envolviendo a una segunda línea con espacio de sobra alrededor sin
     usar. Aquí sí hay margen sobrado para que quepa en una sola línea
     incluso "Emperor's Pose 100% ✦ 500", el caso más largo del juego. */
  .attack-text{ width: 280px; }
  .customize-screen{
    max-width: 760px;
    display:grid; grid-template-columns: 240px 1fr; column-gap: 32px;
  }
  .customize-screen .draft-header{ grid-column: 1 / -1; grid-row: 1; }
  .customize-screen .avatar-stage{ grid-column: 1; grid-row: 2 / span 10; position: sticky; top: 20px; margin: 0; align-self: center; }
  .customize-screen .preset-row{ grid-column: 2; grid-row: 2; margin-top: 0; align-self: start; justify-content: flex-start; }
  .customize-screen .customize-row,
  .customize-screen .customize-row-accessories,
  .customize-screen .customize-hint{ grid-column: 2; }
  .customize-screen .draft-start-btn{ grid-column: 1 / -1; }

  .draft-grid{ grid-template-columns: repeat(3, 1fr); }
  .shop-layout{ flex-direction:row; align-items:flex-start; gap: 24px; }
  .shop-avatar-stage{ flex-shrink:0; position: sticky; top: 20px; margin: 24px 0 0; }
}
@media (min-width: 1180px){
  .arena-screen, .draft-screen, .collection-screen, .home-screen, .customize-screen, .rules, .top-bar, .mode-select-screen, .guest-setup-screen, .online-screen, .ranking-screen{ max-width: 980px; }
  .draft-grid{ grid-template-columns: repeat(4, 1fr); }
  .attack-text{ width: 320px; }
}
