/* ═══════════════════════════════════════════════════════════════════
   COSMÉTICOS — avatares de casino, marcos animados, fondos animados.
   Los ids se corresponden 1:1 con las listas de js/cosmetics.js.

   Todo se anima con `transform`, `opacity`, `filter`, `rotate` y
   `background-position`. Ninguna animación toca layout, así que un móvil
   puede tener varios marcos girando a la vez en el ranking sin bajar de
   60fps.
═══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════
   1. AVATARES
   Un avatar es un emoji (o una secuencia de emojis que se turnan).
   Sustituye a la inicial del nickname en un círculo.
═══════════════════════════════════════════ */

.ca {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, #2a1b3f, #140c22);
  position: relative;
  overflow: hidden;
  line-height: 1;
  user-select: none;
  aspect-ratio: 1;
}
/* El emoji se centra ópticamente: los glifos de emoji tienen mucho aire
   por abajo y sin esto quedan visiblemente altos dentro del círculo. */
.ca-e {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .62em;
  line-height: 1;
}

/* Avatar estático: un solo emoji, sin animación. */
.ca-static .ca-e { position: static; }

/* ── combos animados ──────────────────────────────────────────────────
   Los emojis se turnan con un giro sobre el eje Y. Cada hijo lleva el
   mismo `animation` y un `animation-delay` negativo que lo coloca en su
   franja del ciclo; ese desfase lo escribe js/cosmetics.js, porque CSS
   no sabe dividir por nth-child.

   La ventana visible TIENE que valer 100/n del ciclo. Una única regla
   con la ventana fija al 44% funcionaba con 2 emojis, pero con 3 o 4 las
   franjas se pisaban y se veían dos emojis superpuestos a la vez. De ahí
   que haya unos keyframes por cantidad. */
.ca-anim { perspective: 200px; }
.ca-anim .ca-e {
  animation-duration: var(--d, 3s);
  animation-timing-function: cubic-bezier(.4, 0, .2, 1);
  animation-iteration-count: infinite;
  animation-fill-mode: both;
  backface-visibility: hidden;
  /* Sin `will-change` a propósito: era permanente y reservaba una capa de GPU
     por emoji (30 filas x 4 = 120 capas retenidas sin animar nada). El
     navegador ya promociona solo lo que está animándose de verdad. */
}

.ca-n2 .ca-e { animation-name: caCycle2; }
.ca-n3 .ca-e { animation-name: caCycle3; }
.ca-n4 .ca-e { animation-name: caCycle4; }

/* 2 emojis → 50% cada uno, con ~8% de giro entre medias. */
@keyframes caCycle2 {
  0%          { opacity: 1; transform: rotateY(0deg)   scale(1); }
  42%         { opacity: 1; transform: rotateY(0deg)   scale(1); }
  50%         { opacity: 0; transform: rotateY(85deg)  scale(.72); }
  92%         { opacity: 0; transform: rotateY(-85deg) scale(.72); }
  100%        { opacity: 1; transform: rotateY(0deg)   scale(1); }
}
/* 3 emojis → 33,3% cada uno. */
@keyframes caCycle3 {
  0%          { opacity: 1; transform: rotateY(0deg)   scale(1); }
  26%         { opacity: 1; transform: rotateY(0deg)   scale(1); }
  33.3%       { opacity: 0; transform: rotateY(85deg)  scale(.72); }
  93%         { opacity: 0; transform: rotateY(-85deg) scale(.72); }
  100%        { opacity: 1; transform: rotateY(0deg)   scale(1); }
}
/* 4 emojis → 25% cada uno. */
@keyframes caCycle4 {
  0%          { opacity: 1; transform: rotateY(0deg)   scale(1); }
  19%         { opacity: 1; transform: rotateY(0deg)   scale(1); }
  25%         { opacity: 0; transform: rotateY(85deg)  scale(.72); }
  94%         { opacity: 0; transform: rotateY(-85deg) scale(.72); }
  100%        { opacity: 1; transform: rotateY(0deg)   scale(1); }
}

/* Aura de color según la rareza del avatar. */
.ca-rare      { box-shadow: inset 0 0 0 1px rgba(74,163,255,.5),  0 0 10px rgba(74,163,255,.35); }
.ca-epic      { box-shadow: inset 0 0 0 1px rgba(168,85,247,.55), 0 0 12px rgba(168,85,247,.4); }
.ca-legendary {
  box-shadow: inset 0 0 0 1px rgba(255,180,61,.6), 0 0 16px rgba(255,180,61,.5);
  animation: caLegend 2.6s ease-in-out infinite;
}
@keyframes caLegend {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.25) saturate(1.3); }
}

/* ═══════════════════════════════════════════
   2. MARCOS ANIMADOS NUEVOS (.cf-<id>)
   El truco de main.css se mantiene: gira el degradado del marco, y el
   hijo gira al revés a la misma velocidad para que la cara no dé vueltas.
═══════════════════════════════════════════ */

