/* ====================================================================
   Mahjong Jujuy Legends — sistema visual "Cerro de Siete Colores"
   Paleta directa de la Quebrada de Humahuaca al amanecer.
   Tipografía: Fraunces (display, serif con carácter) + IBM Plex Sans (cuerpo).
   ==================================================================== */

/* v2.48 — las fonts cargan desde index.html (<link> en paralelo + display=optional),
   no por @import acá: el @import era fetch EN SERIE → demoraba el primer pintado y
   reacomodaba el texto al llegar la font ("saltos de pantalla al principio"). */

:root {
  /* paleta — extraída de la quebrada al sol bajo */
  --bg:        #1a0820;     /* noche puneña */
  --bg-elev:   #2a1538;     /* sombra de adobe */
  --bg-elev-2: #3d2350;     /* piedra ceremonial */
  --ink:       #f6efe1;     /* lana cruda */
  --ink-dim:   #b8a98f;     /* tela teñida con nogal */
  --gold:      #f2b84b;     /* oro de carnaval */
  --teal:      #6fe3c1;     /* turquesa de los andes */
  --rose:      #ff6b6b;     /* terracota de hornocal */
  --violet:    #b07ed6;     /* coca en flor */
  --siena:     #c46a2a;     /* tierra ferrugiona */
  --ochre:     #8b6a3b;     /* madera de algarrobo */
  --ok: var(--teal);
  --warn: var(--gold);
  --bad: var(--rose);

  /* ── §19 COLOR FUNCIONAL — el color explica el gameplay, no decora ──
     Estados de ficha (§19.2) y especiales (§19.3). Cada estado se
     distingue por color + brillo + borde, y pasa contraste WCAG 3:1. */
  --state-free:      #f7d88a;   /* ficha jugable — borde cálido claro */
  --state-blocked:   #6f6256;   /* ficha bloqueada — gris cálido apagado */
  --state-selected:  #ffbf3f;   /* ficha en foco — ámbar */
  --state-hint:      #79d88f;   /* par sugerido — verde suave */
  --state-error:     #e84d3d;   /* mismatch — rojo breve */

  --special-golden:    #f6c84f; /* recompensa — dorado */
  --special-frozen:    #82d9ff; /* congelada — celeste hielo */
  --special-bomb:      #ff684d; /* explosiva — rojo/naranja */
  --special-locked:    #8d7aa8; /* obstáculo — violeta */
  --special-lightning: #7adcff; /* urgencia — cian eléctrico */
  --special-eye:       #64dcc8; /* visión — turquesa */
  --boss-accent:       #ff5ea8; /* borde de boss — magenta */

  --shadow-sm: 0 2px 6px rgba(0,0,0,0.35);
  --shadow:    0 6px 22px rgba(0,0,0,0.45);
  --shadow-lg: 0 18px 48px rgba(0,0,0,0.55);

  --r-sm: 10px;
  --r:    16px;
  --r-lg: 24px;

  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  --font-display: 'Fraunces', 'Cormorant Garamond', 'Times New Roman', serif;
  --font-body:    'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body {
  margin: 0; padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.45;
  overscroll-behavior: none;
  /* Evita el "arrastrar = seleccionar texto" (como en Word) que rompía la
     jugabilidad al clickear fuera de las fichas. */
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -webkit-touch-callout: none;
}
/* Inputs/áreas de texto SÍ seleccionables (por si hay formularios). */
input, textarea, [contenteditable] { user-select: text; -webkit-user-select: text; }
body {
  min-height: 100vh; min-height: 100dvh;
  /* atmósfera: gradiente cálido bajo + frío arriba, como horizonte puneño */
  background:
    radial-gradient(ellipse at 50% 110%, #5a2a44 0%, transparent 60%),
    radial-gradient(ellipse at 50% -10%, #1d3a5a 0%, transparent 55%),
    var(--bg);
  position: relative;
}
/* Detalle VIVO en el fondo: bruma andina que deriva/respira lento detrás de
   TODO. Sutil (opacidad baja) y coherente con el gradiente del mundo —
   se tiñe con los colores cálidos/fríos del horizonte. */
body::before {
  content: ''; position: fixed; inset: -25%; z-index: 0; pointer-events: none;
  background:
    radial-gradient(38% 30% at 24% 28%, rgba(242,184,75,0.12), transparent 70%),
    radial-gradient(34% 26% at 80% 68%, rgba(109,140,90,0.11), transparent 70%),
    radial-gradient(30% 22% at 60% 12%, rgba(196,106,42,0.10), transparent 72%);
  animation: bg-drift 28s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes bg-drift {
  0%   { transform: translate3d(-2%, -1.5%, 0) scale(1.0); }
  100% { transform: translate3d(3%, 2%, 0) scale(1.09); }
}
body.reduce-motion::before { animation: none; }

.app { display: grid; grid-template-rows: auto 1fr auto; min-height: 100vh; min-height: 100dvh; position: relative; z-index: 1; }

h1, h2, h3 { font-family: var(--font-display); letter-spacing: -0.01em; }
h1 { font-weight: 900; }
h2 { font-weight: 700; }
h3 { font-weight: 700; }

/* ────────────── topbar ────────────── */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: calc(10px + var(--safe-top)) 16px 10px;
  background: linear-gradient(180deg, rgba(42,21,56,0.95), rgba(26,8,32,0.85));
  border-bottom: 1px solid rgba(242,184,75,0.15);
  position: sticky; top: 0; z-index: 10;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.logo { display: flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 900; font-size: 18px; letter-spacing: -0.01em; }
/* Botón de sonido siempre visible en el topbar. */
.topbar-btn {
  background: rgba(255,255,255,0.06); border: 1px solid rgba(242,184,75,0.28);
  color: var(--ink); border-radius: 10px; font-size: 16px; line-height: 1;
  min-width: 38px; height: 34px; cursor: pointer; display: grid; place-items: center;
  -webkit-tap-highlight-color: transparent; transition: background .15s, opacity .15s;
}
.topbar-btn:hover { background: rgba(255,255,255,0.13); }
.topbar-btn:active { transform: scale(0.94); }
.topbar-btn.muted { opacity: 0.55; }
.logo img { border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.4); }
.wallet { display: flex; gap: 8px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px;
  background: var(--bg-elev);
  font-family: var(--font-body); font-weight: 700; font-size: 13px;
  border: 1px solid rgba(255,255,255,0.06);
}
.chip.coins {
  background: linear-gradient(135deg, #5a3d12, #3a2812);
  color: var(--gold);
  border-color: rgba(242,184,75,0.35);
  text-shadow: 0 1px 2px rgba(0,0,0,0.4);
}
.chip.gems {
  background: linear-gradient(135deg, #1f4a4a, #143030);
  color: var(--teal);
  border-color: rgba(111,227,193,0.35);
}

/* ────────────── navbar inferior ────────────── */
.navbar {
  display: grid; grid-template-columns: repeat(5,1fr);
  background: rgba(42,21,56,0.95);
  border-top: 1px solid rgba(255,255,255,0.06);
  padding-bottom: var(--safe-bottom);
  position: sticky; bottom: 0; z-index: 10;
  backdrop-filter: blur(10px);
}
.nav-btn {
  background: none; border: 0;
  color: var(--ink-dim);
  padding: 12px 4px 10px;
  display: grid; gap: 3px; align-items: center; justify-items: center;
  cursor: pointer; font-size: 20px; font-family: inherit;
  transition: color .15s, transform .08s;
}
.nav-btn small { font-size: 10px; opacity: 0.9; font-family: var(--font-body); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.nav-btn:active { transform: scale(0.94); }
.nav-btn[aria-current="page"] { color: var(--gold); }
.nav-btn[aria-current="page"] small { color: var(--gold); }

/* ────────────── screens ────────────── */
.screen { padding: 16px 14px 28px; overflow-x: hidden; }
.screen h1 { margin: 6px 0 12px; font-size: 26px; line-height: 1.1; }
.screen h2 { margin: 20px 0 10px; font-size: 14px; color: var(--ink-dim); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; font-family: var(--font-body); }

/* ────────────── home hero ────────────── */
.hero {
  position: relative; isolation: isolate;
  padding: 28px 22px 24px;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
  min-height: 240px;
  background: linear-gradient(180deg, #2a1538 0%, #5a2548 60%, #c46a2a 100%);
  border: 1px solid rgba(242,184,75,0.3);
}
.hero-scene {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.95;
}
.hero-scene svg { width: 100%; height: 100%; display: block; }
/* Sol con halo pulsante */
@keyframes sun-pulse {
  0%, 100% { opacity: 0.9; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.05); }
}
.hero-scene .sun { animation: sun-pulse 4s ease-in-out infinite; transform-origin: center; transform-box: fill-box; }
@keyframes star-twinkle {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 1; }
}
.hero-scene .star { animation: star-twinkle 3s ease-in-out infinite; }
.hero-scene .star:nth-child(odd) { animation-delay: 1.5s; }

/* ── Board ambient (in-game) ────────────────────────────────────────────── */
/* Sol/luna del board respira lento — eco visual del que ya hace el win. */
.board-svg .board-sun {
  animation: sun-pulse 6s ease-in-out infinite;
  transform-origin: center; transform-box: fill-box;
}
/* Estrellas del board titilan en stagger por nth-child (no random — estable). */
.board-svg .board-star { animation: star-twinkle 3.4s ease-in-out infinite; transform-origin: center; transform-box: fill-box; }
.board-svg .board-star:nth-child(3n+1) { animation-delay: 0s; }
.board-svg .board-star:nth-child(3n+2) { animation-delay: 1.2s; }
.board-svg .board-star:nth-child(3n)   { animation-delay: 2.4s; }

/* Cóndor: silueta que cruza el cielo de izq→der, lentísimo, una pasada cada 24s. */
@keyframes condor-fly {
  0%   { transform: translateX(-12%) translateY(0)   scale(1); opacity: 0; }
  8%   { opacity: 0.55; }
  50%  { transform: translateX(48%)  translateY(-2%) scale(1.02); opacity: 0.65; }
  92%  { opacity: 0.55; }
  100% { transform: translateX(112%) translateY(0)   scale(1); opacity: 0; }
}
.board-svg .ambient-condor {
  animation: condor-fly 24s ease-in-out infinite;
  transform-origin: center; transform-box: fill-box;
  pointer-events: none;
}

/* Serpentina de carnaval: papelitos flotando hacia abajo en diagonal. */
@keyframes serpentina-float {
  0%   { transform: translateY(-8%)  rotate(0deg);   opacity: 0; }
  10%  { opacity: 0.7; }
  90%  { opacity: 0.7; }
  100% { transform: translateY(110%) rotate(420deg); opacity: 0; }
}
.board-svg .ambient-serpentina {
  animation: serpentina-float 11s linear infinite;
  transform-origin: center; transform-box: fill-box;
  pointer-events: none;
}

/* Viento de altura (§15.5): 4 líneas blancas diagonales cruzando el board
   solo durante peek_active. DOM overlay encima del board SVG. */
.wind-fx {
  position: absolute; inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 6;
}
.wind-fx .wind-line {
  position: absolute;
  height: 1.5px;
  background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.55) 30%, rgba(255,255,255,0.85) 50%, rgba(255,255,255,0.55) 70%, transparent 100%);
  width: 60%;
  left: -65%;
  border-radius: 2px;
  filter: blur(0.4px);
  animation: windSweep 1.8s cubic-bezier(0.34, 0.8, 0.5, 1) forwards;
}
.wind-fx .wind-line:nth-child(1) { top: 22%; animation-delay: 0s;    transform: rotate(-6deg); }
.wind-fx .wind-line:nth-child(2) { top: 38%; animation-delay: 0.18s; transform: rotate(-4deg); width: 55%; }
.wind-fx .wind-line:nth-child(3) { top: 56%; animation-delay: 0.32s; transform: rotate(-5deg); width: 65%; }
.wind-fx .wind-line:nth-child(4) { top: 72%; animation-delay: 0.48s; transform: rotate(-3deg); width: 50%; }
@keyframes windSweep {
  0%   { transform: translateX(-160%); opacity: 0; }
  20%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translateX(160%); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .board-svg .board-sun,
  .board-svg .board-star,
  .board-svg .ambient-condor,
  .board-svg .ambient-serpentina,
  .wind-fx .wind-line { animation: none !important; }
  .wind-fx { display: none !important; }
}
.hero h1 {
  position: relative; z-index: 2;
  margin: 0 0 6px;
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 32px;
  font-weight: 900;
  letter-spacing: 0.3px;
  color: #fef7e3;
  text-shadow: 0 2px 8px rgba(0,0,0,0.5), 0 0 20px rgba(242,184,75,0.4);
}
.hero p, .hero .hero-sub {
  position: relative; z-index: 2;
  margin: 0 0 16px;
  color: rgba(255,255,255,0.85);
  font-size: 14px;
  max-width: 28ch;
  text-shadow: 0 1px 3px rgba(0,0,0,0.6);
}
.hero .row {
  position: relative; z-index: 2;
  display: flex; gap: 10px;
}

/* ────────────── buttons ────────────── */
.btn {
  background: linear-gradient(180deg, var(--gold), #c8881d);
  color: #2a1804;
  border: 0;
  padding: 13px 20px;
  border-radius: 999px;
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 15px;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(242,184,75,0.35), inset 0 1px 0 rgba(255,255,255,0.35);
  transition: transform .08s, box-shadow .15s, opacity .15s;
  min-height: 46px;
}
.btn:active { transform: scale(0.97); box-shadow: 0 2px 8px rgba(242,184,75,0.3); }
.btn[disabled] { opacity: 0.5; cursor: default; }
.btn.ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid rgba(255,255,255,0.18);
  box-shadow: none;
}
.btn.small { padding: 8px 14px; font-size: 13px; min-height: 36px; }
.btn.success {
  background: linear-gradient(180deg, var(--teal), #4a9d85);
  color: #0e3030;
  box-shadow: 0 6px 18px rgba(111,227,193,0.35);
}
.btn.danger {
  background: linear-gradient(180deg, var(--rose), #c44141);
  color: #fff;
}

/* ────────────── cards ────────────── */
.cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 14px; }
.card {
  background: var(--bg-elev);
  padding: 14px 16px;
  border-radius: var(--r);
  display: grid; gap: 4px;
  border: 1px solid rgba(255,255,255,0.05);
  box-shadow: var(--shadow-sm);
}
.card .k { font-size: 11px; color: var(--ink-dim); text-transform: uppercase; letter-spacing: 0.1em; font-weight: 600; }
.card .v { font-size: 22px; font-weight: 800; font-family: var(--font-display); }

/* ────────────── world map ────────────── */
.world {
  background: var(--bg-elev);
  border-radius: var(--r);
  padding: 16px;
  margin-bottom: 12px;
  border: 1px solid rgba(255,255,255,0.05);
  box-shadow: var(--shadow-sm);
}
.world header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.world h3 { margin: 0; font-size: 18px; }
/* v2.20 — auto-enfoque del sendero */
.world.current-world { scroll-margin-top: 16px; border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold), var(--shadow-sm); }
.world.world-collapsed { padding: 12px 16px; opacity: 0.82; }
.world.world-collapsed .world-scene { display: none; }
.world-done-check { color: #6fe3c1; font-weight: 900; }
.here-badge {
  display: inline-block; font-size: 11px; font-weight: 800; color: #0e0418;
  background: var(--gold); border-radius: 999px; padding: 2px 9px; margin-left: 8px;
  vertical-align: middle; animation: hereBob 1.6s ease-in-out infinite;
}
@keyframes hereBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
body.reduce-motion .here-badge { animation: none; }
.world .meta { font-size: 11px; color: var(--ink-dim); font-weight: 500; }
.world .levels { display: grid; grid-template-columns: repeat(5, 1fr); gap: 7px; }
.lvl {
  aspect-ratio: 1/1;
  display: grid; place-items: center;
  background: linear-gradient(160deg, var(--bg-elev-2), #2c1840);
  border-radius: var(--r-sm);
  font-family: var(--font-display);
  font-weight: 800; font-size: 15px;
  cursor: pointer; border: 0; color: var(--ink);
  position: relative;
  transition: transform .08s, box-shadow .15s;
  font-family: inherit;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.05), 0 2px 6px rgba(0,0,0,0.3);
}
.lvl:active { transform: scale(0.93); }
.lvl.locked { opacity: 0.3; cursor: default; filter: saturate(0.4); }
.lvl.done {
  background: linear-gradient(160deg, #6fe3c1, #3a8a72);
  color: #0e3030;
  box-shadow: 0 4px 12px rgba(111,227,193,0.25);
}
.lvl.current {
  background: linear-gradient(160deg, var(--gold), #b07015);
  color: #2a1804;
  box-shadow: 0 0 0 2px var(--gold), 0 6px 18px rgba(242,184,75,0.5);
  animation: pulsecurr 1.8s ease-in-out infinite;
}
@keyframes pulsecurr {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}
.lvl .stars { position: absolute; bottom: 2px; right: 4px; font-size: 9px; }

/* ────────────── gameplay overlay ────────────── */
.gameboard-wrap {
  position: fixed; inset: 0; z-index: 50;
  /* v2.39 — FLEX column en vez de grid de 4 tracks fijos. El grid `auto auto 1fr auto`
     daba el 1fr a la fila de OBJETIVO (3er hijo) y el BOARD (5º hijo, con capítulo+
     objetivo+layout presentes) caía en una fila implícita → board mal dimensionado y
     contenido desbordado en celular. Con flex, el board toma TODO el espacio sobrante
     sin importar cuántas filas opcionales haya arriba → pantalla fija y bien armada. */
  display: flex; flex-direction: column;
  height: 100dvh; /* viewport dinámico (respeta barra del navegador en celular) */
  overflow: hidden; /* nada de scroll de página: la pantalla queda fija */
  background:
    radial-gradient(ellipse at 50% -10%, #2d1a4a 0%, transparent 50%),
    radial-gradient(ellipse at 50% 110%, #4a2030 0%, transparent 55%),
    var(--bg);
}
/* El tablero ocupa el resto; los demás bloques toman su altura natural. */
.gameboard-wrap > .hud,
.gameboard-wrap > .chapter-row,
.gameboard-wrap > .objective-row,
.gameboard-wrap > .layout-row,
.gameboard-wrap > .dock { flex: 0 0 auto; }
.gameboard-wrap > .board { flex: 1 1 auto; min-height: 0; }
.gameboard-wrap .hud {
  display: flex; align-items: center; gap: 6px;
  padding: calc(6px + var(--safe-top)) 10px 6px;
  background: rgba(0,0,0,0.22); backdrop-filter: blur(8px);
  border-bottom: 1px solid rgba(255,255,255,0.05);
  font-size: 11px;
}
.gameboard-wrap .hud-stat {
  display: flex; flex-direction: column; align-items: center;
  min-width: 44px; flex: 0 1 auto;
  padding: 2px 4px;
}
.gameboard-wrap .hud-stat .k { font-size: 9px; color: var(--ink-dim); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; }
.gameboard-wrap .hud-stat .v { font-size: 15px; font-weight: 800; font-family: var(--font-display); line-height: 1.1; }
.gameboard-wrap .hud .btn.small { padding: 6px 10px; font-size: 11px; }
.gameboard-wrap .hud .btn.icon-only { padding: 4px 8px; font-size: 14px; min-width: 32px; }

/* Badge de layout más fino, no tape */
.layout-row {
  padding: 3px 6px;
  background: rgba(0,0,0,0.15);
  display: flex; justify-content: center;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.layout-row .layout-badge {
  padding: 2px 10px; font-size: 10px;
  background: rgba(242,184,75,0.10);
  border: 1px solid rgba(242,184,75,0.25);
  border-radius: 10px;
  color: var(--gold); letter-spacing: 0.4px;
}

.board {
  position: relative; touch-action: manipulation;
  display: grid; place-items: center;
  padding: 14px; overflow: hidden;   /* v2.29: respiro externo — ninguna ficha pegada al borde */
  min-height: 0;
}
.board svg { width: 100%; height: 100%; max-width: 100%; max-height: 100%; }
/* Despegar el tablero del fondo: sombra de elevación para que "flote".
   v2.26 PERF: antes era `filter: drop-shadow` SOBRE el <svg> vivo → se
   re-rasterizaba CADA FRAME mientras las fichas animan el match (jank). Ahora es
   un box-shadow del contenedor .board (no re-rasteriza el contenido del SVG; el
   overflow:hidden propio NO recorta el box-shadow del propio elemento). Las
   fichas ya tienen su sombra 3D dibujada, así que la profundidad se mantiene. */
.board { box-shadow: 0 14px 30px rgba(0,0,0,0.55); }
.tile { cursor: pointer; transition: transform .1s, filter .12s, opacity .35s ease; }
/* Por defecto TODAS las fichas se ven iguales — misma sombra, mismo color.
   La diferencia visible entre libre/bloqueada SÓLO aparece cuando se activa
   el poder Visión (body.vision-active). Sin Visión, el jugador "lee" el
   tablero por la geometría (las que están arriba se ven arriba), no por
   un truco visual de iluminación. */
.tile.free,
.tile.blocked { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.55)); }
.tile.blocked { cursor: default; }

/* PODER VISIÓN — durante 10s las bloqueadas se ven UN POCO MÁS OSCURAS
   y con MÁS SOMBRA, no transparentes. Las libres mantienen su brillo. */
body.vision-active .board-svg .tile.blocked {
  filter: brightness(0.74) saturate(0.7)
          drop-shadow(0 5px 9px rgba(0,0,0,0.7)) !important;
  /* sin opacity — el usuario las quiere visibles, sólo más oscuras */
}
body.vision-active .board-svg .tile.free {
  filter: drop-shadow(0 4px 8px rgba(0,0,0,0.55))
          drop-shadow(0 0 12px rgba(255,215,106,0.55)) !important;
}

/* Cuenta regresiva del poder Visión — píldora con ojo + barrita que se
   agota. Sin números: el ancho del fill comunica el tiempo restante. */
.vision-countdown {
  position: fixed;
  top: 14px;
  right: 14px;
  z-index: 9000;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: rgba(20, 12, 30, 0.92);
  border: 1px solid rgba(122, 220, 255, 0.55);
  border-radius: 24px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.5), 0 0 14px rgba(122,220,255,0.4);
  animation: visionCountdownIn 0.25s ease-out;
}
@keyframes visionCountdownIn {
  from { transform: translateY(-30px) scale(0.7); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.vision-countdown .vc-eye {
  font-size: 20px;
  filter: drop-shadow(0 0 4px rgba(122,220,255,0.7));
}
.vision-countdown .vc-bar {
  width: 140px;
  height: 9px;
  background: rgba(0,0,0,0.45);
  border-radius: 5px;
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.5);
}
.vision-countdown .vc-fill {
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, #7adcff 0%, #46b4dc 60%, #1f7fa8 100%);
  border-radius: 5px;
  box-shadow: 0 0 8px rgba(122,220,255,0.6);
  /* La transición de width la setea el JS al activar la visión. */
}
@media (max-width: 380px) {
  .vision-countdown .vc-bar { width: 100px; }
}

/* Tutorial de boosters — manito 👇 ANCLADA al botón (es hija del botón del
   dock). Vive ARRIBA del botón apuntando hacia ABAJO hacia él. Sigue al
   botón con cualquier reflow/resize del dock. Reusable para los 6 boosters
   (Visión, Cóndor, Viento, Pachamama, Cardón, Comodín). */
.booster-tutorial-pointer,
.vision-tutorial-pointer {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 9001;
  pointer-events: none;
  text-align: center;
  white-space: nowrap;
}
.booster-tutorial-pointer .btp-hand,
.vision-tutorial-pointer .vt-hand {
  display: block;
  font-size: 38px;
  line-height: 1;
  filter: drop-shadow(0 3px 5px rgba(0,0,0,0.55));
  animation: btpHandBob 1.1s ease-in-out infinite;
}
.booster-tutorial-pointer .btp-msg,
.vision-tutorial-pointer .vt-msg {
  display: inline-block;
  margin-top: 2px;
  background: rgba(26,8,32,0.96);
  color: #f6efe1;
  font-size: 11.5px;
  font-weight: 700;
  padding: 5px 10px;
  border-radius: 12px;
  border: 1px solid rgba(255,215,106,0.6);
  box-shadow: 0 4px 12px rgba(0,0,0,0.5);
  max-width: 150px;
  white-space: normal;
  line-height: 1.25;
}
/* La manito 👇 "cabecea" hacia el botón (baja), reforzando que apunta abajo. */
@keyframes btpHandBob {
  0%, 100% { transform: translateY(-3px); }
  50%      { transform: translateY(4px); }
}
@keyframes vtHandBob { /* legacy alias */
  0%, 100% { transform: translateY(-3px); }
  50%      { transform: translateY(4px); }
}
/* El botón con tip activo late para llamar la atención. */
.booster.booster-tip-pulse,
body.vision-tutorial-active #bVision {
  animation: bVisionPulse 1.1s ease-in-out infinite;
  box-shadow: 0 0 0 3px rgba(122,220,255,0.6), 0 0 18px rgba(122,220,255,0.55);
  z-index: 10;
  position: relative;
}
@keyframes bVisionPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.06); }
}
.tile.selected {
  filter: drop-shadow(0 0 14px #f2b84b) drop-shadow(0 0 5px #f2b84b) brightness(1.10);
}
.tile.hint { animation: hintpulse 0.9s ease-in-out 3; }
@keyframes hintpulse {
  0%, 100% { filter: brightness(1) drop-shadow(0 3px 6px rgba(0,0,0,0.5)); }
  50%      { filter: brightness(1.30) drop-shadow(0 0 14px #f2b84b); }
}

.dock {
  display: flex; gap: 6px;
  padding: 8px 10px calc(10px + var(--safe-bottom));
  background: rgba(0,0,0,0.36); backdrop-filter: blur(10px);
  justify-content: space-around;
  border-top: 1px solid rgba(255,255,255,0.05);
}
.booster {
  background: var(--bg-elev);
  border: 1px solid rgba(255,255,255,0.07);
  color: var(--ink);
  padding: 6px 8px;
  border-radius: var(--r);
  display: grid; gap: 1px; place-items: center;
  font-family: inherit; cursor: pointer;
  min-width: 56px; min-height: 52px;
  position: relative;
  transition: transform .08s, background .15s;
  box-shadow: 0 2px 6px rgba(0,0,0,0.3);
}
.booster:active:not(:disabled) { transform: scale(0.94); }
.booster .ico { font-size: 20px; line-height: 1; }
.booster .lbl { font-size: 9px; opacity: 0.85; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.booster .count {
  position: absolute; top: -5px; right: -5px;
  background: var(--gold); color: #2a1804;
  font-size: 10px; font-weight: 800;
  border-radius: 999px;
  min-width: 20px; height: 20px;
  display: grid; place-items: center;
  padding: 0 5px;
  border: 2px solid var(--bg-elev);
}
.booster:disabled { opacity: 0.35; }
/* v2.31 — poder que NO tenés (count 0) DESAPARECE del dock (no queda gris). El
   dock muestra solo lo usable. Pachamama sin jugada queda visible-gris (la tenés). */
.booster.unavailable { display: none !important; }

/* ════════ v2.32 — íconos de premio SVG + barrido de luz + dock que invita ════════ */
/* Íconos de moneda/gema (premium, escalan con el font del chip) */
.ico-coin, .ico-gem { width: 1.15em; height: 1.15em; vertical-align: -0.22em; display: inline-block; }
.win-rewards .ico-coin, .win-rewards .ico-gem { width: 20px; height: 20px; vertical-align: -5px; }
.surprise-bonus .ico-coin { width: 16px; height: 16px; vertical-align: -3px; }
.coin-fly .ico-coin { width: 26px; height: 26px; display: block; filter: drop-shadow(0 2px 3px rgba(120,80,10,0.5)); }

/* Barrido de luz que cruza el tablero cada tanto (premium). 1 elemento, solo
   transform/opacity (GPU). El overflow:hidden de .board lo recorta lindo. */
.board-sheen {
  position: absolute; top: 0; bottom: 0; left: 0; width: 55%;
  pointer-events: none; z-index: 5; opacity: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,0.16) 50%, transparent 62%);
  mix-blend-mode: screen;
  animation: boardSheen 9s ease-in-out 3s infinite;
}
@keyframes boardSheen {
  0%   { transform: translateX(-120%); opacity: 0; }
  3%   { opacity: 1; }
  14%  { transform: translateX(230%); opacity: 0; }
  100% { transform: translateX(230%); opacity: 0; }
}

/* Dock que INVITA: los poderes disponibles laten con un glow dorado suave
   (escalonado) para que llamen a usarlos. Solo opacity/box-shadow, lentos. */
@media (prefers-reduced-motion: no-preference) {
  .dock .booster:not(.unavailable):not(:disabled) { animation: boosterReady 2.8s ease-in-out infinite; }
  .dock .booster:not(.unavailable):not(:disabled):nth-child(2n) { animation-delay: 0.5s; }
  .dock .booster:not(.unavailable):not(:disabled):nth-child(3n) { animation-delay: 1s; }
  .dock .booster-power:not(.unavailable):not(:disabled) { animation-duration: 2.4s; }
}
@keyframes boosterReady {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}
@media (prefers-reduced-motion: reduce) {
  .board-sheen { display: none; }
  .dock .booster { animation: none !important; }
}

/* ✨ Comodín — la carta mágica. Acento dorado-violeta + pulso constante */
.booster.booster-magic {
  background: linear-gradient(135deg, #5a2548 0%, #7a3878 50%, #c46a2a 100%);
  border: 1px solid rgba(242,184,75,0.45);
  box-shadow: 0 2px 8px rgba(0,0,0,0.4), 0 0 12px rgba(200,154,242,0.25);
  animation: magicPulse 2.4s ease-in-out infinite;
}
.booster.booster-magic .ico { animation: magicSpin 4s linear infinite; }
@keyframes magicPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}
@keyframes magicSpin {
  0%, 100% { transform: rotate(0) scale(1); }
  50%       { transform: rotate(8deg) scale(1.08); }
}
/* Cuando 5to slot está visible, dock se reorganiza */
.dock.dock-5 { gap: 4px; }
.dock.dock-5 .booster { min-width: 50px; padding: 5px 6px; }
.dock.dock-5 .booster .lbl { font-size: 7.5px; }
/* Con Visión + Comodín hay 6 boosters — apretar un poco más */
.dock.dock-6 { gap: 3px; }
.dock.dock-6 .booster { min-width: 44px; padding: 4px 5px; }
.dock.dock-6 .booster .lbl { font-size: 7px; }
.dock.dock-6 .booster .ico { font-size: 18px; }

/* v2.19 — dock con scroll horizontal: hasta 11 poderes desbloqueados sin
   apretarlos hasta romper el tap target. Snap suave + sin scrollbar visible. */
.dock.dock-scroll {
  display: flex; gap: 6px;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  padding: 4px 8px calc(4px + var(--safe-bottom));
  scrollbar-width: none;
}
.dock.dock-scroll::-webkit-scrollbar { display: none; }
.dock.dock-scroll .booster { flex: 0 0 auto; scroll-snap-align: center; }
/* Poderes nuevos: acento turquesa para diferenciarlos de los 6 base. */
.booster.booster-power {
  background: linear-gradient(135deg, #1f5a52 0%, #2f7a6e 55%, #c4922a 100%);
  border: 1px solid rgba(111,227,193,0.4);
  box-shadow: 0 2px 8px rgba(0,0,0,0.4), 0 0 10px rgba(111,227,193,0.18);
}

/* Modal "¡Nuevo poder!" */
.power-unlock-overlay {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(0,0,0,0.72); backdrop-filter: blur(6px);
  display: grid; place-items: center; padding: 24px;
}
.power-unlock-dialog {
  background: linear-gradient(160deg, #2a1a3a, #1a1228);
  border: 2px solid var(--gold); border-radius: var(--r-lg, 24px);
  box-shadow: 0 18px 50px rgba(0,0,0,0.6), 0 0 40px rgba(242,184,75,0.3);
  padding: 26px 22px; text-align: center; max-width: 340px;
  animation: winPop .5s cubic-bezier(0.34,1.56,0.55,1);
}
.power-unlock-dialog .pu-kicker { font-size: 12px; font-weight: 800; letter-spacing: 2px; color: #6fe3c1; }
.power-unlock-dialog .pu-icon { font-size: 64px; margin: 10px 0 4px; animation: char-portrait-bob 2.4s ease-in-out infinite; }
.power-unlock-dialog .pu-name { font-family: var(--font-display); color: var(--gold); margin: 4px 0; font-size: 24px; }
.power-unlock-dialog .pu-desc { color: var(--ink); font-size: 14px; margin: 6px 0 4px; line-height: 1.4; }
.power-unlock-dialog .pu-free { color: #6fe3c1; font-size: 12px; font-weight: 700; margin: 6px 0 16px; }
.reduce-motion .power-unlock-dialog,
.reduce-motion .power-unlock-dialog .pu-icon { animation: none; }

/* Cuando Comodín activo, halo en el board para feedback visual */
body.comodin-mode .board {
  box-shadow: inset 0 0 60px rgba(200,154,242,0.35), inset 0 0 30px rgba(242,184,75,0.25);
  animation: comodinFlow 3s ease-in-out infinite;
}
body.comodin-mode .board-svg .tile.free {
  filter: drop-shadow(0 0 8px rgba(200,154,242,0.5)) drop-shadow(0 3px 6px rgba(0,0,0,0.55)) !important;
}
@keyframes comodinFlow {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}

/* ────────────── result overlay ────────────── */
.overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.72); backdrop-filter: blur(6px);
  display: grid; place-items: center; z-index: 100;
  padding: 20px;
  animation: fadein .2s ease-out;
}
@keyframes fadein { from { opacity: 0; } }
.dialog {
  background: linear-gradient(180deg, #3a2354, #2a1538);
  border-radius: var(--r-lg);
  padding: 28px 24px;
  max-width: 380px; width: 100%;
  text-align: center;
  box-shadow: var(--shadow-lg);
  border: 1px solid rgba(242,184,75,0.25);
  animation: dialogin .25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes dialogin {
  from { transform: translateY(20px) scale(0.96); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.dialog h2 { margin: 0 0 6px; font-size: 26px; font-family: var(--font-display); font-weight: 900; }
.dialog p { color: var(--ink-dim); margin: 0 0 16px; font-size: 14px; }
.dialog .stars-big {
  font-size: 44px;
  letter-spacing: 10px;
  color: var(--gold);
  margin: 12px 0 16px;
  text-shadow: 0 0 24px rgba(242,184,75,0.45);
}
.dialog .row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.dialog .rewards { display: flex; gap: 12px; justify-content: center; margin: 10px 0 14px; flex-wrap: wrap; }
.dialog .rewards .chip { padding: 8px 14px; font-size: 14px; }

/* ────────────── pase ────────────── */
.pass-track { display: grid; gap: 8px; }
.pass-tier {
  background: var(--bg-elev);
  border-radius: var(--r);
  padding: 14px 16px;
  display: grid; grid-template-columns: auto 1fr 1fr; gap: 14px;
  align-items: center;
  border: 1px solid rgba(255,255,255,0.05);
}
.pass-tier .num { font-size: 22px; font-weight: 900; color: var(--gold); min-width: 32px; font-family: var(--font-display); }
.pass-tier .reward { font-size: 13px; }
.pass-tier .reward .lbl { font-size: 10px; color: var(--ink-dim); text-transform: uppercase; letter-spacing: 0.08em; display: block; margin-bottom: 1px; }
.pass-tier.claimed { opacity: 0.55; }
.pass-progress {
  background: var(--bg-elev);
  padding: 12px 16px;
  border-radius: var(--r);
  margin-bottom: 12px;
  border: 1px solid rgba(255,255,255,0.05);
}
.bar {
  background: rgba(0,0,0,0.35);
  height: 10px;
  border-radius: 999px;
  overflow: hidden;
  margin-top: 8px;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.4);
}
.bar .fill {
  background: linear-gradient(90deg, var(--gold), var(--teal));
  height: 100%;
  transition: width .35s ease-out;
  box-shadow: 0 0 12px rgba(242,184,75,0.4);
}

/* ────────────── eventos ────────────── */
.event {
  background: var(--bg-elev);
  border-radius: var(--r);
  padding: 14px 16px;
  margin-bottom: 10px;
  display: grid; gap: 4px;
  border-left: 3px solid var(--violet);
  box-shadow: var(--shadow-sm);
}
.event h3 { margin: 0; font-size: 16px; font-family: var(--font-display); font-weight: 700; }
.event .meta { font-size: 11px; color: var(--ink-dim); }
.event .reward { font-size: 12px; color: var(--gold); font-weight: 600; }

/* ────────────── toast ────────────── */
.toast {
  position: fixed; bottom: 96px; left: 50%; transform: translateX(-50%);
  background: var(--ink); color: var(--bg);
  padding: 10px 20px; border-radius: 999px;
  font-weight: 700; font-size: 13px;
  z-index: 200; box-shadow: var(--shadow-lg, var(--shadow)), 0 0 0 1px rgba(0,0,0,0.25);
  border: 1px solid rgba(255,255,255,0.18);
  animation: toastin .25s ease-out;
  max-width: calc(100% - 32px);
}
@keyframes toastin { from { opacity: 0; transform: translateX(-50%) translateY(10px); } }

/* ────────────── settings ────────────── */
.setting {
  background: var(--bg-elev);
  padding: 14px 16px;
  border-radius: var(--r);
  margin-bottom: 8px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border: 1px solid rgba(255,255,255,0.05);
}
.setting label { font-size: 14px; font-weight: 600; }
.setting .desc { font-size: 11px; color: var(--ink-dim); margin-top: 2px; }
.toggle {
  width: 46px; height: 26px;
  background: var(--bg-elev-2);
  border-radius: 999px;
  position: relative; cursor: pointer; border: 0; padding: 0;
  transition: background .15s;
}
.toggle .knob {
  position: absolute; top: 2px; left: 2px;
  width: 22px; height: 22px;
  background: var(--ink);
  border-radius: 50%;
  transition: left .15s, background .15s;
  box-shadow: 0 2px 4px rgba(0,0,0,0.4);
}
.toggle[aria-pressed="true"] { background: var(--teal); }
.toggle[aria-pressed="true"] .knob { left: 22px; background: #0e3030; }

/* ────────────── tile interaction (v∞ — animaciones "nivel dios") ──────────
   IMPORTANTE: el <g class="tile-slot"> SOLO posiciona (transform attr SVG).
   Todas las animaciones (hover, selected, match, hint, mismatch) operan
   sobre el <g class="tile"> interno con transform-box: fill-box, así CSS
   transform no destruye la posición absoluta del slot.

   Stack de animaciones por estado (cada uno aislado, no compite):
     - .tile-entering        → caída del cielo + squash + settle
     - .tile.free:hover      → lift suave con drop-shadow dinámica
     - .tile.selected        → float + idle breathing pulse infinito
     - .tile.match-burst     → anticipación pull-back + explosión rotada
     - .tile.mismatch-shake  → vibración + flash rojo + glow
     - .tile.hint            → pulso con halo dorado dramático
*/
.board-svg .tile-slot {
  /* nunca animar ni transitar el slot — sus coords son la posición real */
}
.board-svg .tile {
  /* transform-origin se inyecta por tile via inline style en game.js:
     "transform-origin: Xpx Ypx" donde X=px+TILE_W/2, Y=py+TILE_H/2
     (coordenadas SVG del centro de la cara frontal del tile).
     Motivo: transform-box:fill-box falla en Chrome para <g> — el browser
     calcula el fill-box en coords del viewport entero, no en coords locales,
     haciendo que transform-origin:center caiga en el centro del SVG completo.
     Con eso, scale(1.045) arrastra la ficha decenas de px hacia ese centro lejano.
     La solución es pasar la coordenada exacta como inline style, que gana
     sobre cualquier regla CSS y evita toda ambigüedad de coordinate space. */
  /* TRANSICIÓN BASE + DEBOUNCE (90ms):
     CRÍTICO: el delay aplica a TRANSFORM y FILTER. Si solo se debounceara
     transform, el filter (glow del drop-shadow) seguiría parpadeando cada
     vez que el browser pierde+recupera hover por sub-pixel jitter en el
     borde. 90ms cubre el jitter típico del cursor (~20-40ms) con margen.
     hover-IN debe ser 0ms (definido dentro del bloque :hover) para que
     la respuesta al pasar el mouse sea inmediata. */
  transition:
    transform .15s cubic-bezier(0.22, 0.7, 0.32, 1) 90ms,
    filter .20s ease-out 90ms;
  /* v2.25 PERF: sin promoción GPU global en la ficha base. Antes se promovía CADA
     ficha (hasta 142) a su propia capa de composición → explosión de memoria GPU
     y jank. Ahora la promoción GPU vive sola en los estados que de verdad animan
     (.selected / .match-burst). El resto del tablero queda estático. */
}

/* ─── HOVER ─── SOLO escala, NO cambio de filter.
   Aprendido a la mala: cambiar filter en hover causa flickering visible en
   los bordes entre fichas (el glow se enciende/apaga rápido por sub-pixel
   jitter del cursor). El drop-shadow de free queda fijo en .tile.free.
   Solo el scale 1.03 da feedback de hover — y con el 90ms debounce de
   transform en el estado base, no parpadea ni en el borde más fino.

   CRÍTICO — `prefers-reduced-motion: no-preference`:
   Windows/macOS pueden tener "Reduce motion" activado a nivel sistema.
   Eso dispara una regla global `*  { transition-duration: 0.01ms !important }`
   que ANULA mi debounce de 90ms — la transition se vuelve instantánea,
   y en el borde sub-pixel donde el hover toggla rápido el scale salta
   INSTANTÁNEAMENTE entre 1.0 y 1.03 (la carta "se vuelve loca").
   Solución: el hover scale SOLO aplica cuando el sistema NO pide reduce-motion.
   Para usuarios con reduce-motion, la ficha NO escala — cero animación,
   cero flicker. El feedback queda en el cursor:pointer + drop-shadow extra. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .board-svg .tile.free:hover {
    transform: scale(1.03);
    /* hover-IN sin delay — respuesta inmediata al entrar */
    transition: transform .13s cubic-bezier(0.22, 0.7, 0.32, 1) 0ms;
  }
}
/* Para reduce-motion: CERO cambios en hover. Ningún transform, ningún filter.
   El cursor:pointer + el ring de selección al hacer click son feedback suficiente.
   Cualquier cambio visual con transition-duration 0.01ms (forzado por la regla
   global de reduce-motion) genera flicker al toggle. La única solución 100%
   estable es no cambiar nada. */

/* ─── SELECTED ─── overshoot + idle breath
   Doble animación: la primera deja la ficha alzada, la segunda respira para siempre.
   Si el usuario hace match o deselecciona, la clase se quita y todo vuelve a 0. */
.board-svg .tile.selected {
  animation:
    tileSelected .34s cubic-bezier(0.34, 1.6, 0.55, 1) forwards,
    tile-breath  2.4s ease-in-out .34s infinite;
  filter: drop-shadow(0 10px 14px rgba(0, 0, 0, 0.6))
          drop-shadow(0 0 18px var(--w-accent, rgba(242, 184, 75, 0.55)));
  will-change: transform;   /* v2.25: promover SOLO la ficha activa */
}
@keyframes tileSelected {
  /* Animación más sutil: la ficha se eleva ~5px y escala 3% (antes 9px+5%).
     Menos invasiva visualmente — se siente "tocada" pero no "saltando". */
  0%   { transform: translateY(0) scale(1); }
  45%  { transform: translateY(-7px) scale(1.045); }
  72%  { transform: translateY(-3px) scale(1.015); }
  100% { transform: translateY(-5px) scale(1.03); }
}
@keyframes tile-breath {
  /* Pulso muy sutil — apenas perceptible. */
  0%, 100% { transform: translateY(-5px) scale(1.03); }
  50%      { transform: translateY(-6px) scale(1.035); }
}

/* CRÍTICO — reduce-motion: las animaciones de selected NO pueden correr.
   La regla global `*  { animation-duration: 0.01ms !important }` hace que
   `tile-breath ... infinite` corra ~100000 veces por segundo → la ficha
   "salta" sin parar al ser seleccionada. Para reduce-motion users, NO usar
   animation, sino aplicar el estado final directamente con transform.
   También deshabilitamos los rings infinite (select-ring-pulse, free-ring-pulse,
   hintPulse) que tienen el mismo problema. */
@media (prefers-reduced-motion: reduce) {
  .board-svg .tile.selected {
    animation: none !important;
    /* Elevación más sutil: 4px (antes 9px) y scale 3% (antes 5%).
       Suficiente para que se vea seleccionada sin sentir que "salta lejos". */
    transform: translateY(-4px) scale(1.03) !important;
    filter: drop-shadow(0 5px 9px rgba(0, 0, 0, 0.55))
            drop-shadow(0 0 12px rgba(242, 184, 75, 0.45)) !important;
  }
  .board-svg .tile.hint { animation: none !important; }
  .board-svg .select-ring,
  .board-svg .free-ring { animation: none !important; }
}

/* ─── REALCE DE FICHAS LIBRES (v2.19) ───
   Telegrafía qué se puede tocar AHORA (clave en juegos top). Es un glow dorado
   que respira — SOLO filter, NUNCA transform (el transform en libres reintroduce
   el flicker sub-pixel en bordes que tanto costó eliminar). El delay lo inyecta
   game.js por ficha (animation-delay inline, derivado de x/y → estable entre
   re-renders, escalonado para que el pulso no sea uniforme = se ve "vivo").
   La ficha seleccionada/hover/match tiene sus propias reglas que ganan. */
/* v2.25 PERF: el telegrafiado de fichas libres ya NO anima `filter` por ficha
   (drop-shadow repintaba cada frame × N fichas = causa #1 del trabe en celular).
   Ahora es un halo dorado <g class="free-glow"> que game.js dibuja dentro de cada
   ficha libre, cuya OPACIDAD pulsa — la opacidad se compone en GPU, no repinta →
   escala a 100+ fichas sin trabarse. El delay escalonado lo inyecta game.js. */
.board-svg .free-glow { opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .board-svg .tile.free:not(.selected):not(.match-burst) .free-glow {
    animation: freeGlowPulse 2.8s ease-in-out infinite;
  }
}
@keyframes freeGlowPulse {
  0%, 100% { opacity: 0.16; }
  50%      { opacity: 0.80; }
}
/* reduce-motion: halo fijo tenue (telegrafía sin movimiento). */
@media (prefers-reduced-motion: reduce) {
  .board-svg .free-glow { opacity: 0.42; animation: none !important; }
}

/* ─── MATCH BURST ─── anticipación + explosión + fade rotando
   Esta es la regla activa (sobreescribe la de la sección v2.6.2 más abajo
   por orden de cascada — ver match-flash). */
.board-svg .tile.match-burst {
  animation: matchBurst .58s cubic-bezier(0.32, 0, 0.18, 1) forwards;
  pointer-events: none;
  z-index: 10;
  will-change: transform;   /* v2.25: solo la ficha que explota se promueve */
}

/* match-leaving — clase nueva que NO tiene animation propia.
   La animación la maneja Web Animations API (vía el.animate() en game.js),
   que funciona INDEPENDIENTE del CSS reduce-motion global.
   Esta clase solo aporta los efectos estáticos: no clickable, encima de otras fichas. */
.board-svg .tile.match-leaving {
  pointer-events: none;
  z-index: 10;
}
@keyframes matchBurst {
  0%   { transform: scale(1) rotate(0deg); opacity: 1;
         filter: brightness(1) saturate(1); }
  15%  { transform: scale(0.92) rotate(-3deg); opacity: 1;
         filter: brightness(1.45) saturate(1.4)
                 drop-shadow(0 0 8px rgba(111, 227, 193, 0.6)); }
  38%  { transform: scale(1.42) rotate(2deg); opacity: 1;
         filter: brightness(2.6) saturate(2.4)
                 drop-shadow(0 0 28px #ffd76a)
                 drop-shadow(0 0 14px #6fe3c1); }
  64%  { transform: scale(1.18) rotate(10deg) translateY(2px); opacity: 0.7;
         filter: brightness(2) saturate(1.8)
                 drop-shadow(0 0 18px #f2b84b); }
  100% { transform: scale(0.32) rotate(28deg) translateY(10px); opacity: 0;
         filter: brightness(1.2) saturate(1); }
}

/* ─── HINT ─── pulso con halo dorado dramático */
.board-svg .tile.hint {
  animation: hintPulse 1.05s ease-in-out infinite;
}
@keyframes hintPulse {
  0%, 100% { transform: scale(1);
             filter: brightness(1) saturate(1); }
  50%      { transform: scale(1.075);
             filter: brightness(1.4) saturate(1.3)
                     drop-shadow(0 0 22px #f2b84b)
                     drop-shadow(0 0 8px #ffd76a); }
}

.match-particle {
  position: fixed;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: radial-gradient(circle, #f2b84b, #c46a2a);
  pointer-events: none;
  z-index: 200;
  animation: particleFly .6s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}
@keyframes particleFly {
  0% {
    transform: translate(-50%, -50%) scale(0.6);
    opacity: 1;
  }
  100% {
    transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(0);
    opacity: 0;
  }
}

/* ────────────── floating score & combo ────────────── */
.match-float-score {
  position: fixed;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 220;
  font-family: 'Fraunces', ui-serif, Georgia, serif;
  font-weight: 900;
  font-size: 32px;
  color: #f2b84b;
  text-shadow:
    0 0 8px rgba(242, 184, 75, 0.8),
    0 2px 4px rgba(0, 0, 0, 0.6),
    -1px -1px 0 #5a2548;
  letter-spacing: 0.5px;
  animation: floatScore 1.1s cubic-bezier(0.215, 0.61, 0.355, 1) forwards;
}
.match-float-score.combo {
  font-size: 28px;
  color: #6fe3c1;
  text-shadow:
    0 0 12px rgba(111, 227, 193, 0.95),
    0 2px 4px rgba(0, 0, 0, 0.7),
    -1px -1px 0 #1a4a35;
}
@keyframes floatScore {
  0%   { transform: translate(-50%, -50%) scale(0.6); opacity: 0; }
  20%  { transform: translate(-50%, -55%) scale(1.15); opacity: 1; }
  60%  { transform: translate(-50%, -85%) scale(1); opacity: 1; }
  100% { transform: translate(-50%, -115%) scale(0.85); opacity: 0; }
}

/* Screen shake en combos altos */
.shake {
  animation: shake 0.3s cubic-bezier(.36,.07,.19,.97) both;
}
@keyframes shake {
  10%, 90% { transform: translate3d(-1px, 0, 0); }
  20%, 80% { transform: translate3d(2px, 0, 0); }
  30%, 50%, 70% { transform: translate3d(-3px, 0, 0); }
  40%, 60% { transform: translate3d(3px, 0, 0); }
}

/* ────────────── win overlay celebration ────────────── */
.win-overlay {
  position: fixed; inset: 0;
  background: rgba(14, 4, 24, 0.85);
  backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
  animation: fadeIn 0.3s ease-out;
}
@keyframes fadeIn {
  from { opacity: 0; } to { opacity: 1; }
}

.win-dialog {
  position: relative;
  background: linear-gradient(160deg, #2d1840 0%, #5a2548 60%, #3a1f5a 100%);
  border: 2px solid #f2b84b;
  border-radius: 20px;
  padding: 32px 40px;
  max-width: 360px;
  text-align: center;
  box-shadow:
    0 0 60px rgba(242, 184, 75, 0.4),
    0 20px 40px rgba(0, 0, 0, 0.5),
    inset 0 0 0 1px rgba(255, 255, 255, 0.1);
  animation: winPop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
  overflow: hidden;
}
@keyframes winPop {
  0%   { transform: scale(0.7) translateY(40px); opacity: 0; }
  60%  { transform: scale(1.05) translateY(-5px); opacity: 1; }
  100% { transform: scale(1) translateY(0); opacity: 1; }
}

/* Rayos detrás del título */
.win-rays {
  position: absolute;
  top: -50%; left: 50%;
  width: 600px; height: 600px;
  transform: translateX(-50%);
  background:
    conic-gradient(
      from 0deg,
      rgba(242, 184, 75, 0.2) 0deg,
      transparent 30deg,
      rgba(242, 184, 75, 0.15) 60deg,
      transparent 90deg,
      rgba(242, 184, 75, 0.2) 120deg,
      transparent 150deg,
      rgba(242, 184, 75, 0.18) 180deg,
      transparent 210deg,
      rgba(242, 184, 75, 0.2) 240deg,
      transparent 270deg,
      rgba(242, 184, 75, 0.15) 300deg,
      transparent 330deg,
      rgba(242, 184, 75, 0.2) 360deg
    );
  animation: rayRotate 12s linear infinite;
  pointer-events: none;
  opacity: 0.6;
}
@keyframes rayRotate {
  to { transform: translateX(-50%) rotate(360deg); }
}

.win-title {
  position: relative;
  margin: 0 0 4px;
  font-family: 'Fraunces', ui-serif, Georgia, serif;
  font-weight: 900;
  font-size: 26px;
  color: #f2b84b;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
  letter-spacing: 0.5px;
}
.win-sub {
  position: relative;
  margin: 0 0 18px;
  font-size: 13px;
  color: #dfd8c4;
  opacity: 0.85;
}

.stars-big {
  position: relative;
  font-size: 56px;
  letter-spacing: 8px;
  margin: 18px 0 14px;
  line-height: 1;
}
.star-slot {
  display: inline-block;
  color: rgba(255, 255, 255, 0.2);
  transition: color 0.2s;
}
.star-slot.star-pop {
  color: #f2b84b;
  text-shadow: 0 0 14px #f2b84b, 0 0 28px rgba(242, 184, 75, 0.6);
  animation: starPop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes starPop {
  0%   { transform: scale(0.3) rotate(-30deg); }
  60%  { transform: scale(1.3) rotate(8deg); }
  100% { transform: scale(1) rotate(0); }
}

.win-rewards {
  position: relative;
  display: flex; gap: 10px; justify-content: center;
  margin: 14px 0;
}
.win-rewards .chip {
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(242, 184, 75, 0.4);
  padding: 8px 14px;
  border-radius: 20px;
  font-weight: 700;
  font-size: 14px;
  color: #f2b84b;
}
/* v2.30 — BONUS SORPRESA (recompensa variable) */
.surprise-bonus {
  margin: -4px auto 10px; text-align: center; font-weight: 800; font-size: 14px;
  color: #fff; padding: 7px 16px; border-radius: 999px; display: inline-block;
  background: linear-gradient(100deg, #c41e5a, #f2b84b);
  box-shadow: 0 4px 16px rgba(242,184,75,0.5);
  animation: surpriseIn .5s cubic-bezier(0.34,1.56,0.64,1) .9s both;
}
.surprise-bonus b { color: #fff8e0; }
@keyframes surpriseIn { 0% { transform: scale(0) rotate(-8deg); opacity: 0; } 100% { transform: scale(1) rotate(0); opacity: 1; } }
/* v2.30 — "estás por llegar a algo": teaser de próxima meta con barra de progreso */
.win-next-goal {
  margin: 4px auto 14px; max-width: 320px; text-align: center;
  background: rgba(0,0,0,0.28); border: 1px solid rgba(255,255,255,0.12);
  border-radius: 14px; padding: 10px 14px;
}
.win-next-goal.big { border-color: rgba(242,184,75,0.55); box-shadow: 0 0 18px rgba(242,184,75,0.25); }
.wng-text { font-size: 13px; color: var(--ink); margin-bottom: 8px; }
.wng-text b { color: #f2b84b; }
.wng-icon { font-size: 16px; }
.wng-bar { height: 8px; border-radius: 999px; background: rgba(255,255,255,0.12); overflow: hidden; }
.wng-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, #f2b84b, #ffd76a);
  box-shadow: 0 0 8px rgba(242,184,75,0.6);
  animation: wngGrow .9s cubic-bezier(0.3,0.8,0.4,1) 1.1s both;
  transform-origin: left;
}
@keyframes wngGrow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* v2.33 — COHERENCIA DE PUNTOS: el puntaje del HUD se convierte en monedas y se ve. */
.win-score { color: #ffd76a; font-weight: 800; }
.score-convert {
  margin: 2px auto 10px; display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 700; color: #e8dcc0;
  background: rgba(0,0,0,0.26); border: 1px solid rgba(255,255,255,0.12);
  padding: 5px 13px; border-radius: 999px;
  animation: scoreConvIn .5s cubic-bezier(0.34,1.56,0.64,1) 1.0s both;
}
.score-convert .sc-pts { color: #cbbfe6; }
.score-convert .sc-arrow { color: #f2b84b; font-weight: 900; }
.score-convert b { color: #ffd76a; display: inline-flex; align-items: center; gap: 3px; }
.score-convert .ico-coin { width: 15px; height: 15px; vertical-align: -2px; }
@keyframes scoreConvIn { 0% { transform: translateY(8px); opacity: 0; } 100% { transform: translateY(0); opacity: 1; } }

/* v2.33 — CELEBRACIÓN ESCALADA: 3★ enciende rayos y borde dorados; 2★ intermedio. */
.win-dialog.win-perfect { border-color: #ffd76a; box-shadow: 0 0 80px rgba(255,215,106,0.55), 0 20px 40px rgba(0,0,0,0.5), inset 0 0 0 1px rgba(255,255,255,0.14); }
.win-dialog.win-perfect .win-rays { opacity: 0.95; animation-duration: 8s; }
.win-dialog.win-perfect .win-title { color: #ffe39a; text-shadow: 0 0 18px rgba(255,215,106,0.7), 0 2px 4px rgba(0,0,0,0.5); animation: perfectThrob 1.6s ease-in-out infinite; }
.win-dialog.win-great .win-rays { opacity: 0.75; }
@keyframes perfectThrob { 0%,100% { transform: scale(1); } 50% { transform: scale(1.05); } }

/* v2.33 — conteo "tragamonedas": el chip late mientras suma y da un pop al aterrizar. */
/* v2.34 (#36) — ciclo COMPLETO (1→1.07→1) sin `alternate`: cada vuelta termina en
   scale(1), así al quitar la clase `.counting` (fin del conteo) no hay micro-salto. */
.win-rewards .chip.coins.counting { animation: coinCount .3s ease-in-out infinite; }
.win-rewards .chip.coins.coin-landed { animation: coinLand .5s cubic-bezier(0.34,1.56,0.64,1); }
@keyframes coinCount { 0% { transform: scale(1); } 50% { transform: scale(1.07); } 100% { transform: scale(1); } }
@keyframes coinLand {
  0% { transform: scale(1.18);  }
  100% { transform: scale(1);  }
}

/* v2.34 — COFRE DE HITO (cada 10 niveles, recompensa REAL). Mismo lenguaje visual
   que el bonus sorpresa pero en clave "cofre" (verde→oro). */
.milestone-bonus {
  margin: -2px auto 10px; text-align: center; font-weight: 800; font-size: 14px;
  color: #fff; padding: 7px 16px; border-radius: 999px; display: inline-block;
  background: linear-gradient(100deg, #1f8a5a, #f2b84b);
  box-shadow: 0 4px 16px rgba(31,138,90,0.45);
  animation: surpriseIn .5s cubic-bezier(0.34,1.56,0.64,1) both;
}
.milestone-bonus b { color: #fff8e0; }
.milestone-bonus .ico-coin { width: 16px; height: 16px; vertical-align: -3px; }

/* v2.35 — RACHA DE SESIÓN (niveles ganados seguidos). Clave "fuego". */
.streak-bonus {
  margin: -2px auto 10px; text-align: center; font-weight: 800; font-size: 14px;
  color: #fff; padding: 7px 16px; border-radius: 999px; display: inline-block;
  background: linear-gradient(100deg, #d23b1e, #f2b84b);
  box-shadow: 0 4px 16px rgba(210,59,30,0.45);
  animation: surpriseIn .5s cubic-bezier(0.34,1.56,0.64,1) both;
}
.streak-bonus b { color: #fff8e0; }
.streak-bonus .ico-coin { width: 16px; height: 16px; vertical-align: -3px; }

/* v2.36 — día-HITO de la escalera de racha (cofre del 3er día, etc.): resalta. */
.streak-day.milestone {
  background: linear-gradient(160deg, rgba(242,184,75,0.25), rgba(31,138,90,0.18));
  border: 1px solid rgba(242,184,75,0.6);
  box-shadow: 0 0 12px rgba(242,184,75,0.25);
}
.streak-day.milestone .streak-reward { font-size: 17px; }

/* v2.36 — puntaje en el HUD del Triple (paridad con el clásico). */
.tt-hud-score {
  display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: 999px;
  background: rgba(0,0,0,0.28); color: #ffd76a; font-weight: 800; font-size: 12px;
  vertical-align: middle;
}

/* v2.36 — MARCOS cosméticos del tablero (sink de monedas). Borde del board según el
   marco equipado (body[data-marco]). Solo box-shadow → barato, sin reflow. */
body[data-marco="marco_inti"]     #board { box-shadow: 0 0 0 3px #f2b84b inset, 0 0 22px rgba(242,184,75,0.45); border-radius: 14px; }
body[data-marco="marco_quebrada"] #board { box-shadow: 0 0 0 3px #6fe3c1 inset, 0 0 22px rgba(111,227,193,0.40); border-radius: 14px; }
body[data-marco="marco_carnaval"] #board { box-shadow: 0 0 0 3px #f2569b inset, 0 0 22px rgba(242,86,155,0.40);  border-radius: 14px; }
body[data-marco="marco_condor"]   #board { box-shadow: 0 0 0 3px #c89af2 inset, 0 0 26px rgba(200,154,242,0.50); border-radius: 14px; }

/* v2.37 — RAREZA de cofres: cada cofre se distingue por color (borde + etiqueta) y los
   listos brillan. Antes todos se veían iguales (🎁/🔒) y no se sabía cuál abrir-ya. */
.chest-slot { border: 1.5px solid var(--chest-col, rgba(242,184,75,0.45)) !important; position: relative; }
.chest-slot.ready { box-shadow: 0 0 14px var(--chest-col, #f2b84b); }
.chest-slot .chest-ico { position: relative; display: inline-block; }
.chest-slot .chest-lock { position: absolute; right: -7px; bottom: -5px; font-size: 0.48em; opacity: 0.85; }
.chest-rarity { font-size: 9.5px; font-weight: 800; color: var(--chest-col, #f2b84b); opacity: 0.95; margin: 1px 0 2px; text-transform: uppercase; letter-spacing: 0.4px; }

/* v2.34 — SALIDA COHERENTE: "lo que entra animado, se va animado". Estas clases las
   agrega dismissEl()/toast.js justo antes de eliminar el nodo (sólo si NO hay
   reduce-motion → el JS quita al instante en ese caso). Todo transform/opacity (GPU). */
.overlay-out { animation: overlayFadeOut .26s ease-in forwards !important; }
@keyframes overlayFadeOut { to { opacity: 0; } }
.overlay-out .dialog,
.overlay-out [class*="-dialog"] { animation: dialogScaleOut .26s ease-in forwards !important; }
@keyframes dialogScaleOut { to { transform: scale(0.92) translateY(16px); opacity: 0; } }
.stuck-bar.stuck-bar-out { animation: stuckBarOut .24s ease-in forwards !important; }
@keyframes stuckBarOut { to { transform: translateY(110%); opacity: 0; } }
.vision-countdown.vision-countdown-out { animation: visionCdOut .22s ease-in forwards !important; }
@keyframes visionCdOut { to { transform: translateY(-12px) scale(0.85); opacity: 0; } }
.booster-armed-badge.armed-badge-out { animation: armedBadgeOut .2s ease-in forwards !important; }
@keyframes armedBadgeOut { to { transform: translateY(10px); opacity: 0; } }
.toast.toast-out { animation: toastOut .2s ease-in forwards !important; }
@keyframes toastOut { to { transform: translateY(-10px); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .surprise-bonus, .wng-fill, .score-convert, .milestone-bonus, .streak-bonus,
  .win-dialog.win-perfect .win-title,
  .win-rewards .chip.coins.counting, .win-rewards .chip.coins.coin-landed { animation: none !important; }
}

.win-dialog .row {
  position: relative;
  display: flex; gap: 10px; margin-top: 16px;
}
.win-dialog .row .btn {
  flex: 1;
}

/* Confetti */
.confetti-layer {
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 101;
  overflow: hidden;
}
.confetti {
  position: absolute;
  top: -20px;
  width: 8px; height: 14px;
  border-radius: 2px;
  animation: confettiFall ease-out forwards;
  --drift: 0px;
}
@keyframes confettiFall {
  0%   { transform: translateY(0) translateX(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(110vh) translateX(var(--drift)) rotate(720deg); opacity: 0; }
}

/* Score chip en HUD */
.hud-stat.score .v {
  color: #f2b84b;
  font-weight: 900;
  text-shadow: 0 0 8px rgba(242, 184, 75, 0.4);
}

/* ────────────── splash screen ────────────── */
.splash {
  position: fixed;
  inset: 0;
  background: radial-gradient(ellipse at center, #3a1f5a 0%, #1a0820 60%, #0e0418 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
.splash.splash-hide {
  opacity: 0;
  transform: scale(1.05);
  pointer-events: none;
}
.splash-inner {
  text-align: center;
  animation: splashFadeIn 0.8s ease-out;
}
@keyframes splashFadeIn {
  0%   { opacity: 0; transform: translateY(20px); }
  100% { opacity: 1; transform: translateY(0); }
}
.splash-logo {
  width: 140px;
  height: 140px;
  filter: drop-shadow(0 8px 24px rgba(242, 184, 75, 0.4));
  animation: splashLogoFloat 2.4s ease-in-out infinite;
}
@keyframes splashLogoFloat {
  0%, 100% { transform: translateY(0) rotate(-2deg); }
  50%      { transform: translateY(-6px) rotate(2deg); }
}
.splash-title {
  margin: 16px 0 4px;
  font-family: 'Fraunces', ui-serif, Georgia, serif;
  font-weight: 900;
  font-size: 36px;
  color: #f2b84b;
  letter-spacing: 1px;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}
.splash-subtitle {
  margin: 0 0 24px;
  font-family: 'Fraunces', ui-serif, Georgia, serif;
  font-weight: 400;
  font-style: italic;
  font-size: 22px;
  color: #dfd8c4;
  letter-spacing: 4px;
  opacity: 0.85;
}
.splash-loader {
  width: 180px;
  height: 4px;
  margin: 0 auto;
  background: rgba(242, 184, 75, 0.2);
  border-radius: 2px;
  overflow: hidden;
}
.splash-loader-bar {
  height: 100%;
  background: linear-gradient(90deg, transparent, #f2b84b, transparent);
  animation: loaderSweep 1.4s ease-in-out infinite;
}
@keyframes loaderSweep {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(280%); }
}

/* ────────────── page transitions ────────────── */
.page-fade-out {
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 0.12s ease-out, transform 0.12s ease-out;
}
.page-fade-in {
  animation: pageIn 0.28s ease-out;
}
@keyframes pageIn {
  0%   { opacity: 0; transform: translateY(12px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* ────────────── navbar SVG icons ────────────── */
.navbar .nav-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  color: var(--ink-dim, #a89568);
  transition: color 0.2s, transform 0.15s;
}
.navbar .nav-btn svg {
  stroke: currentColor;
}
.navbar .nav-btn[aria-current="page"] {
  color: #f2b84b;
  transform: translateY(-2px);
}
.navbar .nav-btn[aria-current="page"] svg {
  filter: drop-shadow(0 0 8px rgba(242, 184, 75, 0.5));
}
.navbar .nav-btn small {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.3px;
}

/* ────────────── hero ────────────── */
.hero {
  position: relative;
  padding: 24px 20px 22px;
  border-radius: 18px;
  background: linear-gradient(135deg, #2d1840 0%, #5a2548 60%, #3a1f5a 100%);
  border: 2px solid rgba(242, 184, 75, 0.3);
  overflow: hidden;
  margin-bottom: 16px;
}
.hero::before {
  content: '';
  position: absolute;
  top: -40%;
  right: -20%;
  width: 200px;
  height: 200px;
  background: radial-gradient(circle, rgba(242, 184, 75, 0.25) 0%, transparent 70%);
  pointer-events: none;
}
.hero h1 {
  position: relative;
  margin: 0 0 4px;
  font-family: 'Fraunces', ui-serif, Georgia, serif;
  font-weight: 900;
  font-size: 28px;
  color: #f2b84b;
}
.hero-sub {
  position: relative;
  margin: 0 0 14px;
  font-size: 13px;
  color: #dfd8c4;
  opacity: 0.85;
}
.hero .row {
  position: relative;
}

/* ────────────── home stat cards ────────────── */
.stat-card {
  display: flex;
  flex-direction: column;
  background: rgba(36, 17, 73, 0.6);
  border: 1px solid rgba(242, 184, 75, 0.15);
  padding: 12px 14px;
  border-radius: 12px;
  transition: transform 0.2s, border-color 0.2s;
}
.stat-card:hover {
  border-color: rgba(242, 184, 75, 0.4);
  transform: translateY(-2px);
}
.stat-card .k {
  font-size: 11px;
  color: var(--ink-dim, #a89568);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 4px;
}
.stat-card .v {
  font-family: 'Fraunces', ui-serif, Georgia, serif;
  font-size: 24px;
  font-weight: 900;
  color: #fef7e3;
}
.stat-card .frac {
  font-size: 14px;
  color: var(--ink-dim, #a89568);
  font-weight: 600;
}

/* ────────────── daily challenge section ────────────── */
.daily-section {
  margin-top: 18px;
}
.daily-section .section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}
.daily-section h2 {
  font-family: 'Fraunces', ui-serif, Georgia, serif;
  font-weight: 700;
  font-size: 19px;
  color: #f2b84b;
  margin: 0;
}
.section-sub {
  font-size: 12px;
  color: var(--ink-dim, #a89568);
  margin: 0 0 10px;
}
.timer {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 13px;
  color: #6fe3c1;
  background: rgba(111, 227, 193, 0.1);
  padding: 4px 10px;
  border-radius: 8px;
  font-variant-numeric: tabular-nums;
}

.daily-card {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 12px;
  background: linear-gradient(135deg, #2d1840, #3a1f5a);
  border: 1px solid rgba(242, 184, 75, 0.25);
  padding: 14px 16px;
  border-radius: 12px;
  transition: border-color 0.2s, transform 0.2s;
}
/* v2.19 — fila de cofres temporizados */
.chest-row { display: flex; gap: 10px; overflow-x: auto; padding: 2px; scrollbar-width: none; }
.chest-row::-webkit-scrollbar { display: none; }
.chest-slot {
  flex: 0 0 auto; width: 96px; text-align: center;
  background: linear-gradient(160deg, #2d1840, #1a1228);
  border: 1px solid rgba(242,184,75,0.25); border-radius: var(--r);
  padding: 12px 8px; display: grid; gap: 6px; justify-items: center;
}
.chest-slot.ready { border-color: var(--gold); box-shadow: 0 0 14px rgba(242,184,75,0.35); animation: chestReadyPulse 1.8s ease-in-out infinite; }
.chest-slot .chest-ico { font-size: 34px; line-height: 1; }
.chest-slot.ready .chest-ico { animation: char-portrait-bob 1.6s ease-in-out infinite; }
.chest-slot .chest-state { font-size: 11px; color: var(--ink-dim); font-weight: 700; }
.chest-slot.ready .chest-state { color: var(--gold); }
@keyframes chestReadyPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}
.reduce-motion .chest-slot.ready,
.reduce-motion .chest-slot.ready .chest-ico { animation: none; }
.daily-card:hover {
  border-color: rgba(242, 184, 75, 0.5);
  transform: translateY(-2px);
}
.daily-card.done {
  opacity: 0.65;
}
.daily-info strong {
  color: #fef7e3;
  font-weight: 700;
  font-size: 15px;
  display: block;
}
.daily-info .daily-meta {
  font-size: 12px;
  color: var(--ink-dim, #a89568);
  margin-top: 2px;
}

.btn.gold {
  background: linear-gradient(135deg, #f2b84b, #c46a2a);
  color: #0e0418;
  font-weight: 800;
  border: none;
  box-shadow: 0 4px 14px rgba(242, 184, 75, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
.btn.gold:hover {
  filter: brightness(1.08);
}

/* ────────────── streak ladder ────────────── */
.streak-ladder {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}
.streak-day {
  background: rgba(36, 17, 73, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 10px;
  padding: 8px 4px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  transition: all 0.2s;
}
.streak-day .streak-num {
  font-family: 'Fraunces', serif;
  font-weight: 700;
  font-size: 18px;
  color: var(--ink-dim, #a89568);
}
.streak-day .streak-reward {
  font-size: 10px;
  color: var(--ink-dim, #a89568);
  font-weight: 600;
}
.streak-day.reached {
  background: linear-gradient(135deg, rgba(111, 227, 193, 0.18), rgba(111, 227, 193, 0.05));
  border-color: rgba(111, 227, 193, 0.45);
}
.streak-day.reached .streak-num {
  color: #6fe3c1;
}
.streak-day.today {
  background: linear-gradient(135deg, rgba(242, 184, 75, 0.25), rgba(242, 184, 75, 0.08));
  border-color: #f2b84b;
  animation: streakTodayPulse 2s ease-in-out infinite;
}
.streak-day.today .streak-num {
  color: #f2b84b;
  text-shadow: 0 0 8px rgba(242, 184, 75, 0.6);
}
@keyframes streakTodayPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}

/* ────────────── trail (sendero) en mapa ────────────── */
.world-header {
  margin-bottom: 12px;
}
.world-title {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}
.world-icon {
  font-size: 32px;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
}
.world-title h3 {
  margin: 0;
  font-family: 'Fraunces', serif;
  font-size: 19px;
  color: #f2b84b;
}
.world-role {
  margin: 2px 0 0;
  font-size: 11px;
  color: var(--ink-dim, #a89568);
}
.world-progress {
  background: rgba(0, 0, 0, 0.25);
  padding: 8px 12px;
  border-radius: 8px;
}
.world-progress.locked {
  text-align: center;
  padding: 12px;
}
.lock-badge {
  color: var(--ink-dim, #a89568);
  font-size: 12px;
  font-style: italic;
}
.progress-bar {
  height: 6px;
  background: rgba(255, 255, 255, 0.08);
  border-radius: 3px;
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #6fe3c1, #f2b84b);
  border-radius: 3px;
  transition: width 0.4s ease-out;
}
.progress-meta {
  display: flex;
  justify-content: space-between;
  margin-top: 4px;
  font-size: 11px;
  color: var(--ink-dim, #a89568);
}

.trail-container {
  background: linear-gradient(180deg, rgba(36, 17, 73, 0.35), rgba(36, 17, 73, 0.15));
  border-radius: 14px;
  padding: 10px;
  margin-top: 10px;
  overflow-x: auto;
}
.trail-svg {
  display: block;
  margin: 0 auto;
  max-width: 100%;
}
.trail-node {
  transition: transform 0.2s;
}
.trail-node:not(.locked):hover {
  transform: scale(1.08);
  transform-origin: center;
}
.trail-node.current circle:first-of-type ~ circle {
  filter: drop-shadow(0 0 8px #f2b84b);
}
/* v2.29 — CÁMARA del sendero: foco en tu zona + mini-metas (cofres) + avatar */
.trail-node.far { opacity: 0.4; transition: opacity .35s ease; }   /* lejanos atenuados → resalta tu zona */
.milestone-marker { transform-box: fill-box; transform-origin: center; }
.milestone-marker.next { animation: msNextPulse 1.3s ease-in-out infinite; }
@keyframes msNextPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.45; } }
.milestone-marker.done { opacity: 0.85; }
.map-avatar { animation: mapAvatarBob 1.8s ease-in-out infinite; }
@keyframes mapAvatarBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) {
  .milestone-marker.next, .map-avatar { animation: none !important; }
}

.world {
  background: linear-gradient(180deg, rgba(36, 17, 73, 0.4), rgba(36, 17, 73, 0.2));
  border: 1px solid rgba(242, 184, 75, 0.15);
  border-radius: 14px;
  padding: 14px;
  margin-bottom: 16px;
}

/* ────────────── galería ────────────── */
.gallery-progress {
  margin: 10px 0 6px;
}
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(98px, 1fr));
  gap: 10px;
  background: rgba(14, 4, 24, 0.4);
  padding: 12px;
  border-radius: 12px;
}
.gallery-item {
  background: rgba(36, 17, 73, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 10px;
  padding: 8px;
  text-align: center;
  position: relative;
  transition: transform 0.2s, border-color 0.2s;
}
.gallery-item.unlocked {
  border-color: rgba(242, 184, 75, 0.3);
}
.gallery-item.unlocked:hover {
  transform: translateY(-3px) scale(1.03);
  border-color: #f2b84b;
}
.gallery-item.locked {
  opacity: 0.5;
  filter: grayscale(1) brightness(0.7);   /* v2.19: bloqueada = apagada, no solo translúcida */
}
.gallery-item.unlocked { transition: transform .12s ease, box-shadow .15s ease; }
.gallery-item.unlocked:hover { transform: translateY(-3px) scale(1.03); box-shadow: 0 6px 16px rgba(0,0,0,0.4), 0 0 0 1px var(--gold); }
.reduce-motion .gallery-item.unlocked:hover { transform: none; }
.gallery-item img {
  width: 80px;
  height: 100px;
  display: block;
  margin: 0 auto 4px;
}
.gallery-item .gallery-locked {
  width: 80px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 36px;
  color: rgba(255, 255, 255, 0.2);
  margin: 0 auto 4px;
}
/* v20 — Museo: ícono grande de la reliquia (reusa la grilla de galería). */
.museum-item .relic-icon {
  width: 80px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 46px;
  margin: 0 auto 4px;
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.45));
}
.gallery-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  color: #fef7e3;
}
.gallery-rarity {
  display: inline-block;
  margin-top: 4px;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.rarity-common    { background: rgba(168, 149, 104, 0.3); color: #d4b878; }
.rarity-rare      { background: rgba(111, 227, 193, 0.25); color: #6fe3c1; }
.rarity-epic      { background: rgba(200, 154, 242, 0.25); color: #c89af2; }
.rarity-legendary { background: rgba(242, 184, 75, 0.25); color: #f2b84b; }

/* ────────────── home quick links ────────────── */
.quick-links {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.quick-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 14px 8px;
  background: linear-gradient(135deg, #2d1840, #3a1f5a);
  border: 1px solid rgba(242, 184, 75, 0.2);
  border-radius: 12px;
  color: #fef7e3;
  cursor: pointer;
  transition: all 0.2s;
}
.quick-link:hover {
  border-color: #f2b84b;
  transform: translateY(-2px);
}
.quick-link .ql-icon { font-size: 26px; }
.quick-link .ql-label {
  font-weight: 700;
  font-size: 13px;
  color: #fef7e3;
}
.quick-link .ql-meta {
  font-size: 10px;
  color: var(--ink-dim, #a89568);
  font-weight: 600;
}
.quick-link .ql-meta.live-dot {
  color: #6fe3c1;
  animation: livePulse 1.8s ease-in-out infinite;
}
@keyframes livePulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

/* ────────────── pase andino visual ────────────── */
.pass-header { margin-bottom: 12px; }
.section-h2 {
  font-family: 'Fraunces', ui-serif, Georgia, serif;
  font-weight: 700;
  font-size: 19px;
  color: #f2b84b;
  margin: 22px 0 12px;
}
.pass-progress-card {
  background: linear-gradient(135deg, #2d1840, #3a1f5a);
  border: 2px solid rgba(242, 184, 75, 0.3);
  border-radius: 14px;
  padding: 14px 16px;
  margin-bottom: 14px;
}
.pass-progress-info {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin-bottom: 10px;
}
.pass-tier-current {
  font-family: 'Fraunces', serif;
  font-weight: 900;
  font-size: 28px;
  color: #f2b84b;
}
.pass-xp {
  font-size: 12px;
  color: var(--ink-dim, #a89568);
  margin-top: -4px;
}
.pass-next {
  font-size: 12px;
  color: #6fe3c1;
}
.pass-bar {
  height: 10px;
  background: rgba(0, 0, 0, 0.4);
  border-radius: 5px;
  overflow: hidden;
}
.pass-fill {
  height: 100%;
  background: linear-gradient(90deg, #f2b84b, #c46a2a);
  border-radius: 5px;
  transition: width 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.pass-premium-cta {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px;
  align-items: center;
  background: linear-gradient(135deg, #5a2548, #3a1f5a);
  border: 2px solid #f2b84b;
  border-radius: 14px;
  padding: 14px 16px;
  margin-bottom: 16px;
  box-shadow: 0 0 20px rgba(242, 184, 75, 0.2);
}
.pass-premium-cta .cta-content strong {
  display: block;
  color: #f2b84b;
  font-size: 16px;
  margin-bottom: 4px;
}
.pass-premium-cta .cta-content p {
  margin: 0;
  font-size: 12px;
  color: var(--ink-dim, #a89568);
}
.pass-premium-active {
  background: linear-gradient(135deg, rgba(242, 184, 75, 0.15), rgba(200, 154, 242, 0.15));
  border: 1px solid #f2b84b;
  border-radius: 10px;
  padding: 10px 14px;
  text-align: center;
  font-size: 13px;
  color: #f2b84b;
  margin-bottom: 14px;
}

.pass-track-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.pass-tier-card {
  display: grid;
  grid-template-columns: 50px 1fr 1fr;
  gap: 10px;
  align-items: center;
  background: rgba(36, 17, 73, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px;
  padding: 10px 12px;
  transition: border-color 0.2s, background 0.2s;
}
.pass-tier-card.earned {
  border-color: rgba(111, 227, 193, 0.45);
  background: linear-gradient(135deg, rgba(111, 227, 193, 0.05), rgba(36, 17, 73, 0.5));
}
.pass-tier-card.current {
  border-color: #f2b84b;
  background: linear-gradient(135deg, rgba(242, 184, 75, 0.1), rgba(36, 17, 73, 0.5));
}
.pass-tier-card.claimed {
  opacity: 0.6;
}
.pass-tier-num {
  text-align: center;
  font-family: 'Fraunces', serif;
  font-size: 22px;
  font-weight: 900;
  color: #f2b84b;
}
.pass-tier-reward {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  position: relative;
}
.pass-tier-reward.locked .tier-value { opacity: 0.4; }
.pass-tier-reward .tier-label {
  display: block;
  font-size: 9px;
  color: var(--ink-dim, #a89568);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-weight: 700;
}
.pass-tier-reward .tier-value {
  color: #fef7e3;
  font-weight: 600;
}
.btn-pico {
  background: linear-gradient(135deg, #f2b84b, #c46a2a);
  color: #0e0418;
  border: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  font-weight: 900;
  font-size: 14px;
  cursor: pointer;
  margin-left: 4px;
}
.claimed-mark {
  color: #6fe3c1;
  font-weight: 900;
  font-size: 14px;
  margin-left: 4px;
}

/* ────────────── events redesign ────────────── */
.events-header { margin-bottom: 16px; }
.event-card-v2 {
  background: linear-gradient(135deg, #2d1840, #3a1f5a);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-left: 4px solid #c46a2a;
  border-radius: 14px;
  padding: 14px 16px;
  margin-bottom: 14px;
  transition: transform 0.2s;
}
.event-card-v2:hover { transform: translateX(2px); }
.event-card-header {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-bottom: 10px;
}
.event-icon-big {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  border: 2px solid;
}
.event-card-title h3 {
  margin: 0 0 4px;
  font-family: 'Fraunces', serif;
  font-size: 17px;
  color: #fef7e3;
}
.event-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 2px 8px;
  border-radius: 4px;
}
.event-badge.live {
  background: linear-gradient(135deg, #c41e3a, #8b3a4a);
  color: #fef7e3;
  animation: livePulse 1.8s ease-in-out infinite;
}
.event-badge.soon { background: rgba(242, 184, 75, 0.25); color: #f2b84b; }
.event-badge.upcoming { background: rgba(168, 149, 104, 0.25); color: #a89568; }
.event-narrative {
  margin: 0 0 10px;
  font-size: 13px;
  color: #dfd8c4;
  font-style: italic;
  line-height: 1.5;
}
.event-meta-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  font-size: 11px;
}
.event-timer { color: #6fe3c1; font-family: 'IBM Plex Mono', monospace; }
.event-participants { color: var(--ink-dim, #a89568); }
.event-rewards {
  margin: 10px 0;
}
.event-rewards-label {
  font-size: 11px;
  color: var(--ink-dim, #a89568);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 4px;
}
.event-reward-chip {
  display: inline-block;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(242, 184, 75, 0.3);
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 12px;
  margin: 0 4px 4px 0;
  color: #f2b84b;
}
.event-action { width: 100%; margin-top: 6px; }
.events-footer { margin-top: 14px; }

/* ────────────── shop ────────────── */
.shop-balance-card {
  display: flex;
  gap: 16px;
  justify-content: center;
  background: linear-gradient(135deg, #2d1840, #3a1f5a);
  border: 1px solid rgba(242, 184, 75, 0.3);
  border-radius: 14px;
  padding: 14px;
  margin-bottom: 14px;
}
.balance-item {
  display: flex;
  align-items: center;
  gap: 6px;
}
.balance-icon { font-size: 22px; }
.balance-val {
  font-family: 'Fraunces', serif;
  font-weight: 900;
  font-size: 22px;
  color: #f2b84b;
}
.balance-label {
  font-size: 11px;
  color: var(--ink-dim, #a89568);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.shop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
}
.shop-bundle {
  position: relative;
  background: linear-gradient(180deg, #2d1840, #1a0820);
  border: 1px solid rgba(242, 184, 75, 0.25);
  border-radius: 14px;
  padding: 14px 12px 12px;
  text-align: center;
  transition: transform 0.2s, border-color 0.2s;
  overflow: hidden;
}
.shop-bundle:hover {
  transform: translateY(-3px);
  border-color: #f2b84b;
}
.shop-bundle.featured {
  border: 2px solid #f2b84b;
  background: linear-gradient(180deg, #5a3878, #3a1f5a);
  box-shadow: 0 0 20px rgba(242, 184, 75, 0.25);
}
.bundle-tag {
  position: absolute;
  top: 6px;
  left: 6px;
  font-size: 9px;
  font-weight: 800;
  padding: 2px 8px;
  border-radius: 4px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.bundle-discount {
  position: absolute;
  top: 6px;
  right: 6px;
  background: linear-gradient(135deg, #c41e3a, #8b3a4a);
  color: #fef7e3;
  font-size: 10px;
  font-weight: 800;
  padding: 2px 8px;
  border-radius: 4px;
}
.bundle-items {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin: 18px 0 8px;
  min-height: 50px;
}
.bundle-item {
  display: flex;
  align-items: center;
  gap: 2px;
  font-size: 13px;
  font-weight: 700;
  color: #fef7e3;
}
.bundle-icon { font-size: 22px; }
.bundle-amount { font-size: 12px; opacity: 0.85; }
.bundle-name {
  font-size: 12px;
  color: var(--ink-dim, #a89568);
  margin-bottom: 8px;
  min-height: 28px;
}
.bundle-buy { width: 100%; padding: 8px; font-size: 14px; }

.ad-card {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: center;
  background: rgba(36, 17, 73, 0.5);
  border: 1px solid rgba(111, 227, 193, 0.3);
  border-radius: 12px;
  padding: 14px 16px;
  margin-top: 8px;
}
.ad-card strong { color: #6fe3c1; display: block; font-size: 14px; }
.ad-meta { font-size: 12px; color: var(--ink-dim, #a89568); margin-top: 2px; }

/* ────────────── achievements ────────────── */
.achievements-header { margin-bottom: 14px; }
.ach-progress-card {
  background: linear-gradient(135deg, #2d1840, #3a1f5a);
  border: 1px solid rgba(242, 184, 75, 0.3);
  border-radius: 12px;
  padding: 12px 14px;
  margin-bottom: 18px;
}
.ach-progress-card .progress-bar { height: 8px; }
.ach-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 22px 0 10px;
}
.ach-section-title .cat-icon { font-size: 22px; }
.ach-section-title .cat-count {
  font-family: system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-dim, #a89568);
  margin-left: auto;
  background: rgba(0, 0, 0, 0.25);
  padding: 2px 8px;
  border-radius: 8px;
}

.ach-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ach-row {
  display: grid;
  grid-template-columns: 48px 1fr auto;
  gap: 12px;
  align-items: center;
  background: rgba(36, 17, 73, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 12px;
  padding: 10px 12px;
  transition: border-color 0.2s, background 0.2s;
}
.ach-row.unlocked {
  border-color: rgba(111, 227, 193, 0.45);
  background: linear-gradient(135deg, rgba(111, 227, 193, 0.05), rgba(36, 17, 73, 0.5));
}
.ach-row.claimed {
  opacity: 0.6;
}
.ach-row.locked { opacity: 0.7; }
.ach-row.ach-tier-5.unlocked {
  border-color: #f2b84b;
  background: linear-gradient(135deg, rgba(242, 184, 75, 0.15), rgba(36, 17, 73, 0.5));
  box-shadow: 0 0 12px rgba(242, 184, 75, 0.25);
}
.ach-row-icon {
  font-size: 32px;
  text-align: center;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 50%;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ach-row.locked .ach-row-icon { filter: grayscale(1) brightness(0.7); }
.ach-row-title {
  font-weight: 700;
  font-size: 14px;
  color: #fef7e3;
}
.ach-row-desc {
  font-size: 12px;
  color: var(--ink-dim, #a89568);
  margin-top: 2px;
}
.ach-row-progress {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
}
.ach-row-bar {
  flex: 1;
  height: 4px;
  background: rgba(255, 255, 255, 0.08);
  border-radius: 2px;
  overflow: hidden;
}
.ach-row-fill {
  height: 100%;
  background: linear-gradient(90deg, #6fe3c1, #f2b84b);
  border-radius: 2px;
}
.ach-row-frac {
  font-size: 11px;
  color: var(--ink-dim, #a89568);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ach-claimed-mark {
  color: #6fe3c1;
  font-weight: 900;
  font-size: 20px;
}
.ach-locked-reward {
  font-size: 11px;
  color: var(--ink-dim, #a89568);
  white-space: nowrap;
}

/* Achievement unlock toast (top-right) */
.achievement-unlock-toast {
  position: fixed;
  top: 20px;
  right: 20px;
  background: linear-gradient(135deg, #2d1840, #5a2548);
  border: 2px solid #f2b84b;
  border-radius: 14px;
  padding: 14px 18px;
  display: flex;
  gap: 12px;
  align-items: center;
  z-index: 300;
  box-shadow: 0 8px 32px rgba(242, 184, 75, 0.35), 0 0 0 0 rgba(242, 184, 75, 0.5);
  transform: translateX(120%);
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
  max-width: 320px;
}
.achievement-unlock-toast.show {
  transform: translateX(0);
  animation: achGlow 1.6s ease-out;
}
@keyframes achGlow {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}
.achievement-unlock-toast .ach-icon {
  font-size: 36px;
  flex-shrink: 0;
}
.achievement-unlock-toast .ach-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: #f2b84b;
  text-transform: uppercase;
}
.achievement-unlock-toast .ach-name {
  font-family: 'Fraunces', serif;
  font-weight: 700;
  font-size: 15px;
  color: #fef7e3;
  margin: 2px 0;
}
.achievement-unlock-toast .ach-reward {
  font-size: 12px;
  color: #6fe3c1;
}

/* ────────────── high contrast mode ────────────── */
body.high-contrast .ach-row,
body.high-contrast .pass-tier-card,
body.high-contrast .event-card-v2,
body.high-contrast .shop-bundle,
body.high-contrast .stat-card,
body.high-contrast .daily-card,
body.high-contrast .quick-link {
  border-width: 2px !important;
  background: #0e0418 !important;
}
body.high-contrast .ach-row.unlocked,
body.high-contrast .pass-tier-card.earned {
  border-color: #6fe3c1 !important;
}
body.high-contrast .ach-row.ach-tier-5.unlocked,
body.high-contrast .pass-tier-card.current,
body.high-contrast .quick-link:hover {
  border-color: #ffffff !important;
}
body.high-contrast {
  --ink-dim: #ffffff !important;
}
body.high-contrast h1, body.high-contrast h2, body.high-contrast h3 {
  color: #ffeb6b !important;
}
body.high-contrast .btn {
  border: 2px solid #ffffff !important;
}

/* ────────────── consent flow ────────────── */
.consent-overlay {
  position: fixed; inset: 0; z-index: 300;
  background: linear-gradient(180deg, rgba(26,8,32,0.96), rgba(42,21,56,0.96));
  backdrop-filter: blur(8px);
  display: grid; place-items: center;
  padding: 16px;
  animation: fadein .2s ease-out;
  overflow-y: auto;
}
.consent-card {
  background: var(--bg-elev);
  border-radius: var(--r-lg);
  padding: 24px;
  max-width: 440px; width: 100%;
  box-shadow: var(--shadow-lg);
  border: 1px solid rgba(242,184,75,0.2);
  animation: dialogin .25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.consent-header {
  margin-bottom: 14px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  padding-bottom: 10px;
}
.consent-step {
  font-family: var(--font-body);
  font-size: 11px;
  color: var(--ink-dim);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 600;
}
.consent-card h2 {
  margin: 6px 0 0;
  font-size: 22px;
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 1.15;
}
.consent-body { margin: 14px 0; }
.consent-body p { font-size: 14px; line-height: 1.55; margin: 0 0 10px; }
.consent-note { font-size: 12px; color: var(--ink-dim); font-style: italic; }
.consent-list { padding-left: 0; list-style: none; }
.consent-list li {
  font-size: 13px;
  line-height: 1.5;
  padding: 8px 12px;
  border-left: 3px solid var(--gold);
  background: rgba(0,0,0,0.18);
  border-radius: 0 6px 6px 0;
  margin-bottom: 6px;
}
.consent-options { display: grid; gap: 8px; margin: 14px 0; }
.consent-actions {
  display: flex; gap: 10px; justify-content: flex-end;
  margin-top: 16px; padding-top: 14px;
  border-top: 1px solid rgba(255,255,255,0.06);
  flex-wrap: wrap;
}

/* ────────────── tutorial bubble ────────────── */
.tutorial-bubble {
  position: fixed;
  z-index: 150;
  background: linear-gradient(180deg, var(--bg-elev), var(--bg-elev-2));
  color: var(--ink);
  padding: 14px 18px;
  border-radius: var(--r);
  box-shadow: var(--shadow-lg);
  border: 1px solid rgba(242,184,75,0.4);
  max-width: 320px;
  width: calc(100% - 40px);
  animation: bubbleIn .3s cubic-bezier(0.34, 1.56, 0.64, 1);
  /* v2.43 — FIX TRABA EN CELULAR: el cartel NO debe interceptar taps del tablero.
     Antes, centrado sobre el board y con pointer-events activos, tapaba las fichas
     del medio y no se podían tocar (se sentia "trabado"). Ahora los taps pasan a
     traves del cartel; solo los botones (Ok / Saltar / A jugar) reciben el toque. */
  pointer-events: none;
}
.tutorial-bubble .tutorial-actions,
.tutorial-bubble button {
  pointer-events: auto;
}
@keyframes bubbleIn {
  from { transform: translateY(20px) scale(0.92); opacity: 0; }
  to { transform: translateY(0) scale(1); opacity: 1; }
}
.tutorial-bubble .tutorial-step {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--gold);
  font-weight: 700;
  margin-bottom: 4px;
}
.tutorial-bubble h3 {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 800;
}
.tutorial-bubble p {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-dim);
}
.tutorial-actions {
  display: flex; gap: 6px;
  justify-content: flex-end;
  flex-wrap: wrap;
}
.tutorial-anchor-board {
  /* v2.43 — arriba, no en el centro: deja ver y tocar las fichas del medio. */
  top: 18%; left: 50%; transform: translate(-50%, -50%);
}
.tutorial-anchor-dock {
  bottom: 110px; left: 50%; transform: translateX(-50%);
}
.tutorial-anchor-center {
  top: 50%; left: 50%; transform: translate(-50%, -50%);
}

/* v2.43 — toggles de audio "a mano" en la barra del juego (música / efectos).
   El estado apagado se ve atenuado + tachado en rojo. */
.snd-toggle { position: relative; }
.snd-toggle.snd-off { opacity: 0.5; }
.snd-toggle.snd-off::after {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 128%; height: 2px;
  background: #e0563b;
  transform: translate(-50%, -50%) rotate(-45deg);
  border-radius: 2px;
  pointer-events: none;
}

/* skip link de accesibilidad */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 8px;
  background: var(--gold);
  color: #2a1804;
  padding: 8px 14px;
  border-radius: 8px;
  z-index: 1000;
  font-weight: 700;
}
.skip-link:focus { left: 8px; }

/* ────────────── accessibility ────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
/* Toggle in-app "Reducir movimiento" (body.reduce-motion): mismo kill-switch que
   la media query del SO, para los casos en que la preferencia del SO no está activa. */
body.reduce-motion *,
body.reduce-motion *::before,
body.reduce-motion *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  scroll-behavior: auto !important;
}

/* ────────────── responsive ────────────── */
@media (min-width: 600px) {
  .app { max-width: 540px; margin: 0 auto; box-shadow: 0 0 60px rgba(0,0,0,0.6); }
  /* gameboard-wrap mantiene full-screen (background cubre todo el viewport)
     pero los hijos directos se centran a 540px — así no ves la home detrás. */
  .gameboard-wrap {
    inset: 0; left: 0; right: 0;
    max-width: none;
    transform: none;
  }
  .gameboard-wrap > .hud,
  .gameboard-wrap > .objective-row,
  .gameboard-wrap > .layout-row,
  .gameboard-wrap > .board,
  .gameboard-wrap > .dock {
    max-width: 540px;
    margin-left: auto;
    margin-right: auto;
    width: 100%;
  }
}

/* §20 LEGIBILIDAD MÓVIL — breakpoints responsive para los tamaños
   objetivo del plan §20.2 (360×640, 390×844, 412×915, 768×1024). */

/* Teléfono chico (≤380px, ej. 360×640): compactar paddings y tipografía
   sin bajar de los mínimos §20.1 (tap 44px, emoji 26px, label 9px). */
@media (max-width: 380px) {
  html, body { font-size: 14px; }
  .hud { padding-left: 8px; padding-right: 8px; }
  .hud-stat { gap: 2px; }
  .dock { gap: 6px; }
  .booster { min-width: 52px; }   /* sigue >44px tap target */
  .objective-row, .layout-row { padding-left: 8px; padding-right: 8px; }
}

/* Teléfono grande (381–767px): tamaño base pleno, layout fluido. */
@media (min-width: 381px) and (max-width: 767px) {
  html, body { font-size: 15px; }
}

/* Tablet grande / desktop (≥900px): el .app ya queda centrado a 540px
   por el breakpoint de 600px; acá sólo se refuerza el encuadre. */
@media (min-width: 900px) {
  .app { box-shadow: 0 0 80px rgba(0,0,0,0.7); }
}

/* ════════════════════════════════════════════
   POLISH v2.6 — Error states + Loading states
   ════════════════════════════════════════════ */

/* ────────────── Skeleton loaders ────────────── */
@keyframes skeleton-pulse {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}
.skeleton {
  background: linear-gradient(90deg,
    rgba(168, 149, 104, 0.08) 0%,
    rgba(242, 184, 75, 0.18) 50%,
    rgba(168, 149, 104, 0.08) 100%);
  background-size: 200% 100%;
  animation: skeleton-pulse 1.4s ease-in-out infinite;
  border-radius: 6px;
}
.skeleton-text { height: 14px; margin: 8px 0; }
.skeleton-text.short { width: 60%; }
.skeleton-text.medium { width: 85%; }
.skeleton-card {
  height: 96px;
  margin: 12px 0;
  border-radius: 10px;
}
.skeleton-tile {
  aspect-ratio: 220 / 280;
  border-radius: 10px;
}

/* ────────────── Route loader (full screen) ────────────── */
.route-loader {
  position: fixed;
  inset: 0;
  background: linear-gradient(180deg, #1a0820 0%, #3a1f08 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  z-index: 9000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease-out;
}
.route-loader.active {
  opacity: 1;
  pointer-events: all;
}
.route-loader .spinner-andean {
  width: 64px;
  height: 64px;
  position: relative;
}
.route-loader .spinner-andean::before,
.route-loader .spinner-andean::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 4px solid transparent;
  border-top-color: #f2b84b;
  animation: spinner-rotate 1.2s cubic-bezier(0.6, 0.2, 0.4, 0.8) infinite;
}
.route-loader .spinner-andean::after {
  border-top-color: #c46a2a;
  animation-delay: -0.6s;
  animation-duration: 1.8s;
}
@keyframes spinner-rotate {
  to { transform: rotate(360deg); }
}
.route-loader .loader-text {
  color: #f2b84b;
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 14px;
  letter-spacing: 1.4px;
  opacity: 0.85;
  text-transform: uppercase;
}

/* ────────────── Board loader (mientras carga nivel) ────────────── */
.board-loader {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 40px 20px;
  min-height: 220px;
  color: #d8c9a8;
}
.board-loader .dots {
  display: flex;
  gap: 8px;
}
.board-loader .dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #f2b84b;
  animation: dot-bounce 1.2s ease-in-out infinite;
}
.board-loader .dot:nth-child(2) { animation-delay: 0.15s; background: #c46a2a; }
.board-loader .dot:nth-child(3) { animation-delay: 0.30s; background: #8b3a4a; }
@keyframes dot-bounce {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.6; }
  40% { transform: translateY(-10px); opacity: 1; }
}

/* ────────────── Error states ────────────── */
.error-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  text-align: center;
  gap: 16px;
  min-height: 320px;
}
.error-state .icon-glyph {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background: linear-gradient(135deg, #5a2548 0%, #c46a2a 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 40px;
  color: #f2b84b;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4),
              inset 0 -3px 0 rgba(0,0,0,0.3),
              inset 0 2px 0 rgba(255,255,255,0.15);
}
.error-state h2 {
  color: #f2b84b;
  font-family: "Fraunces", ui-serif, serif;
  font-size: 22px;
  font-weight: 700;
  margin: 0;
  letter-spacing: 0.3px;
}
.error-state p {
  color: #d8c9a8;
  font-size: 15px;
  line-height: 1.55;
  max-width: 320px;
  margin: 0;
  opacity: 0.85;
}
.error-state .actions {
  display: flex;
  gap: 12px;
  margin-top: 12px;
  flex-wrap: wrap;
  justify-content: center;
}
.error-state .btn-retry {
  background: linear-gradient(180deg, #f2b84b 0%, #c46a2a 100%);
  color: #1a0820;
  border: none;
  padding: 12px 24px;
  border-radius: 8px;
  font-family: "Fraunces", ui-serif, serif;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.5px;
  cursor: pointer;
  text-transform: uppercase;
  box-shadow: 0 4px 0 rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.3);
  transition: transform 0.1s, box-shadow 0.1s;
}
.error-state .btn-retry:active {
  transform: translateY(2px);
  box-shadow: 0 2px 0 rgba(0,0,0,0.35);
}
.error-state .btn-secondary {
  background: transparent;
  color: #d8c9a8;
  border: 1.5px solid #5a3a18;
  padding: 12px 20px;
  border-radius: 8px;
  font-size: 14px;
  cursor: pointer;
}

/* ────────────── Network/offline overlay ────────────── */
.network-banner {
  position: fixed;
  top: -60px;
  left: 0;
  right: 0;
  background: #8b3a4a;
  color: #fef7e3;
  padding: 14px 20px;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  z-index: 8000;
  transition: top 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 4px 16px rgba(0,0,0,0.3);
}
.network-banner.visible { top: 0; }
.network-banner.success { background: #1c3a25; }

/* ────────────── Toast con icono ────────────── */
.toast.with-icon {
  display: flex;
  align-items: center;
  gap: 12px;
}
.toast.with-icon .toast-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(242, 184, 75, 0.18);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 16px;
}
.toast.toast-success .toast-icon { background: rgba(111, 227, 193, 0.2); color: #6fe3c1; }
.toast.toast-error .toast-icon { background: rgba(196, 30, 58, 0.2); color: #ff8b9c; }
.toast.toast-info .toast-icon { background: rgba(74, 144, 226, 0.2); color: #6fa8d4; }

/* ────────────── Button focus rings ────────────── */
button:focus-visible,
a:focus-visible,
[role="button"]:focus-visible {
  outline: 2.5px solid #f2b84b;
  outline-offset: 3px;
  border-radius: 4px;
}

/* ────────────── Button hover feedback (no haptics) ────────────── */
@media (hover: hover) {
  button:not(:disabled):hover,
  [role="button"]:not(:disabled):hover {
    filter: brightness(1.08);
  }
}

/* ────────────── Card lift on tap ────────────── */
.tappable {
  transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 0.15s cubic-bezier(0.4, 0, 0.2, 1);
  cursor: pointer;
}
.tappable:active {
  transform: scale(0.97);
}

/* ────────────── Empty state ────────────── */
.empty-state {
  text-align: center;
  padding: 56px 24px;
  color: #a89568;
}
.empty-state .glyph {
  font-size: 56px;
  opacity: 0.4;
  margin-bottom: 16px;
}
.empty-state h3 {
  color: #d8c9a8;
  font-family: "Fraunces", ui-serif, serif;
  font-size: 18px;
  margin: 0 0 8px 0;
}
.empty-state p {
  font-size: 14px;
  line-height: 1.5;
  margin: 0;
  max-width: 280px;
  margin: 0 auto;
  opacity: 0.8;
}

/* ────────────── Page transitions ────────────── */
.view-enter {
  opacity: 0;
  transform: translateX(20px);
}
.view-enter-active {
  opacity: 1;
  transform: translateX(0);
  transition: opacity 0.3s ease-out, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ────────────── Pull to refresh hint ────────────── */
.pull-hint {
  text-align: center;
  font-size: 12px;
  color: #a89568;
  padding: 8px 0;
  opacity: 0.6;
}

/* ════════════════════════════════════════════
   v2.6.2 — Tablero 3D mejorado
   ════════════════════════════════════════════ */

/* MISMATCH: vibración + flash rojo + glow caliente; refuerzo dramático
   sobre el sutil shake anterior. Filter en cada keyframe da el "neón" rojo. */
@keyframes mismatch-shake {
  0%, 100% { transform: translateX(0) rotate(0); filter: brightness(1); }
  12%      { transform: translateX(-7px) rotate(-2.2deg) scale(1.025);
             filter: brightness(1.2) saturate(1.4)
                     drop-shadow(0 0 14px rgba(226, 90, 90, 0.85)); }
  28%      { transform: translateX(7px) rotate(2.2deg) scale(1.025);
             filter: brightness(1.18) saturate(1.4)
                     drop-shadow(0 0 12px rgba(226, 90, 90, 0.8)); }
  44%      { transform: translateX(-5px) rotate(-1.6deg);
             filter: brightness(1.1) drop-shadow(0 0 9px rgba(226, 90, 90, 0.6)); }
  60%      { transform: translateX(5px) rotate(1.6deg);
             filter: brightness(1.05) drop-shadow(0 0 6px rgba(226, 90, 90, 0.4)); }
  76%      { transform: translateX(-2px) rotate(-0.4deg); filter: brightness(1.02); }
}
.board-svg .tile.mismatch-shake {
  animation: mismatch-shake 0.52s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}

/* Match flash verde sobre el tile antes de removerlo */
@keyframes match-flash {
  0% { filter: brightness(1) saturate(1); }
  30% { filter: brightness(1.4) saturate(1.5) hue-rotate(80deg); }
  60% { filter: brightness(1.6) saturate(1.8) drop-shadow(0 0 12px #6fe3c1); }
  100% { filter: brightness(1) opacity(0); transform: scale(0.85); }
}
.tile.match-burst {
  animation: match-flash 0.55s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

/* Nuevo destello dorado brillante sobre la ficha al matchear */
.match-tile-flash {
  position: fixed;
  pointer-events: none;
  z-index: 9200;
  border-radius: 8px;
  background: radial-gradient(circle, #fef7e3 0%, rgba(242,184,75,0.8) 40%, transparent 80%);
  box-shadow: 0 0 30px #f2b84b;
  transform: translate(-50%, -50%);
  animation: tile-flash-anim 0.6s cubic-bezier(0.2, 0.6, 0.3, 1) forwards;
}
@keyframes tile-flash-anim {
  0% { transform: translate(-50%, -50%) scale(0.8); opacity: 0; }
  30% { transform: translate(-50%, -50%) scale(1.1); opacity: 1; filter: brightness(1.5); }
  100% { transform: translate(-50%, -50%) scale(0.6); opacity: 0; filter: brightness(1); }
}

/* Select ring pulsante */
@keyframes select-ring-pulse {
  0%, 100% { opacity: 0.9; stroke-width: 3; }
  50% { opacity: 1; stroke-width: 4; }
}
.select-ring {
  animation: select-ring-pulse 1.2s ease-in-out infinite;
}

/* Tiles de capa más alta: ligeramente más brillantes (cerca de la luz).
   Apuntamos al <use> de la ilustración, no a <image>. */
.tile.layer-1 use { filter: brightness(1.05); }
.tile.layer-2 use { filter: brightness(1.10); }
.tile.layer-3 use { filter: brightness(1.15); }
.tile.layer-4 use { filter: brightness(1.20); }
.tile.layer-5 use { filter: brightness(1.25); }

/* Hover/selected ya cubiertos en el bloque "tile interaction" arriba,
   con transform-box: fill-box que evita el bug del slot. No duplicar aquí. */

/* Floating combo score animación */
@keyframes float-up-fade {
  0% { opacity: 0; transform: translate(-50%, 0) scale(0.7); }
  20% { opacity: 1; transform: translate(-50%, -10px) scale(1.1); }
  100% { opacity: 0; transform: translate(-50%, -55px) scale(1); }
}
.match-float-score {
  position: fixed;
  pointer-events: none;
  z-index: 9500;
  color: #f2b84b;
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-weight: 900;
  font-size: 20px;
  letter-spacing: 0.5px;
  text-shadow: 0 2px 6px rgba(0,0,0,0.6), 0 0 12px rgba(242,184,75,0.6);
  animation: float-up-fade 1s cubic-bezier(0.2, 0.6, 0.3, 1) forwards;
  transform: translate(-50%, 0);
}
.match-float-score.combo {
  color: #6fe3c1;
  font-size: 22px;
  text-shadow: 0 2px 8px rgba(0,0,0,0.7), 0 0 16px rgba(111,227,193,0.8);
}

/* Match particles */
.match-particle {
  position: fixed;
  pointer-events: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: radial-gradient(circle, #f2b84b 0%, #c46a2a 100%);
  z-index: 9400;
  animation: particle-fly 0.6s cubic-bezier(0.2, 0.6, 0.3, 1) forwards;
}
@keyframes particle-fly {
  0% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 0px))) scale(0); opacity: 0; }
}

/* Screen shake en combos altos */
@keyframes board-shake {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(-2px, 1px); }
  50% { transform: translate(2px, -1px); }
  75% { transform: translate(-1px, 2px); }
}
.board.shake {
  animation: board-shake 0.3s ease-in-out;
}

/* Board container con perspectiva y borde temático */
.board {
  border-radius: 14px;
  overflow: hidden;
  box-shadow:
    0 12px 36px rgba(0,0,0,0.55),
    inset 0 1px 0 rgba(255,255,255,0.08),
    inset 0 -2px 0 rgba(0,0,0,0.3);
  position: relative;
}

/* Layout name badge en HUD */
.layout-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  background: rgba(242, 184, 75, 0.12);
  border: 1px solid rgba(242, 184, 75, 0.35);
  border-radius: 12px;
  font-size: 11px;
  font-family: "Fraunces", ui-serif, serif;
  color: #f2b84b;
  letter-spacing: 0.4px;
  text-transform: capitalize;
}
.layout-badge::before {
  content: "◆";
  font-size: 9px;
  opacity: 0.7;
}

/* Layout row entre HUD y board */
.layout-row {
  display: flex;
  justify-content: center;
  padding: 6px 0 2px;
}

/* ════════════════════════════════════════════
   v2.6.3 — Splash con paisaje + logo chakana
   ════════════════════════════════════════════ */
.splash-scene {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}
.splash-scene svg {
  width: 100%; height: 100%;
  display: block;
}
.splash-inner {
  position: relative;
  z-index: 2;
  background: radial-gradient(ellipse at center, rgba(14,4,24,0.55) 0%, rgba(14,4,24,0.85) 70%, rgba(14,4,24,0.95) 100%);
  padding: 38px 48px 28px;
  border-radius: 18px;
  backdrop-filter: blur(2px);
}
.splash-logo-mark {
  width: 90px; height: 90px;
  filter: drop-shadow(0 4px 16px rgba(242, 184, 75, 0.7));
  animation: splashLogoFloat 2.4s ease-in-out infinite;
}
.splash-title {
  margin: 14px 0 2px;
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 26px;
  font-weight: 900;
  color: #fef7e3;
  letter-spacing: 1px;
  text-shadow: 0 2px 12px rgba(0,0,0,0.6), 0 0 24px rgba(242,184,75,0.4);
}
.splash-subtitle {
  margin: 0 0 18px;
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 6px;
  color: #f2b84b;
  text-transform: uppercase;
  opacity: 0.85;
}
.splash-loader {
  width: 140px; height: 4px;
  margin: 0 auto;
  background: rgba(242, 184, 75, 0.18);
  border-radius: 2px;
  overflow: hidden;
}
.splash-loader-bar {
  width: 30%; height: 100%;
  background: linear-gradient(90deg, transparent, #f2b84b 50%, transparent);
  animation: splashLoaderSlide 1.4s ease-in-out infinite;
}
@keyframes splashLoaderSlide {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(420%); }
}

/* ════════════════════════════════════════════
   v2.6.3 — Win/Lose escenas cinematográficas
   ════════════════════════════════════════════ */

/* Escena de fondo en win overlay */
.win-overlay { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; }
.win-scene {
  position: absolute; inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  animation: scene-zoom-in 1.4s cubic-bezier(0.2, 0.6, 0.3, 1) backwards;
}
.win-scene svg { width: 100%; height: 100%; display: block; }
@keyframes scene-zoom-in {
  0% { opacity: 0; transform: scale(1.18); }
  100% { opacity: 1; transform: scale(1); }
}
.win-scene .win-rays-svg {
  transform-origin: 200px 200px;
  animation: rays-rotate 30s linear infinite;
}
@keyframes rays-rotate {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.win-dialog {
  position: relative;
  z-index: 2;
  background: linear-gradient(180deg, rgba(58, 31, 90, 0.92) 0%, rgba(14, 4, 24, 0.96) 100%);
  backdrop-filter: blur(8px);
  border: 1.5px solid rgba(242, 184, 75, 0.45);
  box-shadow:
    0 0 40px rgba(242, 184, 75, 0.3),
    0 16px 48px rgba(0, 0, 0, 0.7),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

/* Stuck/Lose overlay */
.stuck-overlay {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
}
.lose-scene {
  position: absolute; inset: 0; z-index: 0; overflow: hidden;
  pointer-events: none;
  animation: scene-zoom-in 1.2s cubic-bezier(0.2, 0.6, 0.3, 1) backwards;
}
.lose-scene svg { width: 100%; height: 100%; display: block; }
.lose-dialog {
  position: relative;
  z-index: 2;
  background: linear-gradient(180deg, rgba(26, 8, 32, 0.94) 0%, rgba(14, 4, 24, 0.97) 100%);
  backdrop-filter: blur(10px);
  padding: 28px 26px;
  border-radius: 16px;
  border: 1.5px solid rgba(139, 58, 74, 0.5);
  box-shadow:
    0 0 40px rgba(139, 58, 74, 0.25),
    0 16px 48px rgba(0, 0, 0, 0.7),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
  max-width: 360px;
  text-align: center;
  animation: dialog-slide-up 0.4s cubic-bezier(0.2, 0.6, 0.3, 1) 0.3s backwards;
}
@keyframes dialog-slide-up {
  0% { opacity: 0; transform: translateY(30px) scale(0.96); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
.lose-icon {
  font-size: 56px;
  margin-bottom: 12px;
  filter: drop-shadow(0 4px 12px rgba(139, 58, 74, 0.6));
  animation: lose-icon-float 3s ease-in-out infinite;
}
@keyframes lose-icon-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}
.lose-dialog h2 {
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 22px;
  font-weight: 800;
  margin: 0 0 10px;
  color: #fef7e3;
}
.lose-dialog p {
  font-size: 14px;
  line-height: 1.55;
  color: #d8c9a8;
  margin: 0 0 20px;
  opacity: 0.85;
}
.lose-dialog .row {
  display: flex; gap: 10px;
  flex-wrap: wrap; justify-content: center;
}

/* v2.23 — flujo "trabado": cartel para MIRAR + barra de opciones (no tapan el tablero) */
.stuck-hint {
  position: fixed; top: 70px; left: 50%; transform: translateX(-50%);
  background: rgba(26,18,40,0.92); color: var(--ink); border: 1px solid var(--gold);
  border-radius: 999px; padding: 10px 20px; font-size: 14px; font-weight: 700;
  z-index: 60; box-shadow: 0 6px 20px rgba(0,0,0,0.5); cursor: pointer;
  animation: stuckHintIn .3s ease-out;
}
@keyframes stuckHintIn { from { opacity: 0; transform: translateX(-50%) translateY(-12px); } }
.stuck-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  background: linear-gradient(180deg, rgba(26,18,40,0.6), rgba(14,4,24,0.96));
  backdrop-filter: blur(6px); padding: 14px 16px calc(16px + var(--safe-bottom));
  border-top: 1px solid rgba(242,184,75,0.4);
  animation: stuckBarIn .3s cubic-bezier(0.3,0.8,0.4,1);
}
@keyframes stuckBarIn { from { transform: translateY(100%); } }
.stuck-bar-title { text-align: center; font-size: 13px; color: var(--ink-dim); margin-bottom: 10px; }
.stuck-bar-row { display: flex; gap: 8px; justify-content: center; align-items: stretch; max-width: 460px; margin: 0 auto; }
.stuck-bar-row .btn { flex: 1; }
.stuck-bar-row .btn.small { flex: 0 0 auto; min-width: 48px; }
.stuck-bar-row .btn small { opacity: 0.85; font-weight: 800; }
/* resalto de las últimas fichas jugadas para "ver dónde te trabaste" */
.board-svg .tile.last-played { animation: lastPlayedPulse 1.2s ease-in-out infinite; }
@keyframes lastPlayedPulse {
  0%, 100% { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.55)); }
  50% { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.55)) drop-shadow(0 0 10px rgba(111,227,193,0.9)); }
}
body.reduce-motion .stuck-hint, body.reduce-motion .stuck-bar { animation: none; }
body.reduce-motion .board-svg .tile.last-played { animation: none; filter: drop-shadow(0 0 6px rgba(111,227,193,0.8)); }

/* Fondos escénicos por mundo en el mapa */
.world {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.world-scene {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 140px;
  z-index: 0;
  pointer-events: none;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  overflow: hidden;
  opacity: 0.85;
}
.world-scene svg { width: 100%; height: 100%; display: block; }
.world-scene::after {
  /* fade-out hacia abajo para que el contenido se lea */
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 40%, var(--bg-card, #2a1538) 100%);
}
.world-header {
  position: relative;
  z-index: 1;
  padding-top: 88px !important;
}
.world-title h3 {
  text-shadow: 0 2px 8px rgba(0,0,0,0.6);
  color: #fef7e3 !important;
}
.world-title .world-role {
  text-shadow: 0 1px 3px rgba(0,0,0,0.7);
}

/* ════════════════════════════════════════════
   v2.6.4 — Pause, Stats, Free-ring, Splash proverb
   ════════════════════════════════════════════ */

/* Pause overlay (similar a lose pero con icono propio) */
.pause-overlay { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; }
.pause-scene { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.pause-scene svg { width: 100%; height: 100%; display: block; }
.pause-dialog {
  position: relative; z-index: 2;
  background: linear-gradient(180deg, rgba(26,8,32,0.92) 0%, rgba(14,4,24,0.97) 100%);
  backdrop-filter: blur(8px);
  padding: 28px 26px;
  border-radius: 16px;
  border: 1.5px solid rgba(242,184,75,0.45);
  max-width: 320px;
  text-align: center;
  box-shadow: 0 16px 48px rgba(0,0,0,0.7);
}
.pause-icon { font-size: 56px; margin-bottom: 12px; color: #f2b84b; }
.pause-dialog h2 {
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 22px; margin: 0 0 10px; color: #fef7e3;
}
.pause-dialog p { font-size: 14px; line-height: 1.55; color: #d8c9a8; margin: 0 0 20px; }
.pause-dialog .row { display: flex; gap: 10px; justify-content: center; }

/* HUD button icon-only (pause) */
.hud .btn.icon-only {
  min-width: 36px;
  width: 36px;
  padding: 0;
  font-size: 16px;
}

/* Free-ring pulsante en tiles libres */
@keyframes free-ring-pulse {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 0.85; }
}
.free-ring {
  animation: free-ring-pulse 2.2s ease-in-out infinite;
}

/* Splash proverb */
.splash-proverb {
  margin: 16px 0 0;
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-style: italic;
  font-size: 13px;
  color: #d8c9a8;
  opacity: 0.85;
  letter-spacing: 0.3px;
  max-width: 260px;
  margin-left: auto;
  margin-right: auto;
  line-height: 1.5;
}

/* ════════════════════════════════════════════
   Stats Screen
   ════════════════════════════════════════════ */
.stats-hero {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  min-height: 160px;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow);
  isolation: isolate;
}
.stats-hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.stats-hero-bg svg { width: 100%; height: 100%; display: block; }
.stats-hero-bg::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(14,4,24,0.2) 0%, rgba(14,4,24,0.6) 100%);
}
.stats-hero-content {
  position: relative;
  z-index: 1;
  text-align: center;
  padding: 24px;
}
.big-number {
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 64px;
  font-weight: 900;
  color: #fef7e3;
  line-height: 1;
  text-shadow: 0 2px 12px rgba(0,0,0,0.7), 0 0 24px rgba(242,184,75,0.4);
}
.big-number .frac {
  font-size: 28px;
  opacity: 0.55;
  font-weight: 700;
}
.big-label {
  color: #f2b84b;
  font-size: 13px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  margin-top: 6px;
  text-shadow: 0 1px 4px rgba(0,0,0,0.6);
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-bottom: 22px;
}
.stat-tile {
  background: linear-gradient(180deg, rgba(58,31,90,0.4) 0%, rgba(26,8,32,0.6) 100%);
  border: 1px solid rgba(242,184,75,0.18);
  padding: 14px 12px;
  border-radius: 12px;
  text-align: center;
}
.stat-tile .stat-icon {
  font-size: 22px;
  margin-bottom: 6px;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.4));
}
.stat-tile .stat-val {
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 22px;
  font-weight: 900;
  color: #fef7e3;
  line-height: 1.1;
}
.stat-tile .stat-val .frac {
  font-size: 12px;
  opacity: 0.6;
  font-weight: 600;
}
.stat-tile .stat-key {
  font-size: 11px;
  color: #a89568;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-top: 4px;
}

.stats-section {
  margin-bottom: 22px;
}
.stats-section h2 {
  font-family: "Fraunces", ui-serif, Georgia, serif;
  color: #f2b84b;
  font-size: 18px;
  font-weight: 700;
  margin: 0 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(242,184,75,0.18);
}

.world-progress-row {
  display: grid;
  grid-template-columns: 32px 1fr 50px;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: rgba(58,31,90,0.25);
  border-radius: 10px;
  margin-bottom: 6px;
}
.world-progress-row .wp-icon {
  font-size: 20px;
  text-align: center;
}
.world-progress-row .wp-name {
  font-size: 13px;
  color: #fef7e3;
  margin-bottom: 4px;
  font-weight: 600;
}
.world-progress-row .wp-count {
  text-align: right;
  font-family: "Fraunces", serif;
  font-size: 13px;
  color: #f2b84b;
  font-weight: 700;
}

.booster-stats .bs-row,
.info-rows .info-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 14px;
  background: rgba(58,31,90,0.2);
  border-radius: 8px;
  margin-bottom: 4px;
  font-size: 13px;
}
.booster-stats .bs-row strong,
.info-rows .info-row strong {
  color: #f2b84b;
  font-family: "Fraunces", serif;
  font-size: 14px;
}

/* Modo Zen badge en HUD */
.hud-stat.zen-badge .v {
  color: #6fe3c1;
  text-shadow: 0 0 8px rgba(111, 227, 193, 0.5);
  font-weight: 800;
}
.hud.zen {
  background: linear-gradient(180deg, rgba(58, 31, 90, 0.4), rgba(26, 8, 32, 0.6));
}

/* Quick-link styling consistente para stats */
.quick-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 12px 8px;
}

/* Botones full-width en settings */
.btn.full-width {
  width: 100%;
  margin-bottom: 8px;
}
.btn.danger {
  background: linear-gradient(180deg, #8b3a4a, #5a1f2a);
  color: #fef7e3;
}

/* ════════════════════════════════════════════
   v2.6.5 — Gameplay polish: cascade-in, match dramático, combo banner
   ════════════════════════════════════════════ */

/* Touch responsiveness — eliminar 300ms delay en mobile */
.board, .tile, .booster, .btn, .hud-stat {
  touch-action: manipulation;
}
.tile { -webkit-tap-highlight-color: transparent; }

/* CASCADE-IN: la ficha CAE DEL CIELO desde lejos arriba, se aplasta al
   aterrizar (squash horizontal/vertical), rebota una vez y se asienta.
   Stagger por distancia al centro lo decide el JS via animationDelay. */
@keyframes tile-cascade-in {
  0%   { opacity: 0;
         transform: translateY(-72px) scale(0.45) rotate(-9deg);
         filter: brightness(1.45) blur(1.2px); }
  35%  { opacity: 1;
         transform: translateY(-18px) scale(0.85, 0.92) rotate(-2deg);
         filter: brightness(1.25) blur(0.4px); }
  55%  { opacity: 1;
         transform: translateY(4px) scale(1.12, 0.82) rotate(0.6deg);
         filter: brightness(1.18) blur(0); }
  72%  { transform: translateY(-3px) scale(0.96, 1.06) rotate(-0.3deg);
         filter: brightness(1.08); }
  88%  { transform: translateY(1px) scale(1.02, 0.98) rotate(0.15deg);
         filter: brightness(1.03); }
  100% { opacity: 1;
         transform: translateY(0) scale(1) rotate(0deg);
         filter: brightness(1); }
}
.tile.tile-entering {
  animation: tile-cascade-in 0.62s cubic-bezier(0.28, 1.0, 0.42, 1) backwards;
  transform-origin: center;
  transform-box: fill-box;
}

/* NOTA: la animación activa de match-burst está en el bloque "tile
   interaction" arriba (matchBurst). Esta regla queda como fallback no-svg. */
.tile.match-burst:not(.board-svg .tile) {
  transform-origin: center;
}

/* Shockwave doble: oro afuera + verde adentro, en stagger.
   El JS sigue creando UN solo .match-shockwave; el ::before le agrega
   el segundo anillo verde sin necesidad de cambiar la lógica de spawn. */
.match-shockwave {
  position: fixed;
  pointer-events: none;
  /* v20 perf — el anillo crece por transform:scale (compositor), no por width/height
     (repaint). Base = tamaño FINAL (200px). El centrado va por MÁRGENES fijos
     (-100px): con translate(-50%) el centro se corría mientras escalaba. */
  width: 200px;
  height: 200px;
  margin-left: -100px;
  margin-top: -100px;
  border: 3px solid #ffd76a;
  border-radius: 50%;
  transform: scale(0.12);
  z-index: 9300;
  box-shadow: 0 0 24px rgba(255, 215, 106, 0.6),
              inset 0 0 18px rgba(255, 215, 106, 0.35);
  animation: shockwave-expand 0.72s cubic-bezier(0.16, 0.7, 0.3, 1) forwards;
}
.match-shockwave::before {
  content: "";
  position: absolute;
  inset: 4px;
  border: 2px solid #6fe3c1;
  border-radius: 50%;
  opacity: 0;
  box-shadow: 0 0 14px rgba(111, 227, 193, 0.7);
  animation: shockwave-inner 0.72s cubic-bezier(0.16, 0.7, 0.3, 1) 0.06s forwards;
}
@keyframes shockwave-expand {
  0%   { transform: scale(0.12); opacity: 1;   border-width: 3.5px; }
  60%  { opacity: 0.55; border-width: 2px; }
  100% { transform: scale(1); opacity: 0;   border-width: 0.5px; }
}
@keyframes shockwave-inner {
  0%   { inset: 8px;   opacity: 1;   border-width: 2.5px; }
  100% { inset: -60px; opacity: 0;   border-width: 0.5px; }
}

/* Combo banner cinematográfico */
@keyframes combo-banner-in {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.3) rotate(-8deg);
  }
  60% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.15) rotate(2deg);
  }
  100% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1) rotate(0deg);
  }
}
@keyframes combo-banner-out {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -180%) scale(0.9); }
}
.combo-banner {
  position: fixed;
  left: 50%;
  top: 38%;
  transform: translate(-50%, -50%);
  z-index: 9600;
  pointer-events: none;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 28px;
  border-radius: 14px;
  background: linear-gradient(135deg, rgba(58, 31, 90, 0.95) 0%, rgba(196, 106, 42, 0.95) 100%);
  border: 2px solid #f2b84b;
  box-shadow:
    0 0 40px rgba(242, 184, 75, 0.6),
    0 8px 32px rgba(0, 0, 0, 0.6),
    inset 0 1px 0 rgba(255, 255, 255, 0.2);
  animation: combo-banner-in 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) backwards;
}
.combo-banner.combo-banner-out {
  animation: combo-banner-out 0.4s cubic-bezier(0.5, 0, 0.75, 0) forwards;
}
.combo-banner .combo-x {
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 38px;
  font-weight: 900;
  color: #fef7e3;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.6), 0 0 18px rgba(242, 184, 75, 0.8);
  line-height: 1;
}
.combo-banner .combo-text {
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 22px;
  font-weight: 700;
  color: #f2b84b;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.7);
}

/* Floating score MEJORADO — más visible */
.match-float-score {
  font-size: 26px;
  text-shadow:
    0 2px 8px rgba(0, 0, 0, 0.8),
    0 0 16px rgba(242, 184, 75, 0.7),
    0 0 4px rgba(254, 247, 227, 0.9);
}
.match-float-score.combo {
  font-size: 32px;
  letter-spacing: 1px;
  text-shadow:
    0 2px 10px rgba(0, 0, 0, 0.9),
    0 0 20px rgba(111, 227, 193, 0.9),
    0 0 6px rgba(254, 247, 227, 1);
}

/* Match particles — escala mejorada */
.match-particle {
  border-radius: 50%;
  z-index: 9400;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 0 4px currentColor);
}

/* Win flash — flash blanco corto cuando se gana */
@keyframes win-flash {
  0% { background: transparent; }
  /* v2.34 (#27) — pico adelantado (12% en vez de 20%): el destello pega y se disipa
     antes de que la card de victoria termine de entrar, sin taparla. */
  12% { background: rgba(254, 247, 227, 0.6); }
  100% { background: transparent; }
}
.win-flash-overlay {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9700;
  animation: win-flash 0.5s ease-out forwards;
}

/* v2.40 — BLOQUE STALE ELIMINADO. Acá vivía un `.gameboard-wrap { min-height:100vh }`
   + `.board`/`.board-svg` de la era del layout fijo que PISABA el fix v2.39 (línea ~415):
   su `min-height:100vh` ganaba sobre `height:100dvh` → en celular el contenedor se forzaba
   a 100vh (más alto que el viewport con barra del navegador) y el DOCK se RECORTABA por
   overflow:hidden. Era justo la queja del celular. Las reglas canónicas (415 .gameboard-wrap
   flex+100dvh, 469 .board grid, 475 .board svg) + fitBoard ya cubren todo. */

/* Respeto a reduce-motion (extendido para nuevas anims) */
.reduce-motion .tile.tile-entering { animation: none !important; opacity: 1; transform: none; }
.reduce-motion .tile.match-burst { animation: match-flash-reduced 0.3s ease-out forwards; }
@keyframes match-flash-reduced {
  0% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(0.7); }
}
.reduce-motion .combo-banner { animation: none !important; }
.reduce-motion .match-shockwave { display: none; }
.reduce-motion .match-particle { display: none; }
.reduce-motion .board.shake { animation: none !important; }
@media (prefers-reduced-motion: reduce) {
  .tile.tile-entering { animation: none !important; opacity: 1; transform: none; }
  .combo-banner { animation: none !important; }
  .match-shockwave { display: none; }
  .match-particle { display: none; }
  .board.shake { animation: none !important; }
}

/* ════════════════════════════════════════════
   v2.6.7 — Objectives, preload, performance
   ════════════════════════════════════════════ */

/* Tile preload overlay (al primer nivel de la sesión) */
.tile-preload-overlay {
  position: fixed; inset: 0;
  background: rgba(14,4,24,0.92);
  display: flex; align-items: center; justify-content: center; flex-direction: column;
  gap: 14px;
  z-index: 9000;
  color: #f2b84b;
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-size: 14px;
  letter-spacing: 1px;
}
.tile-preload-overlay .dots { display: flex; gap: 6px; }
.tile-preload-overlay .dot {
  width: 10px; height: 10px;
  background: #f2b84b;
  border-radius: 50%;
  animation: dot-pulse 1.2s ease-in-out infinite;
}
.tile-preload-overlay .dot:nth-child(2) { animation-delay: 0.2s; }
.tile-preload-overlay .dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes dot-pulse {
  0%, 100% { opacity: 0.3; transform: scale(0.7); }
  50% { opacity: 1; transform: scale(1); }
}

/* Objective badge en HUD */
.objective-row {
  display: flex; justify-content: center;
  padding: 4px 8px;
  background: rgba(0,0,0,0.18);
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.objective-badge {
  padding: 3px 12px;
  border-radius: 12px;
  font-size: 11px;
  font-family: "Fraunces", serif;
  font-weight: 600;
  letter-spacing: 0.4px;
  border: 1px solid;
}
.objective-clear_all { background: rgba(111,227,193,0.10); border-color: rgba(111,227,193,0.35); color: #6fe3c1; }
.objective-no_hints { background: rgba(242,184,75,0.10); border-color: rgba(242,184,75,0.45); color: #f2b84b; }
.objective-combo    { background: rgba(196,30,90,0.12); border-color: rgba(196,30,90,0.45); color: #ff7aa3; }
.objective-find_rare{ background: rgba(176,126,214,0.12); border-color: rgba(176,126,214,0.4); color: #c89af2; }
.objective-speed    { background: rgba(74,144,226,0.12); border-color: rgba(74,144,226,0.4); color: #6fb6e6; }
.objective-boss {
  background: linear-gradient(90deg, rgba(242,184,75,0.2), rgba(196,30,90,0.2));
  border-color: #f2b84b;
  color: #fef7e3;
  font-weight: 800;
  animation: boss-pulse 2s ease-in-out infinite;
}
@keyframes boss-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}

/* Objective complete / missed en win overlay */
.objective-complete {
  background: linear-gradient(90deg, rgba(111,227,193,0.18), rgba(242,184,75,0.18));
  border: 1px solid #6fe3c1;
  border-radius: 10px;
  padding: 8px 14px;
  margin: 10px 0;
  color: #fef7e3;
  font-family: "Fraunces", serif;
  font-size: 14px;
  font-weight: 700;
  text-align: center;
}
.objective-complete .bonus {
  color: #f2b84b;
  font-weight: 900;
  margin-left: 6px;
}
.objective-missed {
  padding: 6px 14px;
  margin: 10px 0;
  color: #a89568;
  font-size: 12px;
  text-align: center;
  font-style: italic;
}
/* v2.42 — badge de maestría del jefe en el overlay de victoria. */
.boss-mastery {
  border-radius: 10px;
  padding: 8px 14px;
  margin: 10px 0;
  text-align: center;
  font-family: "Fraunces", serif;
  font-size: 13px;
  font-weight: 700;
}
.boss-mastery.mastered {
  background: linear-gradient(90deg, rgba(242,184,75,0.22), rgba(255,215,120,0.22));
  border: 1px solid #f2b84b;
  color: #fef7e3;
  box-shadow: 0 0 16px rgba(242,184,75,0.35);
}
.boss-mastery.pending {
  background: rgba(168,149,104,0.12);
  border: 1px dashed #a89568;
  color: #d8c9a0;
  font-weight: 600;
}

/* ════════════════════════════════════════════
   v2.6.9 — Reveal screen + Level name HUD
   ════════════════════════════════════════════ */

.level-reveal-overlay {
  position: fixed; inset: 0;
  z-index: 800;
  background: radial-gradient(ellipse at center, rgba(58,31,90,0.92) 0%, rgba(14,4,24,0.97) 100%);
  display: flex; align-items: center; justify-content: center;
  backdrop-filter: blur(8px);
  animation: reveal-fade-in 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: auto;
}
.level-reveal-overlay.reveal-out {
  animation: reveal-fade-out 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
@keyframes reveal-fade-in {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
@keyframes reveal-fade-out {
  0% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.08); }
}
.reveal-inner {
  text-align: center;
  padding: 40px 32px;
  max-width: 90%;
  animation: reveal-slide-up 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.05s backwards;
}
@keyframes reveal-slide-up {
  0% { opacity: 0; transform: translateY(40px) scale(0.85); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
/* v2.22 — los BOSS se anuncian con aura roja/dorada */
.reveal-inner.reveal-boss {
  border-radius: 20px;
  box-shadow: 0 0 0 2px var(--gold), 0 0 60px rgba(196,30,58,0.5), 0 0 30px rgba(242,184,75,0.4);
  background: radial-gradient(ellipse at 50% 0%, rgba(196,30,58,0.25), transparent 70%);
}
.reveal-boss-tag {
  display: inline-block; font-family: var(--font-display, serif); font-weight: 900;
  font-size: 13px; letter-spacing: 3px; color: #2a1804;
  background: linear-gradient(90deg, var(--gold), #ffe98a, var(--gold));
  padding: 4px 16px; border-radius: 999px; margin-bottom: 10px;
  animation: bossTagPulse 1.4s ease-in-out infinite;
}
@keyframes bossTagPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.06); } }
.reveal-boss .reveal-title { color: #ff9d6a; text-shadow: 0 0 20px rgba(196,30,58,0.6); }
.reduce-motion .reveal-boss-tag { animation: none; }
/* chip de gema ganada en el win */
.chip.gemwin { color: #6fe3c1; }
.reveal-eyebrow {
  font-family: "Fraunces", ui-serif, Georgia, serif;
  color: #f2b84b;
  font-size: 12px;
  letter-spacing: 4px;
  font-weight: 600;
  margin-bottom: 14px;
  text-transform: uppercase;
  opacity: 0.85;
}
.reveal-title {
  font-family: "Fraunces", ui-serif, Georgia, serif;
  color: #fef7e3;
  font-size: 42px;
  font-weight: 900;
  line-height: 1.1;
  letter-spacing: 0.5px;
  text-shadow:
    0 2px 12px rgba(0,0,0,0.7),
    0 0 32px rgba(242,184,75,0.4),
    0 0 8px rgba(254,247,227,0.3);
  margin-bottom: 18px;
}
.reveal-objective {
  font-family: "Fraunces", ui-serif, Georgia, serif;
  color: #d8c9a8;
  font-size: 14px;
  font-style: italic;
  opacity: 0.85;
  letter-spacing: 0.5px;
}
.reveal-star-hints {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin-top: 14px;
}
.rsh {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.3px;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(255,255,255,0.1);
}
.rsh-3 { color: #f2b84b; border: 1px solid rgba(242,184,75,0.4); }
.rsh-2 { color: #b8c8ff; border: 1px solid rgba(184,200,255,0.3); }

/* HUD: indicador compacto de fichas libres */
.hud-free {
  font-size: 0.72em;
  opacity: 0.72;
  font-weight: 500;
  letter-spacing: 0;
}

/* HUD: level name visible */
.gameboard-wrap .hud-stat.level-name-stat {
  flex: 1;
  min-width: 0;
  align-items: flex-start;
  padding-left: 4px;
}
.gameboard-wrap .hud-stat.level-name-stat .k {
  color: #f2b84b;
  font-size: 9px;
}
.gameboard-wrap .hud-stat.level-name-stat .level-name {
  font-size: 13px;
  font-family: "Fraunces", serif;
  font-weight: 700;
  color: #fef7e3;
  letter-spacing: 0.2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Antes: max-width:130px fijo. En viewports angostos (≤380px) la columna
     flex queda ~85px y el nombre (max 130px) desbordaba sobre la stat "Pares"
     ("Plaza Belgranb4"). Con 100% se trunca con ellipsis dentro de su columna. */
  max-width: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .level-reveal-overlay,
  .reveal-inner { animation: none !important; }
}
.reduce-motion .level-reveal-overlay,
.reduce-motion .reveal-inner { animation: none !important; }

/* ════════════════════════════════════════════
   v2.6.9 — Chapter intro + Match word + Coya
   ════════════════════════════════════════════ */

/* Chapter intro overlay narrativa */
.chapter-intro-overlay {
  position: fixed; inset: 0; z-index: 8000;
  display: flex; align-items: center; justify-content: center;
  animation: chapter-fade-in 0.5s ease-out;
  background: #1a0820;
}
.chapter-intro-overlay.chapter-fade-out {
  animation: chapter-fade-out 0.35s ease-in forwards;
}
@keyframes chapter-fade-in {
  0% { opacity: 0; } 100% { opacity: 1; }
}
@keyframes chapter-fade-out {
  0% { opacity: 1; } 100% { opacity: 0; }
}
.chapter-scene { position: absolute; inset: 0; z-index: 0; }
.chapter-scene svg { width: 100%; height: 100%; }
.chapter-content {
  position: relative; z-index: 2;
  background: linear-gradient(180deg, rgba(26,8,32,0.85) 0%, rgba(14,4,24,0.92) 100%);
  backdrop-filter: blur(6px);
  padding: 32px 28px;
  max-width: 440px;
  margin: 20px;
  border-radius: 16px;
  border: 1.5px solid rgba(242,184,75,0.4);
  text-align: center;
  box-shadow: 0 0 60px rgba(242,184,75,0.25);
  animation: chapter-content-up 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}
@keyframes chapter-content-up {
  0% { opacity: 0; transform: translateY(40px) scale(0.95); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
.chapter-subtitle {
  font-family: "Fraunces", serif;
  color: #f2b84b;
  font-size: 12px;
  letter-spacing: 5px;
  text-transform: uppercase;
  font-weight: 600;
  margin-bottom: 14px;
}
.chapter-icon {
  font-size: 56px;
  margin: 6px 0 12px;
  filter: drop-shadow(0 4px 12px rgba(242,184,75,0.6));
  animation: chapter-icon-float 2.5s ease-in-out infinite;
}
@keyframes chapter-icon-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}
.chapter-title {
  font-family: "Fraunces", serif;
  font-size: 30px;
  font-weight: 900;
  color: #fef7e3;
  margin: 0 0 14px;
  letter-spacing: 0.3px;
  text-shadow: 0 2px 8px rgba(0,0,0,0.5), 0 0 24px rgba(242,184,75,0.3);
}
.chapter-intro-text {
  font-family: "Fraunces", serif;
  font-style: italic;
  color: #d8c9a8;
  font-size: 16px;
  line-height: 1.55;
  margin: 0 0 24px;
  letter-spacing: 0.2px;
}
.chapter-btn {
  font-size: 14px;
  padding: 12px 28px;
}

/* Match word "¡EXCELENTE!" floating */
.match-word {
  position: fixed;
  pointer-events: none;
  z-index: 9550;
  font-family: "Fraunces", ui-serif, Georgia, serif;
  font-weight: 900;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  transform: translate(-50%, 0);
  animation: word-pop 0.85s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}
@keyframes word-pop {
  0% { opacity: 0; transform: translate(-50%, 8px) scale(0.5) rotate(-3deg); }
  25% { opacity: 1; transform: translate(-50%, -8px) scale(1.18) rotate(2deg); }
  50% { transform: translate(-50%, -18px) scale(1.0) rotate(0deg); }
  100% { opacity: 0; transform: translate(-50%, -42px) scale(0.9) rotate(0deg); }
}
.match-word.combo-1 { font-size: 22px; color: #fef7e3; text-shadow: 0 2px 6px rgba(0,0,0,0.7), 0 0 12px rgba(242,184,75,0.5); }
.match-word.combo-2 { font-size: 26px; color: #f2b84b; text-shadow: 0 2px 8px rgba(0,0,0,0.8), 0 0 16px rgba(242,184,75,0.7); }
.match-word.combo-3 { font-size: 30px; color: #6fe3c1; text-shadow: 0 2px 10px rgba(0,0,0,0.9), 0 0 18px rgba(111,227,193,0.8); }
.match-word.combo-4 { font-size: 32px; color: #ff7aa3; text-shadow: 0 2px 10px rgba(0,0,0,0.9), 0 0 20px rgba(255,122,163,0.8); }
.match-word.combo-5 { font-size: 34px; color: #c89af2; text-shadow: 0 2px 10px rgba(0,0,0,0.9), 0 0 22px rgba(200,154,242,0.9); }
.match-word.combo-6 { font-size: 36px; color: #f8dc3d; text-shadow: 0 2px 12px rgba(0,0,0,1), 0 0 24px rgba(248,220,61,1); }
.match-word.combo-7 { font-size: 38px; color: #fef7e3; text-shadow: 0 2px 12px rgba(0,0,0,1), 0 0 30px #f2b84b, 0 0 6px #fef7e3; }
.match-word.combo-8 {
  font-size: 42px;
  background: linear-gradient(90deg, #f2b84b, #6fe3c1, #c89af2, #f2b84b);
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 2px 12px rgba(0,0,0,1);
  filter: drop-shadow(0 0 16px #f2b84b);
  animation: word-pop 0.85s cubic-bezier(0.2, 0.7, 0.3, 1) forwards,
             rainbow-text 1s linear infinite;
}
@keyframes rainbow-text {
  0% { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}

/* ─── NEAR-WIN BANNER ─────────────────────────────────────────
   Aparece cuando quedan 1-2 pares libres en el nivel. Empuja la
   sensación de "último esfuerzo" — momento más adictivo del juego. */
.near-win-banner {
  position: fixed;
  top: 24%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.6) rotate(-3deg);
  z-index: 9550;
  pointer-events: none;
  padding: 14px 32px;
  border-radius: 16px;
  background: linear-gradient(135deg, #ff4d6d 0%, #f2b84b 50%, #ffd76a 100%);
  border: 3px solid #1a0a02;
  box-shadow:
    0 0 32px rgba(255, 215, 106, 0.7),
    0 12px 28px rgba(0, 0, 0, 0.55),
    inset 0 2px 0 rgba(255, 255, 255, 0.4);
  display: flex; align-items: center; gap: 12px;
  animation: near-win-in 0.42s cubic-bezier(0.34, 1.6, 0.5, 1) forwards;
}
.near-win-banner.near-win-out {
  animation: near-win-out 0.4s cubic-bezier(0.5, 0, 0.75, 0) forwards;
}
.near-win-text {
  font-family: 'Fraunces', ui-serif, Georgia, serif;
  font-size: 28px;
  font-weight: 900;
  color: #1a0a02;
  letter-spacing: 0.4px;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
  position: relative;
  z-index: 2;
}
.near-win-glow {
  position: absolute;
  inset: -20px;
  background: radial-gradient(ellipse, rgba(255, 215, 106, 0.5) 0%, transparent 60%);
  z-index: 0;
  pointer-events: none;
  animation: near-win-pulse 1.4s ease-in-out infinite;
}
@keyframes near-win-in {
  0%   { opacity: 0; transform: translate(-50%, -80%) scale(0.6) rotate(-8deg); }
  60%  { opacity: 1; transform: translate(-50%, -50%) scale(1.12) rotate(2deg); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0); }
}
@keyframes near-win-out {
  0%   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -150%) scale(0.85); }
}
@keyframes near-win-pulse {
  0%, 100% { opacity: 0.6; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.08); }
}

/* Match pulse del board (cada match): zoom + saturation kick */
@keyframes match-pulse-kf {
  0%   { transform: scale(1);     filter: saturate(1) brightness(1); }
  35%  { transform: scale(1.012); filter: saturate(1.25) brightness(1.06); }
  100% { transform: scale(1);     filter: saturate(1) brightness(1); }
}
.board.match-pulse {
  animation: match-pulse-kf 0.28s cubic-bezier(0.34, 1.56, 0.64, 1);
  transform-origin: center center;
}

/* Debris: partículas grandes con animación más larga y rotación
   (la partícula sigue una parábola: --dx,--dy ya incluye gravedad) */
.match-particle.match-debris {
  width: 11px;
  height: 11px;
  border-radius: 2px;
  animation: debris-fly 1.1s cubic-bezier(0.18, 0.5, 0.4, 1) forwards;
}
@keyframes debris-fly {
  0%   { transform: translate(-50%, -50%) scale(1) rotate(0); opacity: 1; }
  60%  { opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 0px))) scale(0.4) rotate(380deg); opacity: 0; }
}


/* ════════════════════════════════════════════
   v2.6.10 — Characters dialog + Quest cards
   ════════════════════════════════════════════ */

/* Character dialog bubble */
.char-dialog {
  position: fixed; bottom: calc(20px + var(--safe-bottom)); left: 16px;
  z-index: 9700;
  display: flex; gap: 10px; align-items: flex-end;
  max-width: min(380px, 88vw);
  animation: char-rise-in 0.6s cubic-bezier(0.18, 0.9, 0.28, 1) backwards;
  pointer-events: auto; cursor: pointer;
}
.char-dialog-out { animation: char-slide-out 0.4s ease-in forwards; }
/* Retrato grande y con presencia. v2.38 — MOVIMIENTO 3D CALMO casi-real (el dueño
   pidió "que dejen de temblar"): el temblor venía del bob mecánico animando translateY
   con `filter: drop-shadow` SIN capa GPU → re-rasterizado por frame = shimmer. Fix:
   (1) promoción a capa propia (capa GPU + translateZ + backface-hidden) → render
   estable; (2) bob reemplazado por una RESPIRACIÓN/BALANCEO lento (7s) con pivote desde
   la base y un giro 3D sutil → se siente vivo y tranquilo, no mecánico. */
.char-portrait {
  width: clamp(110px, 28vw, 140px); flex-shrink: 0;
  filter: drop-shadow(0 8px 18px rgba(0,0,0,0.6));
  transform-origin: 50% 92%;            /* pivota desde los pies, como una persona parada */
  will-change: transform;
  backface-visibility: hidden;
  transform: translateZ(0);             /* capa GPU propia → sin temblor sub-pixel */
  animation: char-breathe 7s ease-in-out 0.8s infinite;
}
.char-portrait svg { width: 100%; height: auto; }
.char-bubble {
  background: rgba(14,4,24,0.96);
  backdrop-filter: blur(8px);
  padding: 12px 16px;
  border-radius: 16px 16px 16px 4px;
  border: 2px solid;
  box-shadow: 0 10px 28px rgba(0,0,0,0.55);
}
.char-name { font-family: Fraunces, serif; font-weight: 800; font-size: 14px; margin-bottom: 5px; letter-spacing: 0.4px; }
.char-msg { color: #fef7e3; font-size: 16px; line-height: 1.45; font-family: Fraunces, serif; font-style: italic; }
/* Entrada grácil: sube + escala desde 0.85 (antes era un slide-X de 0.4s, brusco). */
@keyframes char-rise-in {
  0%   { opacity: 0; transform: translateY(22px) scale(0.85); }
  60%  { opacity: 1; transform: translateY(-3px) scale(1.02); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes char-portrait-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-5px); }
}
/* v2.38 — RESPIRACIÓN 3D del personaje: lenta, orgánica, casi real. Combina respirar
   (translateY + scale leves) con un balanceo suave (rotateZ ±0.5°) y un giro 3D sutil
   (rotateY ±2° con perspective). 7s + ease-in-out → calmo, no mecánico. */
@keyframes char-breathe {
  0%   { transform: perspective(600px) translateZ(0) translateY(0)    rotateZ(0deg)    rotateY(0deg)  scale(1); }
  25%  { transform: perspective(600px) translateZ(0) translateY(-2px) rotateZ(0.5deg)  rotateY(2deg)  scale(1.008); }
  50%  { transform: perspective(600px) translateZ(0) translateY(-3px) rotateZ(0deg)    rotateY(0deg)  scale(1.014); }
  75%  { transform: perspective(600px) translateZ(0) translateY(-2px) rotateZ(-0.5deg) rotateY(-2deg) scale(1.008); }
  100% { transform: perspective(600px) translateZ(0) translateY(0)    rotateZ(0deg)    rotateY(0deg)  scale(1); }
}
@keyframes char-slide-out {
  0% { opacity: 1; }
  100% { opacity: 0; transform: translateY(12px) scale(0.92); }
}
/* Respeta "reducir movimiento": sin bob ni rise exagerado. */
.reduce-motion .char-portrait { animation: none; }
.reduce-motion .char-dialog { animation: char-rise-in 0.3s ease-out backwards; }

/* Confetti reutilizable (juice.js) — celebraciones de win en cualquier modo. */
.juice-confetti-layer { position: fixed; inset: 0; z-index: 9600; pointer-events: none; overflow: hidden; }
.juice-confetti {
  position: absolute; top: -12px; width: 10px; height: 14px; border-radius: 2px;
  opacity: 0.95; animation: juice-confetti-fall linear forwards;
}
@keyframes juice-confetti-fall {
  0%   { transform: translateY(-20px) rotate(0deg); opacity: 1; }
  100% { transform: translateY(105vh) rotate(540deg); opacity: 0.9; }
}

/* Chip de capítulo en el HUD del nivel (narrativa presente · Fase 4). */
.chapter-row { display: flex; justify-content: center; margin: 1px 0 3px; }
.chapter-chip {
  font-family: Fraunces, serif; font-size: 12px; color: #c8b8d8;
  background: rgba(58,31,90,0.40); border: 1px solid rgba(242,184,75,0.28);
  padding: 3px 12px; border-radius: 999px; letter-spacing: 0.2px;
  max-width: 92vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chapter-chip b { color: #f2b84b; font-weight: 700; }

/* Card de progreso de historia en Home (Fase 4b). */
.story-card {
  background: linear-gradient(135deg, rgba(58,31,90,0.45), rgba(139,58,74,0.30));
  border: 1px solid rgba(242,184,75,0.28); border-radius: 14px;
  padding: 12px 14px; margin: 0 0 14px;
}
.story-head { display: flex; align-items: center; gap: 12px; }
.story-icon { font-size: 30px; flex-shrink: 0; }
.story-kicker { font-size: 11px; letter-spacing: 0.6px; text-transform: uppercase; color: #f2b84b; font-weight: 700; }
.story-title { font-family: Fraunces, serif; font-size: 17px; color: #fef7e3; line-height: 1.2; margin-top: 2px; }
.story-bar { height: 6px; border-radius: 999px; background: rgba(0,0,0,0.35); margin-top: 10px; overflow: hidden; }
.story-bar-fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, #c46a2a, #f2b84b); transition: width 0.5s ease; }

/* Modal de subida de tier del Pase (Fase 5a). */
.pass-tierup-overlay {
  position: fixed; inset: 0; z-index: 9750; display: flex; align-items: center; justify-content: center;
  background: rgba(10,4,20,0.72); backdrop-filter: blur(4px); animation: char-rise-in 0.35s ease-out backwards;
}
.pass-tierup-card {
  background: linear-gradient(160deg, #3a1f5a, #1a0820); border: 2px solid #f2b84b;
  border-radius: 20px; padding: 26px 28px; text-align: center; max-width: 86vw; width: 340px;
  box-shadow: 0 18px 50px rgba(0,0,0,0.6);
}
.ptu-icon { font-size: 46px; }
.ptu-kicker { color: #f2b84b; font-weight: 800; letter-spacing: 1.5px; font-size: 12px; margin-top: 4px; }
.pass-tierup-card h2 { font-family: Fraunces, serif; color: #fef7e3; margin: 6px 0 4px; font-size: 30px; }
.pass-tierup-card p { color: #c8b8d8; font-size: 14px; margin: 0 0 16px; }
.pass-tierup-card .row { display: flex; gap: 10px; justify-content: center; }

/* Rescate del modo Triple (Pilar 2b). */
.tt-rescue-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.tt-rescue-actions .btn small { opacity: 0.85; font-weight: 600; margin-left: 4px; }

/* Daily Quest cards */
.quests-section {
  background: rgba(58,31,90,0.18);
  padding: 12px;
  border-radius: 10px;
  border: 1px solid rgba(242,184,75,0.15);
}
.quest-card {
  display: grid;
  grid-template-columns: 32px 1fr auto;
  gap: 10px; align-items: center;
  padding: 8px 10px;
  background: rgba(14,4,24,0.4);
  border-radius: 8px;
  margin-bottom: 6px;
}
.quest-card.done {
  background: rgba(111,227,193,0.12);
  border: 1px solid rgba(111,227,193,0.4);
}
.quest-card.claimed { opacity: 0.5; }
.q-icon { font-size: 22px; text-align: center; }
.q-info { min-width: 0; }
.q-label { font-size: 13px; color: #fef7e3; font-weight: 600; margin-bottom: 4px; }
.q-progress-bar { background: rgba(255,255,255,0.08); height: 5px; border-radius: 3px; overflow: hidden; }
.q-progress-fill { background: linear-gradient(90deg, #f2b84b, #6fe3c1); height: 100%; transition: width 0.4s; }
.q-progress-text { font-size: 10px; color: #a89568; margin-top: 2px; letter-spacing: 0.4px; }

/* ════════════════════════════════════════════
   v2.6.11 — Fix flicker + Reward celebration
   ════════════════════════════════════════════ */

/* Anti-flicker GPU acceleration — SOLO los 3 contenedores del tablero (barato).
   v2.25: se quitó la regla `.tile { promoción-GPU }` que promovía CADA ficha (hasta
   142 capas GPU = jank). Las fichas que animan reciben promoción GPU en su estado
   (.selected / .match-burst); el resto del tablero queda estático. */
.board-svg, .gameboard-wrap, .board {
  will-change: transform;
  transform: translateZ(0);
  backface-visibility: hidden;
}


/* ════════════════════════════════════════════
   Reward Celebration: cofre + tarjeta + partículas
   ════════════════════════════════════════════ */
.reward-celebration {
  position: fixed; inset: 0;
  z-index: 9800;
  display: flex; align-items: center; justify-content: center;
  pointer-events: auto;
}
.reward-celebration.rc-fade-out { animation: rc-fade-out 0.4s ease-in forwards; }
@keyframes rc-fade-out { to { opacity: 0; } }

.rc-backdrop {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at center, rgba(58,31,90,0.85) 0%, rgba(14,4,24,0.95) 100%);
  backdrop-filter: blur(6px);
  animation: rc-backdrop-in 0.4s ease-out;
}
@keyframes rc-backdrop-in {
  from { opacity: 0; backdrop-filter: blur(0); }
  to { opacity: 1; }
}

/* Rayos de luz radiales detrás del cofre */
.rc-rays {
  position: absolute; top: 35%; left: 50%;
  width: 600px; height: 600px;
  margin-left: -300px; margin-top: -300px;
  background: conic-gradient(from 0deg,
    rgba(248,220,61,0.0) 0deg, rgba(248,220,61,0.4) 15deg, rgba(248,220,61,0) 30deg,
    rgba(248,220,61,0) 60deg, rgba(248,220,61,0.4) 75deg, rgba(248,220,61,0) 90deg,
    rgba(248,220,61,0) 120deg, rgba(248,220,61,0.4) 135deg, rgba(248,220,61,0) 150deg,
    rgba(248,220,61,0) 180deg, rgba(248,220,61,0.4) 195deg, rgba(248,220,61,0) 210deg,
    rgba(248,220,61,0) 240deg, rgba(248,220,61,0.4) 255deg, rgba(248,220,61,0) 270deg,
    rgba(248,220,61,0) 300deg, rgba(248,220,61,0.4) 315deg, rgba(248,220,61,0) 330deg,
    rgba(248,220,61,0) 360deg);
  animation: rc-rays-rotate 12s linear infinite, rc-rays-in 0.8s ease-out;
  pointer-events: none;
  opacity: 0;
}
.reward-celebration.rc-chest-show .rc-rays { opacity: 1; }
@keyframes rc-rays-rotate {
  from { transform: rotate(0); } to { transform: rotate(360deg); }
}
@keyframes rc-rays-in { from { opacity: 0; transform: scale(0.5); } to { opacity: 1; transform: scale(1); } }

.rc-content {
  position: relative; z-index: 2;
  text-align: center;
  padding: 32px 24px;
  max-width: 380px;
}

.rc-title {
  font-family: Fraunces, serif;
  font-size: 32px;
  font-weight: 900;
  color: #fef7e3;
  text-shadow: 0 4px 16px rgba(0,0,0,0.6), 0 0 24px rgba(248,220,61,0.7);
  margin-bottom: 18px;
  letter-spacing: 0.5px;
  animation: rc-title-pop 0.6s cubic-bezier(0.2, 1.4, 0.4, 1) backwards;
}
@keyframes rc-title-pop {
  0% { opacity: 0; transform: scale(0.5) translateY(-20px); }
  60% { opacity: 1; transform: scale(1.1); }
  100% { transform: scale(1) translateY(0); }
}

/* Cofre */
.rc-chest {
  width: 200px; height: 180px;
  margin: 0 auto;
  opacity: 0;
  transform: scale(0.4) translateY(40px);
  transition: opacity 0.4s, transform 0.5s cubic-bezier(0.2, 1.2, 0.4, 1);
  filter: drop-shadow(0 12px 30px rgba(0,0,0,0.8)) drop-shadow(0 0 20px rgba(248,220,61,0.4));
}
.reward-celebration.rc-chest-show .rc-chest {
  opacity: 1;
  transform: scale(1) translateY(0);
  animation: rc-chest-shake 0.4s ease-out 0.3s;
}
@keyframes rc-chest-shake {
  0%, 100% { transform: rotate(0); }
  20% { transform: rotate(-4deg); }
  40% { transform: rotate(4deg); }
  60% { transform: rotate(-3deg); }
  80% { transform: rotate(2deg); }
}

/* Tapa del cofre se abre */
.rc-lid {
  transform-origin: 100px 88px;
  transition: transform 0.6s cubic-bezier(0.34, 1.4, 0.5, 1);
}
.reward-celebration.rc-chest-open .rc-lid {
  transform: perspective(300px) rotateX(-118deg);
}
.rc-inner-glow {
  transition: opacity 0.4s 0.2s;
}
.reward-celebration.rc-chest-open .rc-inner-glow {
  opacity: 1;
  animation: rc-inner-pulse 1.6s ease-in-out infinite 0.6s;
}
@keyframes rc-inner-pulse {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 1; }
}
/* v2.21 — halo de luz que ESTALLA al abrir */
.rc-burst { transform-origin: 100px 92px; }
.reward-celebration.rc-chest-open .rc-burst {
  animation: rc-burst-pop 0.7s ease-out forwards;
}
@keyframes rc-burst-pop {
  0% { opacity: 0; transform: scale(0.3); }
  35% { opacity: 0.95; transform: scale(1.15); }
  100% { opacity: 0; transform: scale(1.5); }
}
/* v2.21 — el tesoro (monedas+gema) asoma del cofre al abrir */
.rc-treasure { transform-origin: 100px 100px; }
.reward-celebration.rc-chest-open .rc-treasure {
  animation: rc-treasure-rise 0.6s cubic-bezier(0.2,1.3,0.4,1) forwards 0.18s;
}
@keyframes rc-treasure-rise {
  0% { opacity: 0; transform: translateY(14px) scale(0.7); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
/* candado salta y cae al abrir */
.rc-lock { transform-origin: 100px 114px; }
.reward-celebration.rc-chest-open .rc-lock {
  animation: rc-lock-burst 0.5s ease-in forwards;
}
@keyframes rc-lock-burst {
  0% { opacity: 1; transform: translateY(0) rotate(0); }
  30% { transform: translateY(-22px) rotate(-15deg); }
  100% { opacity: 0; transform: translateY(60px) rotate(40deg); }
}
/* gema con destello (brillo continuo tras abrir) */
.reward-celebration.rc-chest-open .rc-treasure { will-change: transform; }
body.reduce-motion .rc-burst,
body.reduce-motion .rc-treasure,
body.reduce-motion .rc-lock { animation: none !important; opacity: 1; }
body.reduce-motion .rc-lock { display: none; }

/* Tarjeta del premio */
.rc-card {
  margin: -20px auto 20px;
  background: linear-gradient(180deg, rgba(248,220,61,0.18), rgba(242,184,75,0.12));
  border: 2px solid #f2b84b;
  border-radius: 14px;
  padding: 18px 24px;
  min-width: 200px;
  box-shadow:
    0 0 0 3px rgba(248,220,61,0.2),
    0 8px 24px rgba(0,0,0,0.5),
    inset 0 1px 0 rgba(255,255,255,0.2);
  opacity: 0;
  transform: scale(0.7) translateY(40px);
  transition: opacity 0.5s, transform 0.5s cubic-bezier(0.2, 1.3, 0.4, 1);
}
.reward-celebration.rc-card-show .rc-card {
  opacity: 1;
  transform: scale(1) translateY(0);
  animation: rc-card-float 3s ease-in-out infinite 0.6s;
}
@keyframes rc-card-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}
.rc-card-icon {
  font-size: 44px;
  margin-bottom: 8px;
  filter: drop-shadow(0 4px 10px rgba(248,220,61,0.6));
  animation: rc-icon-spin 4s ease-in-out infinite;
}
@keyframes rc-icon-spin {
  0%, 100% { transform: rotate(0); }
  50% { transform: rotate(8deg); }
}
.rc-card-coins {
  font-family: Fraunces, serif;
  font-size: 30px;
  font-weight: 900;
  color: #f8dc3d;
  text-shadow: 0 2px 8px rgba(0,0,0,0.6), 0 0 16px rgba(248,220,61,0.6);
  letter-spacing: 1px;
}
.rc-card-item {
  font-family: Fraunces, serif;
  font-size: 16px;
  color: #fef7e3;
  margin-top: 6px;
  letter-spacing: 0.5px;
}
.rc-card-msg {
  font-family: Fraunces, serif;
  font-style: italic;
  font-size: 13px;
  color: #d8c9a8;
  margin-top: 10px;
  line-height: 1.4;
}

.rc-btn {
  background: linear-gradient(180deg, #f2b84b, #c8881d);
  border: none;
  color: #2a1804;
  padding: 12px 36px;
  border-radius: 10px;
  font-family: Fraunces, serif;
  font-weight: 800;
  font-size: 15px;
  letter-spacing: 0.5px;
  cursor: pointer;
  margin-top: 18px;
  box-shadow: 0 6px 16px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.3);
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.4s 1.2s, transform 0.4s 1.2s;
}
.rc-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0,0,0,0.6); }
.rc-btn:active { transform: translateY(0); }
.reward-celebration.rc-card-show .rc-btn {
  opacity: 1;
  transform: translateY(0);
}

/* Partículas doradas */
.rc-particles {
  position: absolute; top: 35%; left: 50%;
  width: 0; height: 0;
  pointer-events: none;
}
.rc-particle {
  position: absolute;
  width: 8px; height: 8px;
  border-radius: 50%;
  top: 0; left: 0;
  box-shadow: 0 0 8px currentColor;
  animation: rc-particle-fly 1.4s cubic-bezier(0.1, 0.6, 0.3, 1) forwards;
}
@keyframes rc-particle-fly {
  0% { opacity: 1; transform: translate(0, 0) scale(0); }
  20% { opacity: 1; transform: translate(calc(var(--dx) * 0.3), calc(var(--dy) * 0.3 - 20px)) scale(1.4); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(0.4); }
}

/* ====================================================================
   Tendencias modernas: progress bar · shuffle · climax · urgencia · diario
   ==================================================================== */

/* HUD progress bar — barra delgada pegada al fondo del HUD */
.hud { position: relative; }
.hud-progress {
  position: absolute; bottom: 0; left: 0; right: 0;
  height: 3px;
  background: rgba(0,0,0,0.3);
  overflow: hidden;
  border-radius: 0 0 var(--r-sm) var(--r-sm);
}
.hud-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--siena) 0%, var(--gold) 55%, var(--teal) 100%);
  transition: width 0.4s cubic-bezier(0.22, 0.7, 0.32, 1);
  box-shadow: 0 0 8px rgba(242, 184, 75, 0.6);
  will-change: width;
}

/* Board climax: cuando quedan ≤10 fichas, las fichas escalan despacio
   (5 segundos) para dar foco al endgame. EL FRAME (cuadro dorado) NUNCA
   se toca — solo el grupo <g class="board-tiles-layer"> dentro del SVG.
   El transform-origin viene inline del game.js (w/2, h/2 del viewBox).
   `!important` aquí es necesario porque reduce-motion global aplica
   `transition-duration: 0.01ms !important` con `*` selector — sin override
   no habría animación, sería un salto instantáneo. */
.board.board-climax .board-svg .board-tiles-layer {
  transform: scale(1.05) !important;
  transition: transform 5s cubic-bezier(0.22, 0.7, 0.32, 1) !important;
}
.board:not(.board-climax) .board-svg .board-tiles-layer {
  transform: scale(1) !important;
  transition: transform 5s cubic-bezier(0.22, 0.7, 0.32, 1) !important;
}

/* Shuffle out — fade de las fichas antes del remix */
.board-svg .tile.tile-shuffle-out {
  animation: tileShuffleOut 0.32s ease-in forwards !important;
}
@keyframes tileShuffleOut {
  0%   { opacity: 1; }
  60%  { opacity: 0.3; }
  100% { opacity: 0; }
}

/* Timer urgency — cambia de color cuando se acercan las estrellas */
#timer.timer-alert {
  color: var(--gold);
  font-weight: 700;
  transition: color 0.4s;
}
#timer.timer-warn {
  color: var(--rose);
  font-weight: 700;
  animation: timerUrgency 0.8s ease-in-out infinite;
}
@keyframes timerUrgency {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.55; }
}

/* ═══════════════════════════════════════════════════════════════
   A06: SPECIALS — golden / frozen / bomb / locked
   Mecánicas implementadas en game.js. Estos estilos los distinguen
   visualmente del resto para que el jugador identifique su rol.
   ═══════════════════════════════════════════════════════════════ */

/* SPECIALS — efectos LIGEROS para que el emoji original mande siempre.
   Antes había 3 capas de drop-shadow que tapaban la ficha; ahora una sola
   capa sutil + el color funcional vive en bordes/glow apenas perceptible.
   El jugador identifica el tipo por el TINTE de color, no por el chichón. */

/* Golden — tinte dorado leve, brillito chico al estar libre */
.board-svg .tile.special-golden {
  filter: drop-shadow(0 0 6px rgba(246, 200, 79, 0.55)) !important;
}
.board-svg .tile.special-golden.free {
  filter: drop-shadow(0 0 9px rgba(246, 200, 79, 0.80)) !important;
}

/* Bomb — tinte rojo/naranja sutil */
.board-svg .tile.special-bomb {
  filter: drop-shadow(0 0 7px rgba(255, 104, 77, 0.60)) !important;
}

/* Frozen — celeste leve, opacidad apenas reducida (se nota congelada) */
.board-svg .tile.special-frozen {
  filter: drop-shadow(0 0 6px rgba(130, 217, 255, 0.65)) !important;
  opacity: 0.92;
}

/* Locked — violeta tenue + cursor no-allowed */
.board-svg .tile.special-locked {
  filter: drop-shadow(0 0 6px rgba(141, 122, 168, 0.65)) !important;
  cursor: default !important;
}

/* Lightning — cian con un PULSO MUY SUAVE en la opacidad (no en filter,
   para no machacar el emoji) */
.board-svg .tile.special-lightning {
  filter: drop-shadow(0 0 7px rgba(122, 220, 255, 0.70)) !important;
  animation: lightningPulse 1.8s ease-in-out infinite;
}
@keyframes lightningPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.86; }
}

/* Eye — turquesa, pulso lento e imperceptible */
.board-svg .tile.special-eye {
  filter: drop-shadow(0 0 6px rgba(100, 220, 200, 0.65)) !important;
  animation: eyePulse 3.2s ease-in-out infinite;
}
@keyframes eyePulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.88; }
}

/* Peek mode (eye) — ficha bloqueada revelada por 3s con tinte turquesa */
.board-svg .tile.peek-revealed {
  filter: drop-shadow(0 0 5px rgba(100, 220, 200, 0.45)) !important;
  opacity: 0.92;
}

@media (prefers-reduced-motion: reduce) {
  .board-svg .tile.special-lightning,
  .board-svg .tile.special-eye { animation: none !important; }
}

/* Daily challenge in-game badge */
.daily-level-badge {
  display: inline-flex;
  align-items: center;
  background: linear-gradient(135deg, #f2b84b, #c46a2a);
  color: #1a0820;
  font-size: 9px;
  font-weight: 800;
  padding: 2px 7px;
  border-radius: 999px;
  letter-spacing: 0.5px;
  animation: dailyBadgePulse 2s ease-in-out infinite;
  vertical-align: middle;
  margin-left: 5px;
  line-height: 1.4;
}
@keyframes dailyBadgePulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}

/* ════════════════════════════════════════════════════════════════════
   FASE D — Polish visual estilo Supercell
   ════════════════════════════════════════════════════════════════════ */

/* D2 — Hit-flash full-screen (solo combo≥2). Destello dorado radial 160ms. */
.hit-flash-overlay {
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 60;
  background: radial-gradient(circle at 50% 55%, rgba(255,236,140,0.34) 0%, rgba(255,200,80,0.14) 38%, transparent 64%);
  animation: hitFlash 160ms ease-out forwards;
}
@keyframes hitFlash {
  0%   { opacity: 0; }
  30%  { opacity: 1; }
  100% { opacity: 0; }
}

/* ════════ v2.25 — Sensación "top": luz que respira + premio + ripple + crítico.
   TODO opacity/transform (compuesto en GPU, no repinta) → no traba el motor.
   Sutil a propósito para NO bajar el contraste del texto. reduce-motion off. ════════ */

/* Luz ambiental que sube y baja SIEMPRE — calidez de fondo "adictiva". Un solo
   elemento; concentrada arriba (donde está el cielo, lejos del texto del HUD). */
.ambient-breath {
  position: fixed; inset: 0; pointer-events: none; z-index: 1;
  background: radial-gradient(120% 70% at 50% 8%,
              rgba(255,214,106,0.085) 0%, rgba(242,184,75,0.04) 34%, transparent 60%);
  opacity: 0.4; mix-blend-mode: screen;
  animation: ambientBreath 7.5s ease-in-out infinite;
}
@keyframes ambientBreath { 0%,100% { opacity: 0.28; } 50% { opacity: 0.62; } }
.ambient-breath.flare { animation: ambientFlare 0.72s ease-out; }
@keyframes ambientFlare { 0% { opacity: 0.6; } 22% { opacity: 0.95; } 100% { opacity: 0.4; } }

/* Destello CÁLIDO en premios (match/combo/win/cofre) — "la luz cuando hay premio".
   Intensidad por variables que setea juice.js (combo grande = ilumina más). */
.reward-glow {
  position: fixed; inset: 0; pointer-events: none; z-index: 58;
  background: radial-gradient(circle at 50% 55%,
              hsla(var(--rg-hue, 44), 100%, 72%, 0.85) 0%,
              hsla(var(--rg-hue, 44), 95%, 60%, 0.30) 30%, transparent 60%);
  opacity: 0; transform: scale(var(--rg-scale, 1)); mix-blend-mode: screen;
  animation: rewardGlowPulse 0.7s ease-out forwards;
  will-change: opacity, transform;
}
@keyframes rewardGlowPulse {
  0%   { opacity: 0; transform: scale(0.7); }
  28%  { opacity: var(--rg-op, 0.6); transform: scale(var(--rg-scale, 1)); }
  100% { opacity: 0; transform: scale(calc(var(--rg-scale, 1) * 1.18)); }
}

/* Ripple al tocar una ficha — feedback inmediato (técnica de juegos top). */
.tap-ripple {
  position: fixed; pointer-events: none; z-index: 57;
  width: var(--ripple-size, 30px); height: var(--ripple-size, 30px);
  margin-left: calc(var(--ripple-size, 30px) / -2);
  margin-top: calc(var(--ripple-size, 30px) / -2);
  border-radius: 50%; border: 2px solid var(--ripple-color, rgba(255,215,106,0.95));
  opacity: 0.9; transform: scale(0.3);
  animation: tapRippleAnim 0.5s cubic-bezier(0.2,0.7,0.3,1) forwards;
  will-change: opacity, transform;
}
@keyframes tapRippleAnim { 0% { opacity: 0.9; transform: scale(0.3); } 100% { opacity: 0; transform: scale(2.6); } }

/* Flash crítico breve (combo ≥ 5) — pico visual de "golpe crítico". v2.27: cálido
   y suave (antes blanco 0.5 = se sentía duro/"semi-pro"); ahora un destello dorado
   tenue que se integra con la paleta. */
.crit-flash {
  position: fixed; inset: 0; pointer-events: none; z-index: 59;
  background: radial-gradient(circle at 50% 50%, rgba(255,236,180,0.42) 0%, rgba(255,214,106,0.16) 45%, transparent 70%);
  opacity: 0; mix-blend-mode: screen;
  animation: critFlashAnim 0.3s ease-out forwards;
}
@keyframes critFlashAnim { 0% { opacity: 0; } 22% { opacity: 0.9; } 100% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .ambient-breath { animation: none !important; opacity: 0.28; }
  .reward-glow, .tap-ripple, .crit-flash { display: none !important; }
}

/* Shimmer: un brillo que cruza el botón principal cada tanto (atrae el ojo →
   técnica de retención). Solo transform/opacity en un ::after, barato. */
#btnPlay { position: relative; overflow: hidden; }
#btnPlay::after {
  content: ''; position: absolute; top: 0; left: -65%; width: 55%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,0.45), transparent);
  transform: skewX(-18deg); pointer-events: none;
  animation: shimmerSweep 4.5s ease-in-out infinite;
}
@keyframes shimmerSweep {
  0%, 68% { transform: translateX(-160%) skewX(-18deg); }
  100% { transform: translateX(200%) skewX(-18deg); }
}
.win-dialog .win-title, .reveal-title { position: relative; overflow: hidden; }
.win-dialog .win-title::after {
  content: ''; position: absolute; inset: 0; left: -65%; width: 55%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,0.5), transparent);
  transform: skewX(-18deg); pointer-events: none;
  animation: shimmerSweep 3.2s ease-in-out 0.4s infinite;
}
@media (prefers-reduced-motion: reduce) {
  #btnPlay::after, .win-dialog .win-title::after { display: none !important; }
}

/* D5 — Escalada de combo: glow del score en el HUD.
   v2.27 PERF: se QUITÓ el `filter: saturate/brightness` sobre TODO #screen — animar
   un filtro full-screen en cada combo hitcheaba el celular justo al encadenar
   (se sentía como un "salto"). La reacción de pantalla al combo ahora la da el
   reward-glow (juice.js, opacity → GPU), que escala con el combo sin repintar. */
body.combo-3 .gameboard-wrap .hud-stat.score .v { text-shadow: 0 0 10px rgba(242,184,75,0.7); }
body.combo-5 .gameboard-wrap .hud-stat.score .v {
  text-shadow: 0 0 16px rgba(242,184,75,0.9);
  animation: comboHudPulse 0.4s ease-out;
}
body.combo-7 .gameboard-wrap .hud-stat.score .v {
  text-shadow: 0 0 22px rgba(255,180,48,1), 0 0 6px #fff;
  animation: comboHudPulse 0.4s ease-out;
  color: #ffd76a;
}
@keyframes comboHudPulse {
  0% { transform: scale(1); }
  45% { transform: scale(1.28); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .hit-flash-overlay { display: none !important; }
}

/* D1 — Monedas que vuelan al contador (Supercell signature). Las anima WAAPI
   desde JS; acá solo el look del elemento volador. */
.coin-fly {
  position: fixed;
  z-index: 10000;
  font-size: 22px;
  line-height: 1;
  pointer-events: none;
  filter: drop-shadow(0 2px 4px rgba(180,120,20,0.6));
  will-change: transform, opacity;
}

/* D1b — Mini-contador de coins del win-overlay (destino de la coin-fly,
   porque el wallet del Home queda tapado por el overlay). */
.win-coin-target {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(0,0,0,0.32);
  border: 1px solid rgba(242,184,75,0.5);
  border-radius: 999px;
  padding: 4px 12px;
  font-weight: 800; font-size: 16px;
  color: var(--gold);
}
.win-coin-target.coin-bump,
.coin-bump { animation: coinBump 0.3s ease-out; }   /* v2.19: genérico (chip topbar) */
@keyframes coinBump {
  0% { transform: scale(1); }
  50% { transform: scale(1.18); }
  100% { transform: scale(1); }
}
.reduce-motion .coin-bump { animation: none; }

/* D3 — Feedback de boosters armados (modo activo a la espera de target). */
.booster-armed-badge {
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: calc(86px + var(--safe-bottom));
  z-index: 9002;
  background: linear-gradient(135deg, #5a2548, #c46a2a);
  color: #fff; font-weight: 800; font-size: 13px;
  padding: 7px 16px; border-radius: 999px;
  border: 1px solid rgba(255,215,106,0.6);
  box-shadow: 0 6px 18px rgba(0,0,0,0.5);
  pointer-events: none; white-space: nowrap;
  animation: armedBadgeIn 0.3s cubic-bezier(0.34,1.56,0.64,1);
}
@keyframes armedBadgeIn {
  from { opacity: 0; transform: translateX(-50%) translateY(10px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
/* D3b — glow rojo pulsante cuando queda 1 uso del booster (urgencia). */
.booster .count.last-use {
  color: #ffd0d0;
  animation: lastUseBlink 1s ease-in-out infinite;
}
@keyframes lastUseBlink {
  0%, 100% { text-shadow: 0 0 0 transparent; }
  50%      { text-shadow: 0 0 8px rgba(255,80,80,0.95); color: #fff; }
}

/* D4 — Tema visual por mundo: tinta el HALO superior del fondo del juego con
   la paleta del mundo. El board mantiene su frame propio y el HUD su fondo
   oscuro → la legibilidad NO se ve afectada (verificado puna noche + carnaval).
   Solo cambia el color del aura superior, reforzando la identidad del mundo. */
body.world-san_salvador .gameboard-wrap {
  background:
    radial-gradient(ellipse at 50% -10%, #2d3a6a 0%, transparent 52%),
    radial-gradient(ellipse at 50% 110%, #5a3a28 0%, transparent 55%),
    var(--bg);
}
body.world-valles .gameboard-wrap {
  background:
    radial-gradient(ellipse at 50% -10%, #2a5a3e 0%, transparent 52%),
    radial-gradient(ellipse at 50% 110%, #4a3a1e 0%, transparent 55%),
    var(--bg);
}
body.world-quebrada .gameboard-wrap {
  background:
    radial-gradient(ellipse at 50% -10%, #7a3a1e 0%, transparent 52%),
    radial-gradient(ellipse at 50% 110%, #5a2520 0%, transparent 55%),
    var(--bg);
}
body.world-carnaval .gameboard-wrap {
  background:
    radial-gradient(ellipse at 50% -10%, #6a1f5a 0%, transparent 52%),
    radial-gradient(ellipse at 50% 110%, #7a1f3a 0%, transparent 55%),
    var(--bg);
}
body.world-puna .gameboard-wrap {
  background:
    radial-gradient(ellipse at 50% -10%, #1e2a52 0%, transparent 52%),
    radial-gradient(ellipse at 50% 110%, #2a2440 0%, transparent 55%),
    var(--bg);
}
body.world-cielo .gameboard-wrap {
  background:
    radial-gradient(ellipse at 50% -10%, #3a2a72 0%, transparent 52%),
    radial-gradient(ellipse at 50% 110%, #2a3a6a 0%, transparent 55%),
    var(--bg);
}

/* ════════════════════════════════════════════════════════════════════
   FASE B — Modo Triple Tile
   ════════════════════════════════════════════════════════════════════ */

/* Cards de selección de modo en Home */
.mode-cards {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  margin-top: 12px;
}
.mode-card {
  position: relative;
  background: var(--bg-elev);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--r);
  padding: 14px 10px;
  display: grid; gap: 3px; place-items: center;
  cursor: pointer; font-family: inherit; color: var(--ink);
  transition: transform .1s, border-color .15s, box-shadow .15s;
}
.mode-card:active { transform: scale(0.96); }
.mode-card .mode-emoji { font-size: 30px; line-height: 1; }
.mode-card .mode-name { font-weight: 800; font-size: 14px; }
.mode-card .mode-desc { font-size: 11px; color: var(--ink-dim); }
.mode-card.mode-triple {
  border-color: rgba(242,184,75,0.45);
  background: linear-gradient(160deg, #3a2354, #2a1538);
}
.mode-card.mode-triple:hover { box-shadow: 0 0 16px rgba(242,184,75,0.4); }
.mode-badge-new {
  position: absolute; top: -7px; right: 8px;
  background: linear-gradient(135deg, #6fe3c1, #3a8a72);
  color: #06231b; font-size: 9px; font-weight: 800;
  padding: 2px 7px; border-radius: 999px; letter-spacing: 0.5px;
  animation: dailyBadgePulse 2s ease-in-out infinite;
}

/* Menú de stages */
.tt-menu { padding: 12px 14px 80px; }
.tt-menu-hero { text-align: center; margin: 8px 0 18px; }
.tt-kicker {
  display: inline-block; font-size: 11px; font-weight: 800; letter-spacing: 1px;
  color: #6fe3c1; margin-bottom: 6px;
}
.tt-menu-title {
  font-family: var(--font-display); font-size: 30px; margin: 0 0 6px;
  color: var(--gold);
}
.tt-menu-sub { font-size: 13px; color: var(--ink-dim); margin: 0; }
.tt-stage-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 10px; margin-top: 14px;
}
.tt-stage-card {
  position: relative; aspect-ratio: 1;
  background: var(--bg-elev); border: 1px solid rgba(255,255,255,0.08);
  border-radius: 14px; cursor: pointer; font-family: inherit; color: var(--ink);
  display: grid; place-items: center; gap: 2px;
  transition: transform .1s, box-shadow .15s;
}
.tt-stage-card:active { transform: scale(0.94); }
.tt-stage-card.done { border-color: rgba(111,227,193,0.5); }
.tt-stage-card.locked { opacity: 0.5; cursor: default; }
.tt-stage-num { font-size: 24px; font-weight: 800; font-family: var(--font-display); }
.tt-stage-meta { font-size: 10px; color: var(--ink-dim); }
.tt-stage-world { font-size: 9px; color: var(--ink-dim); text-transform: uppercase; letter-spacing: 0.4px; }
.tt-stage-check { position: absolute; top: 5px; right: 7px; color: #6fe3c1; font-size: 13px; }
.tt-stage-lock { position: absolute; top: 5px; right: 7px; font-size: 13px; }
.tt-stage-best { position: absolute; bottom: 4px; left: 0; right: 0; font-size: 9px; color: var(--gold); }
.tt-menu-progress { font-size: 12px; color: var(--ink-dim); margin: 8px 0 0; }

/* Campaña por mundos (v2.17) — espejo del mapa clásico */
.tt-world-section { margin: 0 0 22px; }
.tt-world-section.world-locked { opacity: 0.6; }
.tt-world-header { display: flex; align-items: center; gap: 10px; margin: 6px 2px 9px; }
.tt-world-name { font-family: var(--font-display); font-size: 17px; color: var(--gold); white-space: nowrap; }
.tt-world-prog { flex: 1; height: 7px; border-radius: 99px; background: rgba(255,255,255,0.1); overflow: hidden; }
.tt-world-prog-fill { height: 100%; background: linear-gradient(90deg, #6fe3c1, #43c59e); border-radius: 99px; transition: width .3s; }
.tt-world-count { font-size: 11px; color: var(--ink-dim); white-space: nowrap; min-width: 42px; text-align: right; }
/* grilla densa para campañas de 100 niveles por mundo */
.tt-stage-grid.dense { grid-template-columns: repeat(auto-fill, minmax(50px, 1fr)); gap: 7px; margin-top: 0; }
.tt-stage-grid.dense .tt-stage-card { border-radius: 11px; }
.tt-stage-grid.dense .tt-stage-num { font-size: 16px; }
.tt-stage-stars { font-size: 9px; color: var(--gold); letter-spacing: -1px; line-height: 1; }

/* Tablero de juego (fullscreen, igual que gameboard-wrap) */
.tt-wrap {
  position: fixed; inset: 0; z-index: 50;
  display: grid; grid-template-rows: auto auto 1fr auto;
  background:
    radial-gradient(ellipse at 50% -10%, #3a2a72 0%, transparent 52%),
    radial-gradient(ellipse at 50% 110%, #2a2440 0%, transparent 55%),
    var(--bg);
}
.tt-hud {
  display: flex; align-items: center; gap: 8px;
  padding: calc(6px + var(--safe-top)) 12px 6px;
  background: rgba(0,0,0,0.25); backdrop-filter: blur(8px);
}
.tt-hud-title { font-weight: 800; font-size: 14px; flex: 1; }
.tt-hud-prog { width: 90px; height: 7px; background: rgba(0,0,0,0.4); border-radius: 5px; overflow: hidden; }
.tt-hud-prog-fill { height: 100%; background: linear-gradient(90deg, #6fe3c1, #3a8a72); transition: width .3s; }

/* Bandeja de 7 slots — ARRIBA (la "línea" que pidió la usuaria) */
.tt-tray {
  display: flex; gap: 5px; justify-content: center;
  padding: 14px 14px; background: rgba(0,0,0,0.18);
  border-bottom: 1px solid rgba(255,255,255,0.06);
  box-shadow: 0 -4px 12px rgba(0,0,0,0.3);   /* v2.29: elevación, paridad con el clásico */
}
.tt-slot {
  width: 42px; height: 52px; border-radius: 8px;
  background: rgba(255,255,255,0.05);
  border: 1.5px dashed rgba(255,255,255,0.14);
  display: grid; place-items: center;
  transition: background .15s, transform .15s;
}
.tt-slot.filled {
  background: #f6efe1; border: 1px solid rgba(40,25,12,0.6);
  box-shadow: 0 3px 6px rgba(0,0,0,0.4);
  animation: ttSlotIn .2s cubic-bezier(0.34,1.56,0.64,1);
}
.tt-slot-emoji { font-size: 26px; line-height: 1; }
@keyframes ttSlotIn { from { transform: scale(0.5); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* Área de pilas */
/* Tablero Mahjong INTERCALADO (v2.16): fichas posicionadas absolutamente por
   (x,y,z) en geometría cruzada — mismas constantes que el clásico. */
.tt-board { overflow: auto; padding: min(24px, 5vh) 16px; display: flex; justify-content: center; align-items: flex-start; }   /* v2.29: margen seguro alrededor de las fichas del Triple */
.tt-board-inner { position: relative; margin: 0 auto; flex: none; }
.tt-tile {
  position: absolute;
  border-radius: 6px; background: #f6efe1;
  border: 1px solid rgba(40,25,12,0.8);
  display: grid; place-items: center;
  /* v2.47 — PARIDAD con la ficha del clásico: canto 3D de MARFIL (tonos cálidos
     escalonados que imitan el gradiente bone-side del SVG + línea oscura de
     cierre), no la mancha translúcida vieja. Elevación aparte. */
  box-shadow:
    1px 1px 0 #e9d8ab,
    2px 2px 0 #d2ba85,
    3px 3px 0 #a78c5c,
    3.6px 3.6px 0 rgba(40,25,12,0.7),
    2px 6px 9px rgba(0,0,0,0.45);
}
/* Banda dorada de familia arriba — la misma de la cara del clásico. */
.tt-tile::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 6px;
  background: rgba(244,180,48,0.18); border-radius: 6px 6px 0 0; pointer-events: none;
}
/* v2.48 — PARIDAD con el clásico: TODAS las fichas se ven (casi) iguales — la
   regla de oro del board clásico. El oscurecido fuerte de las tapadas las hacía
   ver "sucias/viejas". Queda un susurro de diferencia + el deny-shake al tocar. */
.tt-tile.covered { filter: brightness(0.965) saturate(0.95); }
.tt-tile.free { cursor: pointer; box-shadow:
    1px 1px 0 #e9d8ab,
    2px 2px 0 #d2ba85,
    3px 3px 0 #a78c5c,
    3.6px 3.6px 0 rgba(40,25,12,0.7),
    2px 8px 14px rgba(0,0,0,0.55);
  transition: box-shadow .12s, filter .12s, transform .08s; }
.tt-tile.free:hover { box-shadow: 0 0 0 2px var(--gold),
    1px 1px 0 #e9d8ab,
    2px 2px 0 #d2ba85,
    3px 3px 0 #a78c5c,
    3.6px 3.6px 0 rgba(40,25,12,0.7),
    2px 10px 18px rgba(0,0,0,0.6);
  filter: brightness(1.07); }
.tt-tile.free:active { transform: scale(0.93); }
/* v2.17 animaciones gloriosas */
.tt-tile.tt-deny { animation: ttDeny 0.32s ease; }
@keyframes ttDeny {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px) rotate(-2deg); }
  60% { transform: translateX(4px) rotate(2deg); }
}
.tt-fly { pointer-events: none; border-radius: 6px; background: #f6efe1;
  border: 1px solid rgba(40,25,12,0.8); display: grid; place-items: center;
  box-shadow: 0 0 0 2px var(--gold),
    1px 1px 0 #e9d8ab, 2px 2px 0 #d2ba85, 3px 3px 0 #a78c5c,
    0 8px 20px rgba(0,0,0,0.6); }
.tt-tray.tt-collapse-flash { animation: ttTrayFlash 0.42s ease; }
@keyframes ttTrayFlash {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}
body.reduce-motion .tt-tile.tt-deny,
body.reduce-motion .tt-tray.tt-collapse-flash { animation: none; }

/* Polvo de estrellas (v2.18) — compartido por el clásico y el Triple */
.star-dust {
  position: fixed; z-index: 96; pointer-events: none;
  color: #ffe79a; text-shadow: 0 0 6px #ffd76a, 0 0 13px #fff3c4;
  transform: translate(-50%, -50%); will-change: transform, opacity;
  animation: starDustFly 0.6s cubic-bezier(.2,.7,.3,1) forwards;
}
@keyframes starDustFly {
  0%   { transform: translate(-50%,-50%) translate(0,0) scale(.2) rotate(0); opacity: 0; }
  22%  { opacity: 1; transform: translate(-50%,-50%) translate(calc(var(--dx)*.3), calc(var(--dy)*.3)) scale(1.05) rotate(calc(var(--rot)*.3)); }
  100% { transform: translate(-50%,-50%) translate(var(--dx), var(--dy)) scale(.3) rotate(var(--rot)); opacity: 0; }
}
body.reduce-motion .star-dust { display: none; }
/* v2.47 — emoji y nombre IGUALES al clásico: emoji 28px, nombre directo sobre
   la cara (sin la cajita blanca translúcida que lo hacía ver "de otro juego").
   v2.48 — nombres largos en 2 líneas balanceadas (como el clásico), nunca "…". */
.tt-tile-emoji { font-size: 28px; line-height: 1; pointer-events: none; margin-top: -8px; }
.tt-tile-label {
  position: absolute; bottom: 3px; left: 1px; right: 1px;
  font-size: 9px; font-weight: 800; color: #2a1a08;
  text-align: center; pointer-events: none; line-height: 1.02;
  white-space: nowrap; overflow: hidden;
  font-family: 'Sora','Inter',system-ui,sans-serif;
}
.tt-tile-label.sm  { font-size: 8px; }
.tt-tile-label.xs  { font-size: 7px; }
.tt-tile-label.two { font-size: 7.5px; bottom: 2px; white-space: normal; }
.tt-tile.covered .tt-tile-label { opacity: 0.82; }
.tt-hint { text-align: center; font-size: 12px; color: var(--ink-dim); padding: 8px calc(8px + var(--safe-bottom)); }

/* End overlay */
.tt-end-overlay {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(0,0,0,0.72); backdrop-filter: blur(6px);
  display: grid; place-items: center;
  animation: fadein .2s ease-out;
}
.tt-end-dialog {
  background: linear-gradient(180deg, #3a2354, #2a1538);
  border: 1px solid rgba(242,184,75,0.3); border-radius: 20px;
  padding: 24px 22px; text-align: center; max-width: 320px;
  animation: dialogin .25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.tt-end-dialog h2 { margin: 0 0 10px; font-family: var(--font-display); }
.tt-end-stars { font-size: 32px; color: var(--gold); margin: 8px 0; }
.tt-end-reward { font-size: 18px; font-weight: 800; color: var(--gold); }
.tt-end-sub { font-size: 13px; color: var(--ink-dim); }
.tt-end-dialog .row { margin-top: 16px; display: flex; gap: 10px; justify-content: center; }

/* v2.23 — overlay de RESCATE (bandeja llena): translúcido + diálogo abajo, para
   que el jugador VEA la bandeja y el tablero mientras decide. Nunca pierde acá. */
.tt-rescue-overlay {
  background: rgba(10,4,20,0.32); backdrop-filter: blur(2px);
  place-items: end center; padding-bottom: calc(18px + var(--safe-bottom));
}
.tt-rescue-overlay .tt-end-dialog {
  background: linear-gradient(180deg, rgba(58,35,84,0.97), rgba(42,21,56,0.99));
  box-shadow: 0 -8px 30px rgba(0,0,0,0.5); max-width: 360px; width: calc(100% - 28px);
}
.tt-rescue-overlay .btn[disabled] { opacity: 0.4; pointer-events: none; }
body.reduce-motion .tt-rescue-overlay, body.reduce-motion .tt-rescue-overlay .tt-end-dialog { animation: none; }

/* ───── Ligas / ranking (v2.19) ───── */
.league-loading { text-align: center; color: var(--ink-dim); padding: 30px 0; }
.league-banner {
  display: flex; justify-content: space-between; align-items: center;
  background: linear-gradient(135deg, #2d1840, #3a1f5a);
  border: 1px solid rgba(242,184,75,0.3); border-radius: var(--r);
  padding: 12px 16px; margin-bottom: 12px;
}
.league-banner .lg-mine { font-size: 14px; }
.league-banner .lg-mine strong { color: var(--gold); }
.league-banner .lg-mode { font-size: 11px; color: var(--ink-dim); }
.league-list { display: flex; flex-direction: column; gap: 5px; }
.league-row {
  display: grid; grid-template-columns: 46px 1fr auto; align-items: center; gap: 10px;
  background: var(--bg-elev); border: 1px solid rgba(255,255,255,0.06);
  border-radius: 12px; padding: 10px 14px;
}
.league-row.me { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold), 0 0 14px rgba(242,184,75,0.25); }
.league-row .lg-rank { font-weight: 800; font-size: 16px; text-align: center; }
.league-row .lg-name { font-size: 14px; font-weight: 600; }
.league-row .lg-score { font-size: 13px; color: var(--gold); font-weight: 700; }

/* ════ v2.46 — escena del mundo DE FONDO del tablero (doc 09 §8c) ════
   La misma escena del mapa, con velo oscuro, detrás de las fichas: el nivel
   se siente EN el mundo (Hornocal, carnaval, salar…). Un solo paint inicial,
   cero costo por frame (sin filtros, sin animación). Las fichas mandan. */
.board > .board-backdrop {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  border-radius: inherit; overflow: hidden; opacity: 0.55;
}
.board > .board-backdrop svg { width: 100%; height: 100%; display: block; }
.board > .board-svg { position: relative; z-index: 1; }
.board > .board-sheen { z-index: 2; }

/* v2.46 — Triple: la MISMA escena de mundo de fondo que el clásico (cohesión
   visual entre los dos modos). Absolute → no participa del grid del tt-wrap. */
.tt-wrap > .tt-backdrop {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  opacity: 0.42; overflow: hidden;
}
.tt-wrap > .tt-backdrop svg { width: 100%; height: 100%; display: block; }
.tt-wrap > .tt-hud, .tt-wrap > .tt-tray, .tt-wrap > .tt-board, .tt-wrap > .tt-hint {
  position: relative; z-index: 1;
}

/* v2.46 — anti "salto de pantalla" (desktop): la barra de scroll aparecía y
   desaparecía con overlays/banners y TODO el layout se corría unos px al
   medio de la partida. Reservar el gutter elimina ese brinco; en móvil no
   cambia nada (no hay scrollbar clásica). */
html { scrollbar-gutter: stable; }
