/* =========================================================================
 * app.css — Hoja de estilos de la aplicación (Fase 3).
 *
 * Extrae y consolida los estilos de disenos-juego.html: variables de tema
 * claro/oscuro, tipografía, y los componentes reutilizables (.card, .btn,
 * .pill, .barwrap, .row, .grid, .input, etc.). El tema se controla con el
 * atributo data-theme en <html> (o <body>), escrito server-side desde
 * users.theme. La estética pixelada (.pix) se mantiene para coherencia
 * con el diseño orientado a niños.
 *
 * Las pantallas posteriores (ronda, plantas, ranking, etc.) reutilizan
 * estos mismos componentes; las fases siguientes añaden aquí lo que falte.
 * ========================================================================= */

/* -------------------------------------------------------------------------
 * Variables de tema
 * ----------------------------------------------------------------------- */
:root{
  --bg:#f4f2ea; --surface:#ffffff; --surface2:#ece9df; --surface3:#dedacd;
  --text:#2c2c2a; --text2:#5f5e5a; --text3:#8a897f; --border:rgba(0,0,0,.12);
  --info-bg:#e6f1fb; --info:#185fa5; --info-border:#378add;
  --ok-bg:#e1f5ee; --ok:#0f6e56; --warn-bg:#faeeda; --warn:#854f0b;
  --danger-bg:#fcebeb; --danger:#a32d2d;
  --mono:ui-monospace,SFMono-Regular,Menlo,monospace;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --r-md:8px; --r-lg:12px;
  --bar:#378add;
}

[data-theme="dark"]{
  --bg:#161512; --surface:#211f1b; --surface2:#2a2823; --surface3:#36332c;
  --text:#f1efe8; --text2:#b4b2a9; --text3:#888780; --border:rgba(255,255,255,.14);
  --info-bg:#0c2138; --info:#85b7eb; --info-border:#378add;
  --ok-bg:#0f2b24; --ok:#5dcaa5; --warn-bg:#3a2a10; --warn:#fac775;
  --danger-bg:#3a1414; --danger:#f09595;
}

/* -------------------------------------------------------------------------
 * Paletas de color (Fase 17)
 *
 * El "modo" (claro/oscuro) lo sigue fijando data-theme y controla fondos y
 * textos. La "paleta" tiñe los ACENTOS (botón primario, barra de experiencia,
 * enlaces, info, bordes destacados) y, además, da un TINTE SUAVE al fondo y a
 * las superficies, manteniendo el texto legible. Modo y paleta son
 * independientes y combinables (p. ej. oscuro + rosa, claro + verde).
 *
 * Cada paleta define cuatro variables de acento:
 *   --accent         color principal del acento
 *   --accent-strong  variante intensa (bordes/hover)
 *   --accent-soft    fondo tenue del acento (usado por --info-bg)
 *   --on-accent      color del texto sobre el acento (normalmente blanco)
 * y un tinte de fondo:
 *   --tint           color con el que se matiza el fondo y las superficies
 *
 * Se reconectan a las variables que ya usa todo el proyecto (--bar, --info,
 * --info-border, --info-bg), de modo que no hay que tocar cada componente.
 * 'default' reproduce exactamente el azul original (no cambia nada).
 * ----------------------------------------------------------------------- */