.cf-neon-pulse {
  background: conic-gradient(from 0deg, #00e6ff, #ff2d95, #00e6ff);
  box-shadow: 0 0 18px rgba(0,230,255,.6);
  animation: cfSpin 3.5s linear infinite, cfBreathe 1.8s ease-in-out infinite;
}
.cf-chip-red {
  /* Ficha de póker: cuñas alternas blancas y rojas. */
  background: repeating-conic-gradient(from 0deg, #d61f37 0deg 22.5deg, #f4f4f6 22.5deg 45deg);
  box-shadow: 0 0 12px rgba(214,31,55,.5);
  animation: cfSpin 6s linear infinite;
}
.cf-emerald {
  background: conic-gradient(from 0deg, #04372a, #22c55e, #a7f3d0, #10b981, #04372a);
  box-shadow: 0 0 18px rgba(34,197,94,.6);
  animation: cfSpin 5s linear infinite;
}
.cf-jackpot {
  background: linear-gradient(100deg, #7a4a00, #ffd700 35%, #fffbe6 50%, #ffd700 65%, #7a4a00);
  background-size: 300% 100%;
  box-shadow: 0 0 20px rgba(255,215,0,.7);
  animation: cfSweep 2.4s linear infinite;
}
.cf-cyber {
  background:
    repeating-linear-gradient(0deg, rgba(0,0,0,.45) 0 2px, transparent 2px 4px),
    conic-gradient(from 0deg, #00fff0, #7b3ff2, #ff2d95, #00fff0);
  box-shadow: 0 0 20px rgba(0,255,240,.55);
  animation: cfSpin 4s linear infinite, cfHue 6s linear infinite;
}
.cf-blood-moon {
  background: conic-gradient(from 0deg, #12000a, #ff1744, #ff8a80, #8b0000, #12000a);
  box-shadow: 0 0 22px rgba(255,23,68,.65);
  animation: cfSpin 7s linear infinite, cfBreathe 2.4s ease-in-out infinite;
}
.cf-aurora {
  background: conic-gradient(from 0deg, #00ffa3, #00d4ff, #a855f7, #ff6ec7, #00ffa3);
  box-shadow: 0 0 24px rgba(0,212,255,.6), 0 0 40px rgba(168,85,247,.35);
  animation: cfSpin 4.5s linear infinite, cfHue 8s linear infinite;
}
.cf-starlight {
  background:
    radial-gradient(1.5px 1.5px at 20% 25%, #fff, transparent),
    radial-gradient(1.5px 1.5px at 78% 32%, #fff, transparent),
    radial-gradient(1px 1px   at 46% 74%, #fff, transparent),
    radial-gradient(1.5px 1.5px at 68% 82%, #fff, transparent),
    linear-gradient(140deg, #0a0620, #2c1b57 55%, #4c1d95);
  box-shadow: 0 0 20px rgba(124,58,237,.6);
  animation: cfTwinkle 3.2s ease-in-out infinite;
}
.cf-gold-rush {
  background: conic-gradient(from 0deg,
    #6b4200, #ffd700, #fffbe6, #ffb43d, #fffbe6, #ffd700, #6b4200);
  box-shadow: 0 0 26px rgba(255,215,0,.8), 0 0 48px rgba(255,143,31,.4);
  animation: cfSpin 2.2s linear infinite;
}

/* Contra-rotación del contenido para los marcos que giran. Sin esto la
   cara del avatar da vueltas con el marco y se lee fatal. */
.cf-neon-pulse > *, .cf-chip-red > *, .cf-emerald > *,
.cf-cyber > *, .cf-blood-moon > *, .cf-aurora > *, .cf-gold-rush > * {
  animation: cfSpinBack 5s linear infinite;
}
.cf-neon-pulse > *  { animation-duration: 3.5s; }
.cf-chip-red > *    { animation-duration: 6s; }
.cf-emerald > *     { animation-duration: 5s; }
.cf-cyber > *       { animation-duration: 4s; }
.cf-blood-moon > *  { animation-duration: 7s; }
.cf-aurora > *      { animation-duration: 4.5s; }
.cf-gold-rush > *   { animation-duration: 2.2s; }

@keyframes cfBreathe {
  0%, 100% { box-shadow: 0 0 14px currentColor; filter: brightness(1); }
  50%      { filter: brightness(1.35); }
}
@keyframes cfSweep  { to { background-position: -300% 0; } }
@keyframes cfHue    { to { filter: hue-rotate(360deg); } }
@keyframes cfTwinkle {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.5) contrast(1.2); }
}

/* ═══════════════════════════════════════════
   3. FONDOS DE PERFIL ANIMADOS (.cb-<id>)
═══════════════════════════════════════════ */

.cb-felt {
  /* Tapete de casino: rombos de palos desplazándose despacio. */
  background:
    repeating-linear-gradient(45deg,  rgba(255,255,255,.03) 0 12px, transparent 12px 24px),
    repeating-linear-gradient(-45deg, rgba(0,0,0,.12) 0 12px, transparent 12px 24px),
    radial-gradient(circle at 50% 40%, #1b6b45, #0b3324 75%);
  background-size: 34px 34px, 34px 34px, 100% 100%;
  animation: cbSlide 22s linear infinite;
}
.cb-reels {
  /* Franjas verticales que caen: la lectura visual de unos rodillos. */
  background:
    repeating-linear-gradient(90deg,
      rgba(255,255,255,.07) 0 2px, transparent 2px 64px),
    repeating-linear-gradient(180deg,
      rgba(255,180,61,.18) 0 16px, rgba(0,0,0,.25) 16px 32px),
    linear-gradient(135deg, #1a1005, #3d2408);
  background-size: 100% 100%, 100% 64px, 100% 100%;
  animation: cbReelRoll 1.6s linear infinite;
}
.cb-roulette {
  background: repeating-conic-gradient(from 0deg at 50% 50%,
    #b3122c 0deg 18deg, #12080f 18deg 36deg);
  animation: cbRotate 26s linear infinite;
}
.cb-neon-city {
  background:
    repeating-linear-gradient(0deg,  transparent 0 26px, rgba(0,230,255,.16) 26px 27px),
    repeating-linear-gradient(90deg, transparent 0 26px, rgba(255,45,149,.14) 26px 27px),
    linear-gradient(190deg, #05021a 0%, #2b0a52 55%, #ff2d95 160%);
  background-size: 100% 27px, 27px 100%, 100% 100%;
  animation: cbGrid 6s linear infinite;
}
.cb-gold-vault {
  background:
    repeating-linear-gradient(115deg,
      rgba(255,255,255,.14) 0 6px, transparent 6px 22px),
    linear-gradient(120deg, #2a1a00 0%, #ffb43d 40%, #fff3c4 52%, #ffb43d 64%, #2a1a00 100%);
  background-size: 100% 100%, 260% 100%;
  animation: cbShine 5s linear infinite;
}
.cb-aurora-sky {
  background: linear-gradient(120deg, #04121f, #00ffa3 25%, #00d4ff 45%, #a855f7 70%, #04121f);
  background-size: 300% 300%;
  animation: cbDrift 12s ease-in-out infinite, cbHueSlow 20s linear infinite;
}
.cb-matrix {
  background:
    repeating-linear-gradient(180deg,
      rgba(0,255,102,.22) 0 3px, transparent 3px 14px),
    repeating-linear-gradient(90deg,
      transparent 0 10px, rgba(0,0,0,.35) 10px 12px),
    linear-gradient(180deg, #000d05, #012d13);
  background-size: 100% 60px, 100% 100%, 100% 100%;
  animation: cbRain 1.1s linear infinite;
}
.cb-confetti {
  background:
    radial-gradient(4px 8px at 12% 20%, #ffb43d, transparent),
    radial-gradient(4px 8px at 38% 65%, #ff4762, transparent),
    radial-gradient(4px 8px at 62% 30%, #9d5cff, transparent),
    radial-gradient(4px 8px at 84% 72%, #22d3ee, transparent),
    radial-gradient(4px 8px at 50% 88%, #b6ff3d, transparent),
    linear-gradient(150deg, #1c0f2e, #3b1d5c);
  background-size: 120px 120px, 120px 120px, 120px 120px, 120px 120px, 120px 120px, 100% 100%;
  animation: cbFall 5s linear infinite;
}
.cb-royal-flush {
  background:
    radial-gradient(2px 2px at 24% 30%, rgba(255,255,255,.9), transparent),
    radial-gradient(2px 2px at 72% 62%, rgba(255,255,255,.8), transparent),
    linear-gradient(125deg, #14002e 0%, #6b21a8 35%, #ffd700 70%, #14002e 100%);
  background-size: 100% 100%, 100% 100%, 260% 260%;
  animation: cbDrift 10s ease-in-out infinite, cbTwinkleBg 2.8s ease-in-out infinite;
}
.cb-inferno-wave {
  background: linear-gradient(115deg, #160300 0%, #ff2200 28%, #ffb43d 50%, #ff5500 72%, #160300 100%);
  background-size: 320% 320%;
  animation: cbDrift 6s ease-in-out infinite;
}

@keyframes cbSlide     { to { background-position: 34px 34px, -34px 34px, 0 0; } }
@keyframes cbReelRoll  { to { background-position: 0 0, 0 64px, 0 0; } }
@keyframes cbRotate    { to { transform: rotate(360deg); } }
@keyframes cbGrid      { to { background-position: 0 27px, 27px 0, 0 0; } }
@keyframes cbShine     { to { background-position: 0 0, -260% 0; } }
@keyframes cbRain      { to { background-position: 0 60px, 0 0, 0 0; } }
@keyframes cbFall      { to { background-position: 20px 120px, -30px 120px, 15px 120px, -20px 120px, 25px 120px, 0 0; } }
@keyframes cbHueSlow   { to { filter: hue-rotate(360deg); } }
@keyframes cbTwinkleBg {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.3); }
}

/* .cb-roulette gira el elemento entero, así que hay que recortarlo o los
   bordes barren fuera de la tarjeta de perfil. */
.cb-roulette { transform-origin: center; }
[class*="cb-"] { position: relative; overflow: hidden; }

/* ═══════════════════════════════════════════
   4. SELECTOR DE AVATAR (página de perfil)
═══════════════════════════════════════════ */

.cos-avatar-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(66px, 1fr));
  gap: 10px;
  margin-top: 10px;
}
.cos-avatar {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 9px 4px;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: rgba(255,255,255,.02);
  cursor: pointer;
  transition: transform .18s cubic-bezier(.34,1.56,.64,1),
              border-color .2s ease, background .2s ease;
}
.cos-avatar:hover { transform: translateY(-3px); background: rgba(255,255,255,.06); }
.cos-avatar.equipped { border-color: var(--neon); background: rgba(255,180,61,.1); }
.cos-avatar.locked   { opacity: .42; cursor: not-allowed; }
.cos-avatar.locked:hover { transform: none; }
.cos-avatar .ca { width: 42px; height: 42px; font-size: 42px; }
.cos-avatar-name {
  font-size: 10px; color: var(--text3); text-align: center;
  line-height: 1.25; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cos-avatar .cos-lock {
  position: absolute; top: 4px; right: 5px; font-size: 10px;
}
.cos-req {
  font-size: 9px; color: var(--text3); font-family: 'Space Mono', monospace;
}

/* ═══════════════════════════════════════════
   5. MOVIMIENTO REDUCIDO
   Los combos de emoji NO se pueden congelar sin más: los hijos se apilan
   con opacity:0 y el avatar quedaría vacío. Se deja fijo el primero.
═══════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .ca-anim .ca-e { animation: none; opacity: 0; }
  .ca-anim .ca-e:first-child { opacity: 1; transform: none; }
  .cb-roulette, .cf-gold-rush, .cf-aurora, .cf-cyber,
  .cf-neon-pulse, .cf-chip-red, .cf-emerald, .cf-blood-moon { animation: none; }
  .cf-neon-pulse > *, .cf-chip-red > *, .cf-emerald > *,
  .cf-cyber > *, .cf-blood-moon > *, .cf-aurora > *, .cf-gold-rush > * { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   6. SEGUNDA TANDA — 10 marcos, 10 fondos y 10 avatares más.
   Cada marco usa una técnica distinta a propósito (cónico, barrido
   lineal, destellos radiales, pulso de brillo, doble capa) para que no
   parezcan diez variaciones del mismo degradado.
═══════════════════════════════════════════════════════════════════ */

/* ── MARCOS ─────────────────────────────────────────────────────── */

/* Cónico rápido con los siete colores: el más llamativo del set. */
.cf-rainbow-run {
  background: conic-gradient(from 0deg,
    #ff0040, #ff8a00, #ffe600, #37ff00, #00e5ff, #4b00ff, #ff00c8, #ff0040);
  box-shadow: 0 0 22px rgba(255,0,200,.55);
  animation: cfSpin 1.8s linear infinite;
}
/* Cristal: barrido lineal, no giro. Da sensación de superficie pulida. */
.cf-ice-crystal {
  background: linear-gradient(115deg, #0b3a4d, #7fe9ff 30%, #ffffff 48%, #7fe9ff 66%, #0b3a4d);
  background-size: 280% 100%;
  box-shadow: 0 0 20px rgba(127,233,255,.65);
  animation: cfSweep 3s linear infinite;
}
/* Magma: base oscura fija con grietas que laten. */
.cf-magma {
  background:
    radial-gradient(circle at 30% 30%, #ff6a00, transparent 45%),
    radial-gradient(circle at 72% 68%, #ff2d00, transparent 42%),
    linear-gradient(135deg, #1a0500, #3d0f00);
  box-shadow: 0 0 22px rgba(255,60,0,.6);
  animation: cfMagma 2.2s ease-in-out infinite;
}
/* Eléctrico: giro rápido + parpadeo irregular. */
.cf-electric {
  background: conic-gradient(from 0deg, #001a4d, #00d0ff, #ffffff, #ffe600, #00d0ff, #001a4d);
  box-shadow: 0 0 20px rgba(0,208,255,.7);
  animation: cfSpin 1.2s linear infinite, cfFlicker 2.6s steps(1) infinite;
}
/* Tóxico: verde ácido con latido de saturación. */
.cf-toxic-waste {
  background: conic-gradient(from 0deg, #0d2600, #7cff00, #d4ff8a, #3fa200, #0d2600);
  box-shadow: 0 0 22px rgba(124,255,0,.6);
  animation: cfSpin 4.2s linear infinite, cfBreathe 1.5s ease-in-out infinite;
}
/* Púrpura real: giro lento, sensación de peso. */
.cf-royal-purple {
  background: conic-gradient(from 0deg, #1a0033, #7b2fff, #ffd700, #b06bff, #1a0033);
  box-shadow: 0 0 24px rgba(123,47,255,.65), 0 0 40px rgba(255,215,0,.25);
  animation: cfSpin 8s linear infinite;
}
/* Plata: metálico, barrido en diagonal contraria al de hielo. */
.cf-silver-storm {
  background: linear-gradient(65deg, #3a3a44, #e9e9f2 32%, #ffffff 46%, #b8b8c8 60%, #3a3a44);
  background-size: 300% 100%;
  box-shadow: 0 0 18px rgba(230,230,245,.5);
  animation: cfSweep 2.6s linear infinite;
}
/* Sakura: rosa suave, giro muy lento. El más discreto del set. */
.cf-sakura {
  background: conic-gradient(from 0deg, #4a1030, #ffb7d5, #fff0f6, #ff7eb6, #4a1030);
  box-shadow: 0 0 18px rgba(255,150,200,.55);
  animation: cfSpin 9s linear infinite;
}
/* Abismo: casi negro con un halo que respira. Sin giro. */
.cf-abyss {
  background:
    radial-gradient(circle at 50% 50%, #0a2f6b 0%, #04081f 70%),
    linear-gradient(135deg, #000814, #001233);
  box-shadow: 0 0 20px rgba(10,80,200,.5);
  animation: cfAbyss 3.4s ease-in-out infinite;
}
/* Supernova: núcleo blanco que estalla hacia fuera. */
.cf-supernova {
  background:
    radial-gradient(circle at 50% 50%, #ffffff 0%, #ffe680 18%, #ff8a00 38%, #7b1fa2 62%, #12002e 100%);
  background-size: 200% 200%;
  box-shadow: 0 0 30px rgba(255,230,128,.8), 0 0 55px rgba(255,138,0,.4);
  animation: cfNova 2.8s ease-in-out infinite;
}

.cf-rainbow-run > *, .cf-electric > *, .cf-toxic-waste > *,
.cf-royal-purple > *, .cf-sakura > * { animation: cfSpinBack 4s linear infinite; }
.cf-rainbow-run > *  { animation-duration: 1.8s; }
.cf-electric > *     { animation-duration: 1.2s; }
.cf-toxic-waste > *  { animation-duration: 4.2s; }
.cf-royal-purple > * { animation-duration: 8s; }
.cf-sakura > *       { animation-duration: 9s; }

@keyframes cfMagma {
  0%, 100% { filter: brightness(1)   saturate(1); }
  50%      { filter: brightness(1.55) saturate(1.4); }
}
@keyframes cfFlicker {
  0%, 100% { filter: brightness(1); }
  47%      { filter: brightness(1); }
  50%      { filter: brightness(2.2); }
  53%      { filter: brightness(.85); }
  56%      { filter: brightness(1.7); }
  60%      { filter: brightness(1); }
}
@keyframes cfAbyss {
  0%, 100% { box-shadow: 0 0 14px rgba(10,80,200,.35); }
  50%      { box-shadow: 0 0 30px rgba(20,120,255,.75); }
}
@keyframes cfNova {
  0%, 100% { background-position: 50% 50%; background-size: 200% 200%; filter: brightness(1); }
  50%      { background-position: 50% 50%; background-size: 130% 130%; filter: brightness(1.4); }
}

/* ── FONDOS ─────────────────────────────────────────────────────── */

.cb-poker-table {
  background:
    radial-gradient(circle at 50% 45%, rgba(255,255,255,.06), transparent 55%),
    repeating-linear-gradient(90deg, transparent 0 48px, rgba(0,0,0,.18) 48px 50px),
    radial-gradient(ellipse at 50% 50%, #1e5c3a 0%, #0a2b1c 80%);
  background-size: 100% 100%, 100px 100%, 100% 100%;
  animation: cbSlideX 18s linear infinite;
}
.cb-vegas-lights {
  background:
    radial-gradient(3px 3px at 15% 25%, #ffd700, transparent),
    radial-gradient(3px 3px at 45% 60%, #ff2d95, transparent),
    radial-gradient(3px 3px at 72% 22%, #00e5ff, transparent),
    radial-gradient(3px 3px at 88% 70%, #b6ff3d, transparent),
    linear-gradient(160deg, #12001f, #3a0a52 55%, #7b0f6e);
  background-size: 90px 90px, 110px 110px, 130px 130px, 100px 100px, 100% 100%;
  animation: cbVegas 2.4s steps(4) infinite;
}
.cb-cards-rain {
  background:
    repeating-linear-gradient(155deg,
      rgba(255,255,255,.10) 0 4px, transparent 4px 30px),
    repeating-linear-gradient(25deg,
      rgba(255,71,98,.14) 0 4px, transparent 4px 34px),
    linear-gradient(140deg, #14101f, #241a3d);
  background-size: 60px 90px, 70px 100px, 100% 100%;
  animation: cbCards 3.2s linear infinite;
}
.cb-deep-space {
  background:
    radial-gradient(1px 1px  at 10% 20%, #fff, transparent),
    radial-gradient(1.5px 1.5px at 35% 70%, #cfe4ff, transparent),
    radial-gradient(1px 1px  at 62% 35%, #fff, transparent),
    radial-gradient(2px 2px  at 82% 78%, #ffe6b0, transparent),
    radial-gradient(ellipse at 70% 30%, rgba(90,40,200,.5), transparent 60%),
    linear-gradient(180deg, #01010a, #060320 70%, #0c0637);
  background-size: 200px 200px, 240px 240px, 180px 180px, 260px 260px, 100% 100%, 100% 100%;
  animation: cbStars 30s linear infinite;
}
.cb-lava-flow {
  background:
    radial-gradient(ellipse at 20% 80%, #ff3d00, transparent 45%),
    radial-gradient(ellipse at 75% 25%, #ff8a00, transparent 42%),
    linear-gradient(160deg, #1a0400, #4a0f00 60%, #7a1a00);
  background-size: 180% 180%, 160% 160%, 100% 100%;
  animation: cbLava 9s ease-in-out infinite;
}
.cb-ocean-wave {
  background:
    repeating-linear-gradient(100deg,
      rgba(255,255,255,.07) 0 3px, transparent 3px 26px),
    linear-gradient(180deg, #012a4a, #0466a3 55%, #01c5c4);
  background-size: 200% 100%, 100% 100%;
  animation: cbWave 7s ease-in-out infinite;
}
.cb-cyber-grid {
  background:
    repeating-linear-gradient(0deg,  transparent 0 18px, rgba(0,255,200,.20) 18px 19px),
    repeating-linear-gradient(90deg, transparent 0 18px, rgba(0,255,200,.10) 18px 19px),
    linear-gradient(200deg, #00060d, #002b2b 60%, #005c4d);
  background-size: 100% 19px, 19px 100%, 100% 100%;
  animation: cbGridFast 3.5s linear infinite;
}
.cb-diamond-dust {
  background:
    radial-gradient(2px 2px at 22% 32%, #ffffff, transparent),
    radial-gradient(2px 2px at 58% 68%, #cfefff, transparent),
    radial-gradient(1.5px 1.5px at 80% 28%, #ffffff, transparent),
    linear-gradient(135deg, #101a2e, #35507e 55%, #9fc4ff);
  background-size: 120px 120px, 150px 150px, 100px 100px, 100% 100%;
  animation: cbDust 4s ease-in-out infinite;
}
.cb-sunrise {
  background: linear-gradient(180deg, #17023a 0%, #7b2166 32%, #ff6b3d 62%, #ffc46b 88%, #fff0c2 100%);
  background-size: 100% 260%;
  animation: cbRise 11s ease-in-out infinite;
}
.cb-thunder {
  background:
    linear-gradient(105deg, transparent 44%, rgba(255,255,255,.85) 47%, transparent 50%),
    linear-gradient(160deg, #05060f, #14183a 60%, #262b5c);
  background-size: 250% 100%, 100% 100%;
  animation: cbBolt 4.5s ease-in-out infinite;
}

@keyframes cbSlideX   { to { background-position: 0 0, 100px 0, 0 0; } }
@keyframes cbVegas {
  0%,100% { filter: brightness(1); }
  25%     { filter: brightness(1.5); }
  50%     { filter: brightness(.85); }
  75%     { filter: brightness(1.3); }
}
@keyframes cbCards    { to { background-position: 60px 90px, -70px 100px, 0 0; } }
@keyframes cbStars    { to { background-position: 200px 0, -240px 0, 180px 0, -260px 0, 0 0, 0 0; } }
@keyframes cbLava {
  0%,100% { background-position: 0% 100%, 100% 0%, 0 0; }
  50%     { background-position: 40% 60%, 60% 40%, 0 0; }
}
@keyframes cbWave {
  0%,100% { background-position: 0 0, 0 0; }
  50%     { background-position: 200% 0, 0 0; }
}
@keyframes cbGridFast { to { background-position: 0 19px, 19px 0, 0 0; } }
@keyframes cbDust {
  0%,100% { filter: brightness(1); }
  50%     { filter: brightness(1.4) contrast(1.15); }
}
@keyframes cbRise {
  0%,100% { background-position: 0 0%; }
  50%     { background-position: 0 100%; }
}
@keyframes cbBolt {
  0%, 82%, 100% { background-position: -150% 0, 0 0; }
  86%           { background-position:  40% 0, 0 0; }
  88%           { background-position:  50% 0, 0 0; }
  92%           { background-position: 150% 0, 0 0; }
}

/* ── Niveles del pase sin premio ─────────────────────────────────────
   Tienen que leerse como "aquí no hay nada" a primera vista, sin que
   parezcan un fallo de carga. */
.sp-reward-none {
  opacity: .38;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.sp-reward-dash {
  font-size: 22px; line-height: 1; color: var(--text3);
  font-family: 'Space Mono', monospace;
}
.sp-reward-none .sp-reward-name { color: var(--text3); font-style: italic; }

/* El avatar como premio del pase reutiliza el propio componente .ca, así
   que se ve exactamente igual que cuando esté equipado. */
.sp-reward .ca { margin: 0 auto; }

/* ═══════════════════════════════════════════════════════════════════
   7. TÉCNICAS PARAMÉTRICAS (.cft-* marcos · .cbt-* fondos)
   Los cosméticos de la serie generada no tienen regla propia: eligen
   una de estas técnicas y aportan su paleta en --c1/--c2/--c3.

   Rendimiento: todas animan una sola propiedad compositable
   (rotate / background-position / opacity). Ninguna anima `filter` en
   bucle, que es lo que cuesta caro cuando hay 30 marcos a la vez en el
   ranking. El pausado fuera de pantalla lo hace js/motion.js.
═══════════════════════════════════════════════════════════════════ */

.cft-conic, .cft-sweep, .cft-pulse, .cft-dual,
.cft-spark, .cft-chip, .cft-halo, .cft-flick { --c1:#222; --c2:#888; --c3:#fff; }

/* Cónico girando: el clásico "anillo de energía". */
.cft-conic {
  background: conic-gradient(from 0deg, var(--c1), var(--c2), var(--c3), var(--c2), var(--c1));
  box-shadow: 0 0 14px var(--c2);
  animation: cfSpin 5s linear infinite;
}
/* Barrido lineal: superficie pulida, sin giro. */
.cft-sweep {
  background: linear-gradient(110deg, var(--c1), var(--c2) 35%, var(--c3) 50%, var(--c2) 65%, var(--c1));
  background-size: 280% 100%;
  box-shadow: 0 0 14px var(--c2);
  animation: cftSweep 3.2s linear infinite;
}
/* Radial que respira. Late la opacidad de una capa, no un filter. */
.cft-pulse {
  background: radial-gradient(circle at 50% 50%, var(--c3) 0%, var(--c2) 45%, var(--c1) 100%);
  box-shadow: 0 0 14px var(--c2);
  position: relative;
}
.cft-pulse::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(circle at 50% 50%, var(--c3), transparent 65%);
  animation: cftBreath 2.4s ease-in-out infinite;
  pointer-events: none;
}
/* Doble cónico a distinta velocidad: dos anillos que se cruzan. */
.cft-dual {
  background: conic-gradient(from 0deg, var(--c1), var(--c3), var(--c2), var(--c1), var(--c2), var(--c1));
  box-shadow: 0 0 16px var(--c2), 0 0 30px var(--c1);
  animation: cfSpin 3.4s linear infinite;
}
/* Destellos: puntos fijos sobre base y capa que parpadea. */
.cft-spark {
  background:
    radial-gradient(1.5px 1.5px at 22% 26%, var(--c3), transparent),
    radial-gradient(1.5px 1.5px at 76% 34%, var(--c3), transparent),
    radial-gradient(1px 1px   at 44% 76%, var(--c3), transparent),
    radial-gradient(1.5px 1.5px at 66% 80%, var(--c3), transparent),
    linear-gradient(140deg, var(--c1), var(--c2));
  box-shadow: 0 0 14px var(--c2);
  position: relative;
}
.cft-spark::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(circle at 50% 50%, var(--c3), transparent 70%);
  animation: cftBreath 1.9s ease-in-out infinite;
  pointer-events: none;
}
/* Ficha de casino: cuñas alternas. */
.cft-chip {
  background: repeating-conic-gradient(from 0deg,
    var(--c2) 0deg 22.5deg, var(--c3) 22.5deg 45deg);
  box-shadow: 0 0 12px var(--c2);
  animation: cfSpin 7s linear infinite;
}
/* Halo: fondo quieto, aura que late. El más barato de todos. */
.cft-halo {
  background: linear-gradient(135deg, var(--c1), var(--c2));
  position: relative;
}
.cft-halo::after {
  content: ''; position: absolute; inset: -3px; border-radius: inherit;
  box-shadow: 0 0 16px var(--c2);
  animation: cftBreath 2.8s ease-in-out infinite;
  pointer-events: none;
}
/* Parpadeo eléctrico: giro rápido + capa que aparece a saltos. */
.cft-flick {
  background: conic-gradient(from 0deg, var(--c1), var(--c2), var(--c3), var(--c2), var(--c1));
  box-shadow: 0 0 16px var(--c2);
  animation: cfSpin 1.6s linear infinite;
  position: relative;
}
.cft-flick::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: var(--c3);
  opacity: 0;
  animation: cftFlick 2.6s steps(1) infinite;
  pointer-events: none;
}

/* El contenido gira al revés en las técnicas que rotan, para que la cara
   del avatar no dé vueltas. */
.cft-conic > *, .cft-dual > *, .cft-chip > *, .cft-flick > * {
  animation: cfSpinBack 5s linear infinite;
}
.cft-dual > *  { animation-duration: 3.4s; }
.cft-chip > *  { animation-duration: 7s; }
.cft-flick > * { animation-duration: 1.6s; }

@keyframes cftSweep { to { background-position: -280% 0; } }
@keyframes cftBreath { 0%,100% { opacity: .25; } 50% { opacity: .85; } }
@keyframes cftFlick  { 0%,100% { opacity: 0; } 48% { opacity: 0; } 50% { opacity: .55; } 54% { opacity: 0; } }

/* ── FONDOS PARAMÉTRICOS ─────────────────────────────────────────── */

.cbt-drift, .cbt-spin, .cbt-scan, .cbt-stars, .cbt-pulse,
.cbt-wave, .cbt-grid, .cbt-sweep, .cbt-rain, .cbt-orbit { --c1:#111; --c2:#555; --c3:#ccc; }

.cbt-drift {
  background: linear-gradient(125deg, var(--c1), var(--c2) 45%, var(--c3) 60%, var(--c2) 75%, var(--c1));
  background-size: 300% 300%;
  animation: cbDrift 11s ease-in-out infinite;
}
.cbt-spin {
  background: repeating-conic-gradient(from 0deg at 50% 50%,
    var(--c1) 0deg 15deg, var(--c2) 15deg 30deg);
  animation: cbRotate 30s linear infinite;
}
.cbt-scan {
  background:
    repeating-linear-gradient(180deg, var(--c3) 0 2px, transparent 2px 16px),
    linear-gradient(160deg, var(--c1), var(--c2));
  background-size: 100% 64px, 100% 100%;
  animation: cbtScan 2.6s linear infinite;
}
.cbt-stars {
  background:
    radial-gradient(1.5px 1.5px at 18% 24%, var(--c3), transparent),
    radial-gradient(2px 2px   at 62% 58%, var(--c3), transparent),
    radial-gradient(1px 1px   at 84% 30%, var(--c3), transparent),
    radial-gradient(1.5px 1.5px at 38% 78%, var(--c3), transparent),
    linear-gradient(170deg, var(--c1), var(--c2));
  background-size: 180px 180px, 220px 220px, 150px 150px, 200px 200px, 100% 100%;
  animation: cbtStars 26s linear infinite;
}
.cbt-pulse {
  background: radial-gradient(ellipse at 50% 45%, var(--c2) 0%, var(--c1) 75%);
  position: relative;
}
.cbt-pulse::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 45%, var(--c3), transparent 60%);
  animation: cftBreath 3.6s ease-in-out infinite;
  pointer-events: none;
}
.cbt-wave {
  background:
    repeating-linear-gradient(100deg, var(--c3) 0 3px, transparent 3px 26px),
    linear-gradient(180deg, var(--c1), var(--c2));
  background-size: 200% 100%, 100% 100%;
  animation: cbtWave 7s ease-in-out infinite;
}
.cbt-grid {
  background:
    repeating-linear-gradient(0deg,  transparent 0 20px, var(--c3) 20px 21px),
    repeating-linear-gradient(90deg, transparent 0 20px, var(--c2) 20px 21px),
    linear-gradient(190deg, var(--c1), var(--c2));
  background-size: 100% 21px, 21px 100%, 100% 100%;
  animation: cbtGrid 5s linear infinite;
}
.cbt-sweep {
  background:
    linear-gradient(105deg, transparent 42%, var(--c3) 50%, transparent 58%),
    linear-gradient(150deg, var(--c1), var(--c2));
  background-size: 260% 100%, 100% 100%;
  animation: cbtSweepBg 4.5s linear infinite;
}
.cbt-rain {
  background:
    repeating-linear-gradient(170deg, var(--c3) 0 3px, transparent 3px 22px),
    linear-gradient(180deg, var(--c1), var(--c2));
  background-size: 70px 110px, 100% 100%;
  animation: cbtRain 1.8s linear infinite;
}
.cbt-orbit {
  background:
    radial-gradient(circle at 50% 50%, var(--c3) 0 4%, transparent 5%),
    repeating-conic-gradient(from 0deg at 50% 50%, var(--c1) 0deg 25deg, var(--c2) 25deg 50deg);
  animation: cbRotate 22s linear infinite;
}

@keyframes cbtScan     { to { background-position: 0 64px, 0 0; } }
@keyframes cbtStars    { to { background-position: 180px 0, -220px 0, 150px 0, -200px 0, 0 0; } }
@keyframes cbtWave     { 0%,100% { background-position: 0 0, 0 0; } 50% { background-position: 200% 0, 0 0; } }
@keyframes cbtGrid     { to { background-position: 0 21px, 21px 0, 0 0; } }
@keyframes cbtSweepBg  { to { background-position: -260% 0, 0 0; } }
@keyframes cbtRain     { to { background-position: 0 110px, 0 0; } }

/* ═══════════════════════════════════════════════════════════════════
   8. PAUSADO — lo aplica js/motion.js
   `paused` congela el fotograma actual: al volver a pantalla la
   animación continúa donde estaba, sin saltos ni reinicios.
═══════════════════════════════════════════════════════════════════ */
.anim-paused,
.anim-paused::before,
.anim-paused::after,
.anim-paused * { animation-play-state: paused !important; }

/* Pestaña en segundo plano: se para todo el sitio. Los navegadores ya
   limitan los timers, pero no las animaciones CSS, que siguen quemando
   GPU y batería con la ventana oculta. */
.anim-hidden *,
.anim-hidden *::before,
.anim-hidden *::after { animation-play-state: paused !important; }

/* `content-visibility` deja que el navegador se salte por completo el
   render de las filas del ranking que están fuera de pantalla.
   `contain-intrinsic-size` reserva la altura para que la barra de scroll
   no dé saltos al entrar y salir. */
.leaderboard-table tbody tr {
  content-visibility: auto;
  contain-intrinsic-size: auto 44px;
}
.cos-grid, .cos-avatar-grid {
  content-visibility: auto;
  contain-intrinsic-size: auto 320px;
}

/* `contain: paint` aquí NO: recortaría los ::after de .cft-halo (inset:-3px)
   y el aura de .cft-spark, que se salen del borde a propósito. El ahorro real
   ya lo da `content-visibility` en las filas del ranking. Se deja solo en el
   avatar, que sí tiene overflow:hidden y no proyecta nada fuera. */
.ca { contain: paint; }