:root,
[data-palette="default"]{
  --accent:#378add; --accent-strong:#185fa5; --accent-soft:#e6f1fb;
  --on-accent:#ffffff; --tint:#378add;
}
[data-palette="pink"]  { --accent:#e2649e; --accent-strong:#b13c77; --accent-soft:#fbe7f1; --on-accent:#ffffff; --tint:#e2649e; }
[data-palette="blue"]  { --accent:#3a7bd5; --accent-strong:#1f4fa5; --accent-soft:#e6eefb; --on-accent:#ffffff; --tint:#3a7bd5; }
[data-palette="red"]   { --accent:#e24b4a; --accent-strong:#a32d2d; --accent-soft:#fcebeb; --on-accent:#ffffff; --tint:#e24b4a; }
[data-palette="green"] { --accent:#3da876; --accent-strong:#0f6e56; --accent-soft:#e1f5ee; --on-accent:#ffffff; --tint:#3da876; }
[data-palette="purple"]{ --accent:#8b5fd0; --accent-strong:#5f3ca5; --accent-soft:#efe7fb; --on-accent:#ffffff; --tint:#8b5fd0; }
[data-palette="orange"]{ --accent:#ef9f27; --accent-strong:#a06410; --accent-soft:#faeeda; --on-accent:#2c2c2a; --tint:#ef9f27; }

/* Reconexión de los acentos: las variables existentes toman el color de la
   paleta. Así .bar, los enlaces, .info y los bordes destacados se tiñen solos. */
[data-palette]{
  --bar:var(--accent);
  --info:var(--accent-strong);
  --info-border:var(--accent);
  --info-bg:var(--accent-soft);
}

/* Tinte suave del fondo y las superficies (modo CLARO).
   color-mix mezcla el neutro original con una pizca de --tint: el fondo deja de
   ser gris y toma un matiz del color elegido, sin perder contraste con el texto.
   Si el navegador no soporta color-mix, se conservan los neutros (el @supports
   no aplica y quedan los valores base de :root). */
@supports (background: color-mix(in srgb, red 10%, white)){
  [data-palette]:not([data-palette="default"]){
    --bg:      color-mix(in srgb, var(--tint) 7%,  #f4f2ea);
    --surface: color-mix(in srgb, var(--tint) 4%,  #ffffff);
    --surface2:color-mix(in srgb, var(--tint) 9%,  #ece9df);
    --surface3:color-mix(in srgb, var(--tint) 13%, #dedacd);
  }
  /* En modo OSCURO el tinte es más sutil para no levantar demasiado el fondo. */
  [data-theme="dark"][data-palette]:not([data-palette="default"]){
    --bg:      color-mix(in srgb, var(--tint) 8%,  #161512);
    --surface: color-mix(in srgb, var(--tint) 7%,  #211f1b);
    --surface2:color-mix(in srgb, var(--tint) 10%, #2a2823);
    --surface3:color-mix(in srgb, var(--tint) 14%, #36332c);
  }
}

/* -------------------------------------------------------------------------
 * Base
 * ----------------------------------------------------------------------- */
*{box-sizing:border-box}

body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:var(--sans);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  display:flex;
  flex-direction:column;
  min-height:100vh;
}

a{color:var(--info)}

.pix{image-rendering:pixelated;image-rendering:crisp-edges}

/* -------------------------------------------------------------------------
 * Cabecera del jugador (layout base)
 * ----------------------------------------------------------------------- */
header.top{
  position:sticky;top:0;z-index:10;
  background:var(--surface);
  border-bottom:.5px solid var(--border);
  display:flex;align-items:center;justify-content:space-between;
  gap:16px;padding:14px 22px;flex-wrap:wrap;
}
header.top .brand{
  font-size:18px;font-weight:500;margin:0;
  display:flex;align-items:center;gap:10px;
  color:var(--text);text-decoration:none;
}
header.top .stats{display:flex;align-items:center;gap:10px;flex-wrap:wrap}

/* -------------------------------------------------------------------------
 * Contenedor y pie
 * ----------------------------------------------------------------------- */
main.app{flex:1;width:100%;max-width:920px;margin:0 auto;padding:30px 22px 60px}
main.auth{flex:1;display:flex;align-items:center;justify-content:center;padding:30px 18px}

footer.foot{
  border-top:.5px solid var(--border);
  padding:16px 22px;
  font-size:12px;color:var(--text3);
  text-align:center;
}

/* -------------------------------------------------------------------------
 * Componentes
 * ----------------------------------------------------------------------- */
.card{background:var(--surface);border:.5px solid var(--border);border-radius:var(--r-lg)}

.btn{
  background:transparent;border:.5px solid var(--border);color:var(--text);
  border-radius:var(--r-md);padding:8px 14px;font-size:14px;font-family:inherit;
  cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  text-decoration:none;
}
.btn:hover{background:var(--surface2)}
/* Botón primario: usa el acento SÓLIDO de la paleta activa (Fase 17). El acento
   y su color de texto los define la paleta; en 'default' equivale al azul. */
.btn.primary{background:var(--accent);border-color:var(--accent-strong);color:var(--on-accent)}
.btn.primary:hover{background:var(--accent-strong)}
.btn[disabled],.btn.is-disabled{opacity:.55;cursor:default;pointer-events:none}

.input{
  width:100%;height:38px;padding:0 12px;border:.5px solid var(--border);
  border-radius:var(--r-md);background:var(--surface);color:var(--text);
  font-family:inherit;font-size:14px;
}

.row{display:flex;align-items:center;gap:12px}
.grid{display:grid;gap:14px}

.pill{font-size:11px;padding:3px 9px;border-radius:var(--r-md);font-weight:500}

.muted{color:var(--text2)}
.hint{color:var(--text3)}

.barwrap{height:8px;background:var(--surface3);border-radius:999px;overflow:hidden}
.bar{height:100%;background:var(--bar)}

.alert{
  border-radius:var(--r-md);padding:10px 12px;font-size:13px;margin-bottom:14px;
  background:var(--danger-bg);color:var(--danger);border:.5px solid var(--danger);
}
.alert.ok{background:var(--ok-bg);color:var(--ok);border-color:var(--ok)}

/* -------------------------------------------------------------------------
 * Hub (menú principal)
 * ----------------------------------------------------------------------- */
.hub-frame{
  background:var(--surface2);border:.5px solid var(--border);
  border-radius:var(--r-lg);padding:24px;position:relative;overflow:hidden;
}
.hub-stars{position:absolute;top:10px;left:0;width:100%;height:70px;opacity:.5}

.hub-head{
  display:flex;align-items:center;justify-content:space-between;
  flex-wrap:wrap;gap:14px;margin-bottom:18px;position:relative;
}

.hub-zones{
  display:grid;gap:14px;position:relative;
  grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
}
/* Cada zona es una tarjeta-enlace; hereda el aspecto de .card. */
.zone{
  display:block;padding:20px;color:inherit;text-decoration:none;
  transition:transform .08s ease, background .12s ease;
}
.zone:hover{background:var(--surface2);transform:translateY(-1px)}
.zone.featured{
  grid-column:span 2;border:2px solid var(--info-border);
  display:flex;align-items:center;gap:16px;
}
.zone h3{margin:0;font-weight:500;font-size:16px}
.zone p{margin:4px 0 0;font-size:12px;color:var(--text2)}
.zone.featured p{font-size:13px}

@media(max-width:520px){
  .zone.featured{grid-column:span 1}
}

/* Botón de tema en la cabecera (formulario inline) */
.theme-form{display:inline-flex;margin:0}

/* ======================================================================
   Panel de administración (Fase 9)
   Layout de dos columnas (menú lateral + cuerpo), reutilizando las mismas
   variables de tema. Tomado de disenos-juego.html; los .navitem aquí son
   enlaces reales (<a>), así que llevan cursor pointer y estado hover.
   ====================================================================== */
.adminwrap{
  display:flex;
  background:var(--surface2);
  border:.5px solid var(--border);
  border-radius:var(--r-lg);
  overflow:hidden;
}
.sidebar{
  width:185px;
  flex-shrink:0;
  background:var(--surface);
  border-right:.5px solid var(--border);
  padding:18px 12px;
  border-radius:var(--r-lg) 0 0 var(--r-lg);
}
.navitem{
  display:flex;
  align-items:center;
  gap:10px;
  padding:9px 10px;
  border-radius:var(--r-md);
  font-size:14px;
  color:var(--text2);
  text-decoration:none;
  margin-bottom:4px;
}
.navitem:hover{background:var(--surface3)}
.navitem.active{background:var(--info-bg);color:var(--info);font-weight:500}
.navitem.active:hover{background:var(--info-bg)}
.adminbody{
  flex:1;
  padding:22px;
  position:relative;
  min-width:0;
}

/* En móvil el menú lateral se oculta; el cuerpo ocupa todo el ancho.
   Las secciones siguen siendo accesibles por sus URLs /admin/*. */
@media(max-width:640px){
  .sidebar{display:none}
  .adminbody{padding:16px}
}

/* -------------------------------------------------------------------------
 * Importación CSV (Fase 10)
 * ----------------------------------------------------------------------- */
.csv-drop{
  border:2px dashed var(--border);
  border-radius:var(--r-lg);
  padding:24px;
  text-align:center;
  transition:background .15s ease, border-color .15s ease;
}
.csv-drop.is-over{
  background:var(--info-bg);
  border-color:var(--info-border);
}

/* Filas de la previsualización: estado por color de fondo (verde/ámbar/rojo)
   resuelto en la vista con variables de tema. */
.csv-rowline{
  gap:10px;
  border-radius:var(--r-md);
  padding:8px 12px;
  font-size:13px;
  align-items:flex-start;
}


/* -------------------------------------------------------------------------
 * Animaciones de los acompañantes (Fase 16)
 *
 * El acompañante de la ronda reacciona al resultado de la pregunta anterior:
 * se alegra al acertar y se entristece (o enfada) al fallar, con un estilo
 * propio por personaje. Se incorpora además el acompañante 'poop' (caca rosa).
 *
 * Cómo se dispara (sin JavaScript, compatible con la CSP de las Fases 11/13):
 * round/play.php envuelve el <svg><use> del acompañante en un
 * <div class="companion-anim c-{id} {estado}">, donde {estado} es 'is-happy'
 * (acierto) o 'is-sad' (fallo), calculado server-side desde $feedback. La
 * combinación estado + personaje selecciona la animación.
 *
 * Nota técnica: la animación se aplica al DIV contenedor, no al <svg>, porque
 * Firefox no aplica de forma fiable transform/transform-origin sobre nodos
 * <svg>. Animar el contenedor HTML funciona igual en todos los navegadores.
 * ----------------------------------------------------------------------- */

.companion-anim{
  display:inline-block;
  transform-origin:50% 100%;
  will-change:transform;
  position:relative;
}
.companion-anim svg{display:block;position:relative;z-index:1}

/* Rayos del robot: cuatro destellos alrededor, ocultos salvo en acierto. */
.companion-anim .bolt{
  position:absolute;z-index:0;opacity:0;line-height:1;
  font-size:.55em;pointer-events:none;color:#EF9F27;
}
.companion-anim .bolt.b1{top:-8%;left:-16%}
.companion-anim .bolt.b2{top:-12%;right:-12%}
.companion-anim .bolt.b3{bottom:14%;left:-22%}
.companion-anim .bolt.b4{bottom:8%;right:-20%}

/* ----- Acierto (alegría) ----- */

/* Marciano y Conejito: salto con rebote elástico. */
.is-happy.c-alien,
.is-happy.c-bunny{animation:comp-jump .6s cubic-bezier(.3,1.6,.5,1) infinite}
@keyframes comp-jump{
  0%,100%{transform:translateY(0) scale(1)}
  40%{transform:translateY(-24px) scale(1.08)}
}

/* Gatito y Seta: brincos cortos y rítmicos. */
.is-happy.c-cat,
.is-happy.c-mushroom{animation:comp-bounce .55s ease-in-out infinite}
@keyframes comp-bounce{
  0%,100%{transform:translateY(0)}
  30%{transform:translateY(-18px) scaleY(1.05)}
  55%{transform:translateY(0) scaleY(.9)}
}

/* Fantasmita: flota dando vueltas suaves. */
.is-happy.c-ghost{animation:comp-swirl 1s ease-in-out infinite}
@keyframes comp-swirl{
  0%{transform:translateY(0) rotate(0)}
  50%{transform:translateY(-12px) rotate(-14deg) scale(1.06)}
  100%{transform:translateY(0) rotate(0)}
}

/* Slime: rebote gelatinoso (squash & stretch). */
.is-happy.c-slime{animation:comp-wobble .5s ease-in-out infinite}
@keyframes comp-wobble{
  0%,100%{transform:scale(1,1)}
  30%{transform:scale(1.15,.82) translateY(4px)}
  60%{transform:scale(.9,1.18) translateY(-8px)}
}

/* Pingüino: baile de lado a lado. */
.is-happy.c-penguin{animation:comp-dance .5s ease-in-out infinite}
@keyframes comp-dance{
  0%,100%{transform:rotate(-10deg)}
  50%{transform:rotate(10deg)}
}

/* Robotito: vibración eléctrica; los rayos (.bolt) hacen el resto. */
.is-happy.c-robot{animation:comp-charge .16s linear infinite}
@keyframes comp-charge{
  0%,100%{transform:translate(0,0)}
  50%{transform:translate(0,-2px)}
}
.is-happy.c-robot .bolt{animation:comp-bolt-flash .4s steps(1) infinite}
@keyframes comp-bolt-flash{
  0%,49%{opacity:1;transform:scale(1)}
  50%,100%{opacity:0;transform:scale(.6)}
}
.is-happy.c-robot .bolt.b2,
.is-happy.c-robot .bolt.b3{animation-delay:.2s}

/* Pollito: brincos altos y enérgicos. */
.is-happy.c-chick{animation:comp-hop .45s cubic-bezier(.28,1.5,.5,1) infinite}
@keyframes comp-hop{
  0%,100%{transform:translateY(0) scaleY(1)}
  25%{transform:translateY(-26px) scaleY(1.12)}
  50%{transform:translateY(0) scaleY(.88)}
}

/* Caca rosa: salto del marciano + flip del gato (salta y voltea en el aire). */
.is-happy.c-poop{animation:comp-jumpflip .7s cubic-bezier(.3,1.4,.5,1) infinite}
@keyframes comp-jumpflip{
  0%{transform:translateY(0) scaleX(1) scale(1)}
  25%{transform:translateY(-26px) scaleX(1) scale(1.08)}
  50%{transform:translateY(-26px) scaleX(-1) scale(1.08)}
  75%{transform:translateY(0) scaleX(-1) scale(1)}
  100%{transform:translateY(0) scaleX(1) scale(1)}
}

/* ----- Fallo (tristeza / enfado) ----- */

/* Marciano y Conejito: se hunden y encogen. */
.is-sad.c-alien,
.is-sad.c-bunny{animation:comp-droop .6s ease-out forwards}
@keyframes comp-droop{to{transform:translateY(8px) scaleY(.86)}}

/* Gatito: se gira ofendido. */
.is-sad.c-cat{animation:comp-turn .6s ease-out forwards}
@keyframes comp-turn{to{transform:scaleX(-1) translateY(6px) rotate(-6deg)}}

/* Fantasmita y Pollito: tiritan/tiemblan. */
.is-sad.c-ghost,
.is-sad.c-chick{animation:comp-tremble .1s linear infinite}
@keyframes comp-tremble{
  0%,100%{transform:translate(-2px,4px)}
  50%{transform:translate(2px,4px)}
}

/* Slime: se desinfla en charco. */
.is-sad.c-slime{animation:comp-deflate .8s ease-out forwards}
@keyframes comp-deflate{to{transform:scaleY(.5) scaleX(1.2) translateY(20px)}}

/* Pingüino: se enfada y vibra. */
.is-sad.c-penguin{animation:comp-angry .14s linear infinite}
@keyframes comp-angry{
  0%,100%{transform:translate(-3px,0) rotate(-2deg)}
  50%{transform:translate(3px,0) rotate(2deg)}
}
.is-sad.c-penguin svg{filter:saturate(1.7)}

/* Robotito: se apaga en gris. */
.is-sad.c-robot{animation:comp-grey .6s ease-out forwards}
@keyframes comp-grey{to{transform:translateY(10px) rotate(4deg)}}
.is-sad.c-robot svg{filter:grayscale(1)}

/* Seta y Caca rosa: se hunden mustias / se derrumban. */
.is-sad.c-mushroom,
.is-sad.c-poop{animation:comp-sink .7s ease-out forwards}
@keyframes comp-sink{to{transform:translateY(14px) scaleY(.7) scaleX(1.1)}}

/* Respeto a prefers-reduced-motion: sin movimiento, pero se conserva la pista
   estática (robot gris / pingüino saturado) para no perder el feedback. */
@media(prefers-reduced-motion:reduce){
  .companion-anim,
  .companion-anim .bolt{animation:none !important}
  .is-sad.c-robot svg{filter:grayscale(1)}
  .is-sad.c-penguin svg{filter:saturate(1.7)}
}
/* -------------------------------------------------------------------------
 * Identidad en cabecera (Fase 18)
 *
 * Bloque "quién soy" a la izquierda de los contadores: nombre del jugador,
 * nivel y una barra de experiencia compacta. Se apoya en .barwrap/.bar ya
 * definidos, así la barra hereda el color de la paleta activa (Fase 17).
 * ----------------------------------------------------------------------- */
header.top .who{
  display:flex;align-items:center;gap:10px;
  min-width:0;            /* permite que el nombre largo se recorte con ellipsis */
}
header.top .who .who-text{
  display:flex;flex-direction:column;gap:2px;min-width:0;
}
header.top .who .who-name{
  font-weight:600;font-size:14px;color:var(--text);
  max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
header.top .who .lvl{
  font-size:12px;color:var(--text2);line-height:1;
}
header.top .who .xp{
  display:block;width:120px;height:6px;margin-top:2px;
}
/* La barra .xp se construye con <span> en la cabecera. El .bar interno
   hereda la regla global `.bar{height:100%}`, pero al ser un <span> es
   `inline` por defecto y los elementos inline ignoran width/height, por lo
   que la barra no se pintaba. Forzarlo a bloque restaura su tamaño. */
header.top .who .xp .bar{
  display:block;
}

/* En pantallas estrechas, la barra de exp se oculta para no apretar la fila;
   el nombre y el nivel siguen visibles. */
@media(max-width:560px){
  header.top .who .xp{display:none}
  header.top .who .who-name{max-width:110px}
}


/* -------------------------------------------------------------------------
 * Modal de recompensa excepcional (Fase 19)
 *
 * Cuando una respuesta dispara un EVENTO (tesoro o planta solar nueva, §5.5),
 * round/play.php y round/finished.php pintan una modal con un icono pixel-art
 * animado y una lluvia de partículas tipo "fuegos artificiales".
 *
 * Compatibilidad con la CSP (Fases 11/13, script-src 'self'):
 *   - TODA la animación del icono, la corona de rayos y la entrada de la modal
 *     es CSS puro (@keyframes + clases), exactamente como los acompañantes de
 *     la Fase 16. No hay JavaScript en línea.
 *   - Los "fuegos artificiales" y el cierre de la modal los engancha
 *     public/js/app.js (servido desde 'self', permitido por la CSP) a través de
 *     atributos data-* / id. Si el JS no se ejecuta, la modal sigue siendo
 *     usable: el icono se anima igual y se puede cerrar con el botón (que es un
 *     enlace real a la propia pantalla) o el aspa.
 *
 * Accesibilidad: se respeta prefers-reduced-motion (sin movimiento, pero el
 * cofre/planta quedan en su estado final y legible).
 * ----------------------------------------------------------------------- */

/* Capa que oscurece el fondo y centra la modal. No usa position:fixed para no
   depender de JS; se pinta dentro del flujo, al principio de <main>. */
.reward-overlay{
  position:fixed;inset:0;z-index:1000;
  display:flex;align-items:center;justify-content:center;padding:20px;
  background:rgba(8,6,2,.55);
  animation:reward-fade-in .25s ease both;
}
@keyframes reward-fade-in{from{opacity:0}to{opacity:1}}

.reward-modal{
  position:relative;
  width:320px;max-width:100%;
  background:var(--surface);
  border:.5px solid var(--border);
  border-radius:18px;
  padding:30px 24px 24px;
  text-align:center;
  overflow:hidden;
  box-shadow:0 18px 50px rgba(0,0,0,.35);
  animation:reward-pop .5s cubic-bezier(.2,1.5,.4,1) both;
}
@keyframes reward-pop{0%{transform:scale(.5);opacity:0}100%{transform:scale(1);opacity:1}}

/* Aspa de cierre arriba a la derecha (enlace real a la pantalla actual). */
.reward-close{
  position:absolute;top:10px;right:12px;z-index:5;
  width:26px;height:26px;line-height:24px;
  border-radius:8px;
  font-size:16px;font-weight:500;text-align:center;text-decoration:none;
  color:var(--text2);background:transparent;border:.5px solid transparent;
}
.reward-close:hover{background:var(--surface3);color:var(--text)}

/* Corona de rayos que gira detrás del icono. */
.reward-rays{
  position:absolute;top:24px;left:50%;
  width:200px;height:200px;margin-left:-100px;z-index:1;
  background:repeating-conic-gradient(from 0deg,
            rgba(250,199,117,.32) 0deg 11deg, transparent 11deg 30deg);
  border-radius:50%;
  animation:reward-spin 9s linear infinite;
  -webkit-mask:radial-gradient(circle,transparent 30px,#000 34px);
          mask:radial-gradient(circle,transparent 30px,#000 34px);
  pointer-events:none;
}
@keyframes reward-spin{to{transform:rotate(360deg)}}

/* Contenedor del icono pixel-art (cofre o planta). */
.reward-icon{
  position:relative;z-index:3;
  height:130px;display:flex;align-items:flex-end;justify-content:center;
}
.reward-icon svg{display:block}

/* Textos de la modal. */
.reward-eyebrow{
  position:relative;z-index:3;
  font-size:11px;letter-spacing:1.5px;text-transform:uppercase;
  color:var(--warn);margin:0 0 4px;font-weight:600;
  animation:reward-text .4s .35s both;
}
.reward-title{
  position:relative;z-index:3;
  font-size:19px;font-weight:500;margin:0 0 4px;color:var(--text);
  animation:reward-text .4s .45s both;
}
.reward-sub{
  position:relative;z-index:3;
  font-size:14px;margin:0;color:var(--text2);font-weight:500;
  animation:reward-text .4s .55s both;
}
@keyframes reward-text{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}

.reward-cta{
  position:relative;z-index:3;
  margin-top:20px;width:100%;
  animation:reward-text .4s .65s both;
}

/* Capa donde app.js inyecta las partículas de los fuegos artificiales. */
.reward-fx{position:absolute;inset:0;z-index:4;pointer-events:none}
.reward-fx .spark{position:absolute;top:46%;left:50%;width:7px;height:7px;border-radius:1px}

/* ----- Animación del cofre (cerrado, balanceándose) ----- */
.reward-chest-bob{
  transform-box:fill-box;transform-origin:50% 100%;
  animation:reward-bob 1.6s .5s ease-in-out infinite;
}
@keyframes reward-bob{
  0%,100%{transform:translateY(0) scale(1,1)}
  25%{transform:translateY(-4px) scale(.98,1.04)}
  55%{transform:translateY(0) scale(1.03,.97)}
}
.reward-chest-glow{
  transform-box:fill-box;transform-origin:50% 100%;opacity:0;
  animation:reward-glow 1.4s .6s ease-in-out infinite alternate;
}
@keyframes reward-glow{
  from{opacity:.5;transform:scaleY(.8)}
  to{opacity:1;transform:scaleY(1.2)}
}
.reward-chest-coins rect{opacity:0;animation:reward-coinfly 1.1s .5s ease-out infinite}
.reward-chest-coins rect:nth-child(2){animation-delay:.85s}
.reward-chest-coins rect:nth-child(3){animation-delay:.4s}
@keyframes reward-coinfly{
  0%{transform:translateY(2px);opacity:0}
  20%{opacity:1}70%{opacity:1}
  100%{transform:translateY(-7px);opacity:0}
}

/* ----- Animación de la planta solar (sol naciente + panel desplegándose) ----- */
.reward-sun-rise{
  transform-box:fill-box;transform-origin:50% 100%;
  animation:reward-sunrise 1s .4s cubic-bezier(.3,1.3,.5,1) both;
}
@keyframes reward-sunrise{
  0%{transform:translateY(10px) scale(.4);opacity:0}
  100%{transform:translateY(0) scale(1);opacity:1}
}
.reward-panel-grow{
  transform-box:fill-box;transform-origin:50% 100%;
  animation:reward-panel .7s .3s cubic-bezier(.3,1.4,.5,1) both;
}
@keyframes reward-panel{
  0%{transform:scaleY(0);opacity:0}
  100%{transform:scaleY(1);opacity:1}
}

/* Respeto a prefers-reduced-motion: sin movimiento, pero el icono queda en su
   estado final y legible (el brillo del cofre se mantiene encendido). */
@media(prefers-reduced-motion:reduce){
  .reward-overlay,.reward-modal,.reward-rays,
  .reward-chest-bob,.reward-chest-glow,.reward-chest-coins rect,
  .reward-sun-rise,.reward-panel-grow,
  .reward-eyebrow,.reward-title,.reward-sub,.reward-cta{animation:none}
  .reward-chest-glow{opacity:1}
}
