/* Marco de rango + aura de premio, alrededor de la foto.
   ------------------------------------------------------------------
   Dos capas sobre la MISMA foto:
     capa 1, el marco = tu rango  -> el aro dibujado que le toca (data-tier),
             más la chapa con el animal del rango y la división.
     capa 2, el aura = lo que has ganado -> data-aura="1..6" y data-tone, la
             escalera que se explica más abajo. Va por delante Y por detrás de la
             foto, sin tocar el marco.

   Los siete aros son dibujos hechos para PBC (static/img/ranks/*.webp): bronce,
   plata, oro, platino, esmeralda, diamante y maestro, cada uno con más herraje
   que el anterior. Gran Maestro lleva el de Maestro con una luz que respira.

   Reglas que no se pueden romper:
   * La corona necesita hueco por encima de la foto. Ese hueco se reserva SIEMPRE
     (.pbc-flair tiene padding aunque no haya corona), así ni se corta en las
     listas apretadas ni la lista pega un salto el día que alguien gana. La chapa
     de abajo reserva el suyo igual.
   * Nada gira ALREDEDOR del marco (Guille, 24/08/2026): la luz cruza por delante
     y por detrás de la foto, y el aro metálico que rodeaba el escudo se quitó.
   * La corona es solo del escalón más alto. Si la lleva mucha gente no significa
     nada.
   * Con "reducir movimiento" activado el aura se queda quieta, no desaparece.

   Nombres de clase: nada de "avatar" ni "image" (regla global de
   mobile-responsive.css, que infla cualquier cosa que se llame así en el móvil). */

:root {
  /* El dorado del podio, uno solo para aro, halo, corona y nombre. */
  --flair-gold: #e6b422;
  --flair-gold-lit: #fff3c4;
  --flair-gold-soft: rgba(230, 180, 34, .55);
}

/* ── El escudo (perfil, fichas, listas de clases e intercambios) ───────────── */
.pbc-flair {
  --flair-size: 2.5rem;
  --flair-color: #a97142;
  --flair-light: #d8a06a;
  --flair-dark: #5d3d22;
  position: relative;
  display: inline-block;
  /* EL HUECO DE LA CORONA (arriba) Y EL DE LA CHAPA (abajo). Siempre, haya o no:
     así la fila mide lo mismo antes y después de ganar.
     A LOS LADOS igual (Guille 13/08/2026): el marco se pinta a 1,5 veces la foto,
     así que sobresale un cuarto del tamaño por cada lado; sin ese hueco el borde
     izquierdo se comía el marco en la ficha del intercambio. */
  padding: calc(var(--flair-size) * .34) calc(var(--flair-size) * .25)
           calc(var(--flair-size) * .3);
  line-height: 0;
  overflow: visible;
  vertical-align: middle;
}

/* El círculo de la foto. Va por encima de todo el herraje. */
.pbc-flair-photo {
  position: relative;
  display: block;
  /* !important a propósito: en móvil hay hojas de la casa que fuerzan
     img/contenedores a su tamaño natural (el mismo choque con
     viewport-fix.css que ya se documentó en friend-invite.css). Sin esto la
     foto se pinta ENORME en vez del circulito (Guille 18/08/2026). */
  width: var(--flair-size) !important;
  height: var(--flair-size) !important;
  border-radius: 50%;
  overflow: hidden;              /* la FOTO sí se recorta en redondo */
  background: #02A9CA;
  color: #fff;
  font-weight: 700;
  font-size: calc(var(--flair-size) * .42);
  line-height: var(--flair-size);
  text-align: center;
  z-index: 3;
}

.pbc-flair-photo img {
  width: 100% !important;
  height: 100% !important;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}

/* Sin foto propia, el animal del rango hace de foto (Guille, 12/08/2026).

   18/08/2026, Guille: los siete dibujos se rehicieron para que el animal LLENE
   el círculo y asome por el borde, y vienen YA CON SU PROPIO ARO dentro del PNG
   (los recompuso ChatGPT a partir de nuestros originales: mismo animal, mismo
   aro, solo más grande). Eso cambia dos cosas respecto a antes:

     * el aro del CSS se apaga cuando la cara es un animal, porque si no saldría
       DOS VECES, uno encima del otro;
     * el dibujo se pinta justo en el hueco que ocupaba ese aro (1,5 veces el
       círculo, centrado en él), así el conjunto mide exactamente lo mismo que
       antes y ninguna lista da un salto.

   Ya no hace falta la máscara de dos piezas que cortaba los hombros: el dibujo
   trae su propio aro y se recorta solo. */
.pbc-flair-photo.pbc-flair-critter {
  overflow: visible;
  /* Sin el círculo azul de debajo: el dibujo ya trae su propio fondo dentro del
     aro, y el azul asomaba por el hueco como si fuera otro aro más. */
  background: transparent;
}

.pbc-flair-photo.pbc-flair-critter img.pbc-flair-critter-img {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 150%;
  height: 150%;
  transform: translate(-50%, -50%);
  object-fit: contain;
  object-position: center;
  border-radius: 0;
}

/* El aro del CSS, apagado cuando la cara ya es un animal con su aro dibujado.
   Con foto propia (la mayoría) no cambia nada: sigue el aro de siempre. */
.pbc-flair:has(.pbc-flair-critter)::before { display: none; }

/* El MISMO animal, pero dentro de un circulito cualquiera de la web (la barra de
   arriba, el menú, los mensajes directos, las listas de gente…). Esas pantallas
   tienen su propio círculo y su propio CSS, así que aquí solo se arregla la
   imagen: entera y centrada, nunca recortada como una foto. Centrada y no
   apoyada abajo desde el 18/08/2026: el dibujo trae su aro y es simétrico, así
   que el aro cae justo sobre el borde del círculo. La pone la
   etiqueta {% avatar %} (mainmodule/templatetags/flair_tags.py) y el chat desde
   JavaScript. Va con !important porque varias hojas de móvil estiran a lo ancho
   cualquier <img> dentro de un avatar. */
img.pbc-critter {
  width: 100% !important;
  height: 100% !important;
  object-fit: contain !important;
  object-position: center !important;
  border-radius: 0 !important;
  display: block;
  background: transparent !important;
}

/* ── Capa 1: el marco del rango ───────────────────────────────────────────── */
/* Los siete aros son DIBUJOS (static/img/ranks/*.webp), uno por rango, hechos
   para PBC el 11/08/2026. Van de fondo en una capa detrás de la foto, nunca como
   <img>: así no hay una etiqueta más por cada cara de una lista, el navegador se
   los guarda como cualquier imagen y el hueco del centro queda libre para la foto.

   La cuenta que lo ata todo: en el dibujo, el agujero del centro mide DOS TERCIOS
   del ancho. Por eso el marco se pinta a 1,5 veces el tamaño de la foto y su
   agujero cae justo encima de ella, en todos los tamaños y en los siete rangos
   (están recortados con el agujero centrado a propósito). */
.pbc-flair::before {
  content: "";
  position: absolute;
  left: 50%;
  top: calc(var(--flair-size) * .34 + var(--flair-size) / 2);
  width: calc(var(--flair-size) * 1.5);
  height: calc(var(--flair-size) * 1.5);
  margin-left: calc(var(--flair-size) * -.75);
  margin-top: calc(var(--flair-size) * -.75);
  background: var(--flair-img) center / contain no-repeat;
  z-index: 2;
  pointer-events: none;
}

/* Qué dibujo lleva cada rango. Se guarda en una variable y no directamente en el
   fondo para poder usar la MISMA lista en el marco grande y en el pequeño del
   chat: si estuviera escrita dos veces, el día que se cambie un aro se cambiaría
   en un sitio y no en el otro. */
[data-tier="bronce"]    { --flair-img: url("../img/ranks/bronce.a9f3441ecf96.webp"); }
[data-tier="plata"]     { --flair-img: url("../img/ranks/plata.33182e070e85.webp"); }
[data-tier="oro"]       { --flair-img: url("../img/ranks/oro.d74b82aca3bb.webp"); }
[data-tier="platino"]   { --flair-img: url("../img/ranks/platino.ac7263357a1c.webp"); }
[data-tier="esmeralda"] { --flair-img: url("../img/ranks/esmeralda.adc318b8e780.webp"); }
[data-tier="diamante"]  { --flair-img: url("../img/ranks/diamante.2386f4bcbbf1.webp"); }
[data-tier="maestro"]   { --flair-img: url("../img/ranks/maestro.0cff4bc773a0.webp"); }

/* Sombra corta bajo la foto: despega el conjunto del fondo. No se le pone al
   animal del rango: ese dibujo no es redondo (trae su aro y asoma por fuera) y
   la sombra circular se le vería por debajo. */
.pbc-flair[data-tier]:not([data-tier=""]) .pbc-flair-photo:not(.pbc-flair-critter) {
  box-shadow: 0 calc(var(--flair-size) * .03) calc(var(--flair-size) * .07)
              rgba(11, 20, 26, .3);
}

/* Gran Maestro lleva el aro de Maestro y encima su propia luz, que respira. Es lo
   único del marco que se mueve solo, y son cien personas como mucho. */
.pbc-flair[data-gm="1"]::before {
  filter: drop-shadow(0 0 calc(var(--flair-size) * .09) var(--flair-light));
  animation: pbcFlairBreathe 4.5s ease-in-out infinite;
}

/* Sin rango (o con el marco quitado desde el perfil) no hay marco ni chapa: queda
   el círculo de siempre. Escrito así, y no quitando elementos, para que el
   interruptor del perfil encienda y apague cambiando UN atributo. */
.pbc-flair[data-tier=""]::before,
.pbc-flair:not([data-tier])::before { display: none; }

.pbc-flair[data-tier=""] .pbc-flair-plate,
.pbc-flair:not([data-tier]) .pbc-flair-plate { display: none; }

/* ── La chapa de abajo: el animal del rango y la división ──────────────────── */
/* Es el "símbolo" del escudo: el animal grande, con contorno oscuro y la
   división en su pastilla al lado. A lo Duolingo: formas gordas y línea negra,
   nada de filigrana fina que se pierda en el móvil. */
.pbc-flair-plate {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--flair-size) * .05);
  padding: calc(var(--flair-size) * .025) calc(var(--flair-size) * .09);
  background: linear-gradient(180deg, var(--flair-light), var(--flair-color));
  border: calc(var(--flair-size) * .022) solid var(--flair-dark);
  border-radius: 999px;
  box-shadow: 0 calc(var(--flair-size) * .02) 0 rgba(11, 20, 26, .25);
  color: #fff;
  font-size: calc(var(--flair-size) * .17);
  font-weight: 900;
  line-height: 1;
  white-space: nowrap;
  z-index: 4;
  pointer-events: none;
}

.pbc-flair-plate .m {
  font-size: calc(var(--flair-size) * .26);
  line-height: 1;
  filter: drop-shadow(0 1px 1px rgba(11, 20, 26, .45));
}

/* La división, en su propia pastilla oscura: se lee de un vistazo aunque el
   rango sea de color claro. */
.pbc-flair-plate .d {
  background: var(--flair-dark);
  border-radius: 999px;
  padding: calc(var(--flair-size) * .02) calc(var(--flair-size) * .06);
  font-size: calc(var(--flair-size) * .15);
  letter-spacing: .04em;
}

/* ── Capa 2: LA ESCALERA DEL AURA (Guille, 24/08/2026) ────────────────────────
   Antes aquí había un anillo partido girando, un aro alrededor y un halo, y solo
   los tenía el podio del mes. Guille los tumbó los dos: "no quiero nada que vuele
   hacia los lados ni ese aro que rodea el marco; quiero cintas de luz que crucen
   por delante del círculo, y que pueda ganarlo más gente".

   De ahí salen dos cosas:

   * **El dibujo.** Cintas de luz que envuelven la cabeza, estrellas dando
     vueltas como los electrones de un átomo, destellos de cuatro rayos y, arriba
     del todo, la corona. Nada gira alrededor del marco.
   * **La escalera.** SEIS escalones (``mainmodule.flair.AURA_PIECES``): cuantas
     más cintas, estrellas y destellos, más alto. El color sube con ellos
     (bronce, plata, oro) para que el escalón se lea sin contar piezas.

   CÓMO ENVUELVE: cada cinta se pinta DOS VECES, una capa por debajo de la foto y
   otra por encima, y cada copia se recorta a su mitad. Como la foto va en medio,
   el trozo de atrás queda tapado por la cara. Sin este truco haría falta 3D de
   verdad, que en el móvil parpadea y gasta.

   El HTML de las dos capas es templates/includes/aura_layer.html, y
   static/js/flair.js monta ese MISMO HTML desde el navegador. */

/* Los tres tonos. Cambiar un color es tocar una línea, no repetir el bloque. */
[data-tone="bronze"] {
  --au-line: rgba(255, 214, 168, .58);
  --au-line-back: rgba(255, 214, 168, .3);
  --au-core: #fff2e2;
  --au-glow: rgba(226, 150, 78, .95);
  --au-star-fill: radial-gradient(circle at 50% 50%, #fff6ea 0 22%, #e9a765 62%, #b06f2e 100%);
}
[data-tone="silver"] {
  --au-line: rgba(226, 241, 255, .6);
  --au-line-back: rgba(226, 241, 255, .3);
  --au-core: #f6fbff;
  --au-glow: rgba(150, 205, 255, .95);
  --au-star-fill: radial-gradient(circle at 50% 50%, #ffffff 0 22%, #d7ecff 62%, #8fc0ea 100%);
}
[data-tone="gold"] {
  --au-line: rgba(255, 236, 176, .62);
  --au-line-back: rgba(255, 236, 176, .34);
  --au-core: #fffdf2;
  --au-glow: rgba(255, 214, 110, .95);
  --au-star-fill: radial-gradient(circle at 50% 50%, #fffdf3 0 22%, #ffd45e 62%, #e6a90f 100%);
}

/* La caja del aura: del tamaño de la foto y centrada sobre ella, con la misma
   cuenta que usa el marco (el hueco de la corona más media foto). */
.pbc-aura {
  position: absolute;
  left: 50%;
  top: calc(var(--flair-size) * .34 + var(--flair-size) / 2);
  width: var(--flair-size);
  height: var(--flair-size);
  margin-left: calc(var(--flair-size) * -.5);
  margin-top: calc(var(--flair-size) * -.5);
  pointer-events: none;
  line-height: 0;
}
.pbc-aura-back { z-index: 1; }
.pbc-aura-front { z-index: 6; }

/* El resplandor de detrás de la cabeza: solo en los dos escalones de oro. */
.au-glow {
  position: absolute;
  inset: -50%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 236, 178, .5) 0%,
              rgba(255, 205, 90, .32) 34%, rgba(255, 190, 60, .1) 58%, transparent 74%);
  animation: auBreathe 2.6s ease-in-out infinite;
}

/* Las cintas. Cada una es una elipse inclinada, y cada capa se queda con su
   mitad: la de delante con la de abajo, la de detrás con la de arriba. */
.au-band {
  position: absolute;
  inset: -34%;
  border-radius: 50%;
  border: calc(var(--flair-size) * .055) solid var(--au-line);
  transform: rotate(var(--au-tilt)) scaleY(var(--au-flat));
  /* Dos sombras: la de dentro pega la luz al trazo y la de fuera hace el halo.
     Con una sola, la cinta se perdía sobre fondo claro. */
  box-shadow: 0 0 calc(var(--flair-size) * .05) var(--au-glow),
              0 0 calc(var(--flair-size) * .14) var(--au-glow) inset;
  animation: auBandPulse 2.4s ease-in-out infinite;
}
/* Cada capa se queda con su mitad, y se pasan un pelo (52% y no 50%) para que
   el canto del corte no se vea como un arañazo en los lados. */
.pbc-aura-front .au-band { clip-path: inset(48% 0 0 0); }
.pbc-aura-back .au-band  { clip-path: inset(0 0 48% 0); border-color: var(--au-line-back); }
.au-b1 { --au-tilt: -22deg; --au-flat: .42; }
.au-b2 { --au-tilt: 38deg; --au-flat: .34; }
.au-b3 { --au-tilt: 96deg; --au-flat: .3; }
.au-b4 { --au-tilt: 140deg; --au-flat: .46; }
.au-b2 { animation-delay: -.6s; }
.au-b3 { animation-delay: -1.2s; }
.au-b4 { animation-delay: -1.8s; }

/* Los destellos: núcleo redondo y cuatro rayos, como el brillo de un arma
   encantada. Van clavados en un punto de su cinta y laten ahí. */
.au-flare {
  position: absolute;
  width: var(--au-fs);
  height: var(--au-fs);
  transform: translate(-50%, -50%);
  animation: auFlare 2s ease-in-out infinite;
}
.au-core, .au-ray {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.au-core {
  width: 24%;
  height: 24%;
  border-radius: 50%;
  background: radial-gradient(circle, #fff 0 38%, var(--au-core) 62%, transparent 74%);
  filter: drop-shadow(0 0 3px var(--au-glow));
}
.au-ray {
  width: 100%;
  height: 8%;
  background: linear-gradient(90deg, transparent 0%, var(--au-core) 50%, transparent 100%);
}
.au-r2 { transform: translate(-50%, -50%) rotate(90deg); width: 78%; }
.au-r3 { transform: translate(-50%, -50%) rotate(45deg); width: 46%; height: 5%; opacity: .75; }
.au-r4 { transform: translate(-50%, -50%) rotate(-45deg); width: 46%; height: 5%; opacity: .75; }
.au-f1 { left: 123.3%; top: 40.3%; --au-fs: 46%; animation-delay: -0.7s; }
.au-f2 { left: 4.7%; top: 95.4%; --au-fs: 32%; animation-delay: -1.4s; }
.au-f3 { left: 40.5%; top: 78.6%; --au-fs: 30%; animation-delay: -2.1s; }
.au-f4 { left: 24.9%; top: 99.9%; --au-fs: 34%; animation-delay: -2.8s; }
.au-f5 { left: 61.0%; top: -2.8%; --au-fs: 26%; animation-delay: -3.5s; }

/* Chispas sueltas que suben y se apagan. Solo en el escalón más alto. */
.au-spark {
  position: absolute;
  width: 7%;
  height: 7%;
  border-radius: 50%;
  background: radial-gradient(circle, var(--au-core) 0 30%, var(--au-glow) 60%, transparent 72%);
  animation-name: auSpark;
  animation-timing-function: ease-out;
  animation-iteration-count: infinite;
  opacity: 0;
}
.au-p1 { left: 18%; top: 74%; animation-duration: 2.8s; animation-delay: -0.6s; }
.au-p2 { left: 78%; top: 66%; animation-duration: 3.4s; animation-delay: -1.1s; }
.au-p3 { left: 34%; top: 88%; animation-duration: 2.4s; animation-delay: -1.7s; }
.au-p4 { left: 66%; top: 82%; animation-duration: 3.9s; animation-delay: -2.2s; }
.au-p5 { left: 12%; top: 52%; animation-duration: 3.2s; animation-delay: -2.8s; }
.au-p6 { left: 88%; top: 44%; animation-duration: 3.0s; animation-delay: -3.3s; }

/* Las estrellas en órbita. La trayectoria viene calculada paso a paso (elipse
   inclinada) en los @keyframes de abajo: si se aplastara el contenedor, la
   estrella saldría estirada como una raya. */
.au-star {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 23%;
  height: 23%;
  margin: calc(23% / -2) 0 0 calc(23% / -2);
  background: var(--au-star-fill);
  clip-path: polygon(50% 0%, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0% 50%, 40% 40%);
  filter: drop-shadow(0 0 .14em var(--au-glow));
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  opacity: 0;
}
.pbc-aura-front .au-s1 { animation-name: auStarF1; animation-duration: 4.7s; animation-delay: 0.0s; }
.pbc-aura-back .au-s1 { animation-name: auStarB1; animation-duration: 4.7s; animation-delay: 0.0s; }
.pbc-aura-front .au-s2 { animation-name: auStarF2; animation-duration: 5.9s; animation-delay: -1.9s; }
.pbc-aura-back .au-s2 { animation-name: auStarB2; animation-duration: 5.9s; animation-delay: -1.9s; }
.pbc-aura-front .au-s3 { animation-name: auStarF3; animation-duration: 4.1s; animation-delay: -3.1s; }
.pbc-aura-back .au-s3 { animation-name: auStarB3; animation-duration: 4.1s; animation-delay: -3.1s; }

/* La chapa del rango se viste del tono del aura: el escudo entero dice a qué
   escalón ha llegado esa persona, no solo las cintas. */
.pbc-flair[data-tone="gold"] .pbc-flair-plate {
  background: linear-gradient(180deg, var(--flair-gold-lit), var(--flair-gold));
  border-color: #fff8dc;
  color: #4a3708;
  text-shadow: none;
}
.pbc-flair[data-tone="silver"] .pbc-flair-plate {
  background: linear-gradient(180deg, #ffffff, #cfe2f3);
  border-color: #ffffff;
  color: #24425e;
  text-shadow: none;
}
.pbc-flair[data-tone="bronze"] .pbc-flair-plate {
  background: linear-gradient(180deg, #ffe6cc, #d59258);
  border-color: #fff1e0;
  color: #4a2c0c;
  text-shadow: none;
}
/* La corona (escalón más alto) se enciende con el tono. */
.pbc-flair[data-aura] .pbc-flair-crown {
  filter: drop-shadow(0 2px 2px rgba(11, 20, 26, .35))
          drop-shadow(0 0 5px var(--au-glow));
}

@keyframes auBreathe {
  0%, 100% { opacity: .62; transform: scale(.94); }
  50%      { opacity: 1;   transform: scale(1.06); }
}
@keyframes auBandPulse {
  0%, 100% { opacity: .72; }
  50%      { opacity: 1; }
}
@keyframes auFlare {
  0%, 100% { opacity: .5; transform: translate(-50%, -50%) scale(.85) rotate(0deg); }
  50%      { opacity: 1;  transform: translate(-50%, -50%) scale(1.1) rotate(14deg); }
}
@keyframes auSpark {
  0%   { opacity: 0;   transform: translateY(18%) scale(.5); }
  25%  { opacity: .95; }
  100% { opacity: 0;   transform: translateY(-92%) scale(.9); }
}
@keyframes auStarF1 {
  0.0000% { transform: translate(305.99%, -99.42%) scale(0.720); opacity: 0.500; }
  4.1667% { transform: translate(310.49%, -50.10%) scale(0.808); opacity: 1.000; }
  8.3333% { transform: translate(293.83%, 2.63%) scale(0.890); opacity: 1.000; }
  12.5000% { transform: translate(257.14%, 55.19%) scale(0.960); opacity: 1.000; }
  16.6667% { transform: translate(202.94%, 103.99%) scale(1.014); opacity: 1.000; }
  20.8333% { transform: translate(134.90%, 145.70%) scale(1.048); opacity: 1.000; }
  25.0000% { transform: translate(57.67%, 177.48%) scale(1.060); opacity: 1.000; }
  29.1667% { transform: translate(-23.50%, 197.16%) scale(1.048); opacity: 1.000; }
  33.3333% { transform: translate(-103.06%, 203.41%) scale(1.014); opacity: 1.000; }
  37.5000% { transform: translate(-175.59%, 195.80%) scale(0.960); opacity: 1.000; }
  41.6667% { transform: translate(-236.16%, 174.84%) scale(0.890); opacity: 1.000; }
  45.8333% { transform: translate(-280.64%, 141.97%) scale(0.808); opacity: 1.000; }
  50.0000% { transform: translate(-305.99%, 99.42%) scale(0.720); opacity: 0.500; }
  54.1667% { transform: translate(-310.49%, 50.10%) scale(0.632); opacity: 0.000; }
  58.3333% { transform: translate(-293.83%, -2.63%) scale(0.550); opacity: 0.000; }
  62.5000% { transform: translate(-257.14%, -55.19%) scale(0.480); opacity: 0.000; }
  66.6667% { transform: translate(-202.94%, -103.99%) scale(0.426); opacity: 0.000; }
  70.8333% { transform: translate(-134.90%, -145.70%) scale(0.392); opacity: 0.000; }
  75.0000% { transform: translate(-57.67%, -177.48%) scale(0.380); opacity: 0.000; }
  79.1667% { transform: translate(23.50%, -197.16%) scale(0.392); opacity: 0.000; }
  83.3333% { transform: translate(103.06%, -203.41%) scale(0.426); opacity: 0.000; }
  87.5000% { transform: translate(175.59%, -195.80%) scale(0.480); opacity: 0.000; }
  91.6667% { transform: translate(236.16%, -174.84%) scale(0.550); opacity: 0.000; }
  95.8333% { transform: translate(280.64%, -141.97%) scale(0.632); opacity: 0.000; }
  100.0000% { transform: translate(305.99%, -99.42%) scale(0.720); opacity: 0.500; }
}
@keyframes auStarB1 {
  0.0000% { transform: translate(305.99%, -99.42%) scale(0.720); opacity: 0.375; }
  4.1667% { transform: translate(310.49%, -50.10%) scale(0.808); opacity: 0.000; }
  8.3333% { transform: translate(293.83%, 2.63%) scale(0.890); opacity: 0.000; }
  12.5000% { transform: translate(257.14%, 55.19%) scale(0.960); opacity: 0.000; }
  16.6667% { transform: translate(202.94%, 103.99%) scale(1.014); opacity: 0.000; }
  20.8333% { transform: translate(134.90%, 145.70%) scale(1.048); opacity: 0.000; }
  25.0000% { transform: translate(57.67%, 177.48%) scale(1.060); opacity: 0.000; }
  29.1667% { transform: translate(-23.50%, 197.16%) scale(1.048); opacity: 0.000; }
  33.3333% { transform: translate(-103.06%, 203.41%) scale(1.014); opacity: 0.000; }
  37.5000% { transform: translate(-175.59%, 195.80%) scale(0.960); opacity: 0.000; }
  41.6667% { transform: translate(-236.16%, 174.84%) scale(0.890); opacity: 0.000; }
  45.8333% { transform: translate(-280.64%, 141.97%) scale(0.808); opacity: 0.000; }
  50.0000% { transform: translate(-305.99%, 99.42%) scale(0.720); opacity: 0.375; }
  54.1667% { transform: translate(-310.49%, 50.10%) scale(0.632); opacity: 0.750; }
  58.3333% { transform: translate(-293.83%, -2.63%) scale(0.550); opacity: 0.750; }
  62.5000% { transform: translate(-257.14%, -55.19%) scale(0.480); opacity: 0.750; }
  66.6667% { transform: translate(-202.94%, -103.99%) scale(0.426); opacity: 0.750; }
  70.8333% { transform: translate(-134.90%, -145.70%) scale(0.392); opacity: 0.750; }
  75.0000% { transform: translate(-57.67%, -177.48%) scale(0.380); opacity: 0.750; }
  79.1667% { transform: translate(23.50%, -197.16%) scale(0.392); opacity: 0.750; }
  83.3333% { transform: translate(103.06%, -203.41%) scale(0.426); opacity: 0.750; }
  87.5000% { transform: translate(175.59%, -195.80%) scale(0.480); opacity: 0.750; }
  91.6667% { transform: translate(236.16%, -174.84%) scale(0.550); opacity: 0.750; }
  95.8333% { transform: translate(280.64%, -141.97%) scale(0.632); opacity: 0.750; }
  100.0000% { transform: translate(305.99%, -99.42%) scale(0.720); opacity: 0.375; }
}
@keyframes auStarF2 {
  0.0000% { transform: translate(239.10%, 215.29%) scale(0.720); opacity: 0.500; }
  4.1667% { transform: translate(203.09%, 238.89%) scale(0.808); opacity: 1.000; }
  8.3333% { transform: translate(153.24%, 246.22%) scale(0.890); opacity: 1.000; }
  12.5000% { transform: translate(92.95%, 236.76%) scale(0.960); opacity: 1.000; }
  16.6667% { transform: translate(26.33%, 211.18%) scale(1.014); opacity: 1.000; }
  20.8333% { transform: translate(-42.09%, 171.20%) scale(1.048); opacity: 1.000; }
  25.0000% { transform: translate(-107.64%, 119.55%) scale(1.060); opacity: 1.000; }
  29.1667% { transform: translate(-165.86%, 59.76%) scale(1.048); opacity: 1.000; }
  33.3333% { transform: translate(-212.77%, -4.11%) scale(1.014); opacity: 1.000; }
  37.5000% { transform: translate(-245.18%, -67.70%) scale(0.960); opacity: 1.000; }
  41.6667% { transform: translate(-260.89%, -126.67%) scale(0.890); opacity: 1.000; }
  45.8333% { transform: translate(-258.81%, -177.01%) scale(0.808); opacity: 1.000; }
  50.0000% { transform: translate(-239.10%, -215.29%) scale(0.720); opacity: 0.500; }
  54.1667% { transform: translate(-203.09%, -238.89%) scale(0.632); opacity: 0.000; }
  58.3333% { transform: translate(-153.24%, -246.22%) scale(0.550); opacity: 0.000; }
  62.5000% { transform: translate(-92.95%, -236.76%) scale(0.480); opacity: 0.000; }
  66.6667% { transform: translate(-26.33%, -211.18%) scale(0.426); opacity: 0.000; }
  70.8333% { transform: translate(42.09%, -171.20%) scale(0.392); opacity: 0.000; }
  75.0000% { transform: translate(107.64%, -119.55%) scale(0.380); opacity: 0.000; }
  79.1667% { transform: translate(165.86%, -59.76%) scale(0.392); opacity: 0.000; }
  83.3333% { transform: translate(212.77%, 4.11%) scale(0.426); opacity: 0.000; }
  87.5000% { transform: translate(245.18%, 67.70%) scale(0.480); opacity: 0.000; }
  91.6667% { transform: translate(260.89%, 126.67%) scale(0.550); opacity: 0.000; }
  95.8333% { transform: translate(258.81%, 177.01%) scale(0.632); opacity: 0.000; }
  100.0000% { transform: translate(239.10%, 215.29%) scale(0.720); opacity: 0.500; }
}
@keyframes auStarB2 {
  0.0000% { transform: translate(239.10%, 215.29%) scale(0.720); opacity: 0.375; }
  4.1667% { transform: translate(203.09%, 238.89%) scale(0.808); opacity: 0.000; }
  8.3333% { transform: translate(153.24%, 246.22%) scale(0.890); opacity: 0.000; }
  12.5000% { transform: translate(92.95%, 236.76%) scale(0.960); opacity: 0.000; }
  16.6667% { transform: translate(26.33%, 211.18%) scale(1.014); opacity: 0.000; }
  20.8333% { transform: translate(-42.09%, 171.20%) scale(1.048); opacity: 0.000; }
  25.0000% { transform: translate(-107.64%, 119.55%) scale(1.060); opacity: 0.000; }
  29.1667% { transform: translate(-165.86%, 59.76%) scale(1.048); opacity: 0.000; }
  33.3333% { transform: translate(-212.77%, -4.11%) scale(1.014); opacity: 0.000; }
  37.5000% { transform: translate(-245.18%, -67.70%) scale(0.960); opacity: 0.000; }
  41.6667% { transform: translate(-260.89%, -126.67%) scale(0.890); opacity: 0.000; }
  45.8333% { transform: translate(-258.81%, -177.01%) scale(0.808); opacity: 0.000; }
  50.0000% { transform: translate(-239.10%, -215.29%) scale(0.720); opacity: 0.375; }
  54.1667% { transform: translate(-203.09%, -238.89%) scale(0.632); opacity: 0.750; }
  58.3333% { transform: translate(-153.24%, -246.22%) scale(0.550); opacity: 0.750; }
  62.5000% { transform: translate(-92.95%, -236.76%) scale(0.480); opacity: 0.750; }
  66.6667% { transform: translate(-26.33%, -211.18%) scale(0.426); opacity: 0.750; }
  70.8333% { transform: translate(42.09%, -171.20%) scale(0.392); opacity: 0.750; }
  75.0000% { transform: translate(107.64%, -119.55%) scale(0.380); opacity: 0.750; }
  79.1667% { transform: translate(165.86%, -59.76%) scale(0.392); opacity: 0.750; }
  83.3333% { transform: translate(212.77%, 4.11%) scale(0.426); opacity: 0.750; }
  87.5000% { transform: translate(245.18%, 67.70%) scale(0.480); opacity: 0.750; }
  91.6667% { transform: translate(260.89%, 126.67%) scale(0.550); opacity: 0.750; }
  95.8333% { transform: translate(258.81%, 177.01%) scale(0.632); opacity: 0.750; }
  100.0000% { transform: translate(239.10%, 215.29%) scale(0.720); opacity: 0.375; }
}
@keyframes auStarF3 {
  0.0000% { transform: translate(-55.87%, 316.85%) scale(0.720); opacity: 0.500; }
  4.1667% { transform: translate(-108.09%, 296.51%) scale(0.808); opacity: 1.000; }
  8.3333% { transform: translate(-152.95%, 255.96%) scale(0.890); opacity: 1.000; }
  12.5000% { transform: translate(-187.38%, 197.97%) scale(0.960); opacity: 1.000; }
  16.6667% { transform: translate(-209.04%, 126.49%) scale(1.014); opacity: 1.000; }
  20.8333% { transform: translate(-216.46%, 46.39%) scale(1.048); opacity: 1.000; }
  25.0000% { transform: translate(-209.12%, -36.87%) scale(1.060); opacity: 1.000; }
  29.1667% { transform: translate(-187.54%, -117.62%) scale(1.048); opacity: 1.000; }
  33.3333% { transform: translate(-153.17%, -190.36%) scale(1.014); opacity: 1.000; }
  37.5000% { transform: translate(-108.37%, -250.12%) scale(0.960); opacity: 1.000; }
  41.6667% { transform: translate(-56.18%, -292.84%) scale(0.890); opacity: 1.000; }
  45.8333% { transform: translate(-0.16%, -315.60%) scale(0.808); opacity: 1.000; }
  50.0000% { transform: translate(55.87%, -316.85%) scale(0.720); opacity: 0.500; }
  54.1667% { transform: translate(108.09%, -296.51%) scale(0.632); opacity: 0.000; }
  58.3333% { transform: translate(152.95%, -255.96%) scale(0.550); opacity: 0.000; }
  62.5000% { transform: translate(187.38%, -197.97%) scale(0.480); opacity: 0.000; }
  66.6667% { transform: translate(209.04%, -126.49%) scale(0.426); opacity: 0.000; }
  70.8333% { transform: translate(216.46%, -46.39%) scale(0.392); opacity: 0.000; }
  75.0000% { transform: translate(209.12%, 36.87%) scale(0.380); opacity: 0.000; }
  79.1667% { transform: translate(187.54%, 117.62%) scale(0.392); opacity: 0.000; }
  83.3333% { transform: translate(153.17%, 190.36%) scale(0.426); opacity: 0.000; }
  87.5000% { transform: translate(108.37%, 250.12%) scale(0.480); opacity: 0.000; }
  91.6667% { transform: translate(56.18%, 292.84%) scale(0.550); opacity: 0.000; }
  95.8333% { transform: translate(0.16%, 315.60%) scale(0.632); opacity: 0.000; }
  100.0000% { transform: translate(-55.87%, 316.85%) scale(0.720); opacity: 0.500; }
}
@keyframes auStarB3 {
  0.0000% { transform: translate(-55.87%, 316.85%) scale(0.720); opacity: 0.375; }
  4.1667% { transform: translate(-108.09%, 296.51%) scale(0.808); opacity: 0.000; }
  8.3333% { transform: translate(-152.95%, 255.96%) scale(0.890); opacity: 0.000; }
  12.5000% { transform: translate(-187.38%, 197.97%) scale(0.960); opacity: 0.000; }
  16.6667% { transform: translate(-209.04%, 126.49%) scale(1.014); opacity: 0.000; }
  20.8333% { transform: translate(-216.46%, 46.39%) scale(1.048); opacity: 0.000; }
  25.0000% { transform: translate(-209.12%, -36.87%) scale(1.060); opacity: 0.000; }
  29.1667% { transform: translate(-187.54%, -117.62%) scale(1.048); opacity: 0.000; }
  33.3333% { transform: translate(-153.17%, -190.36%) scale(1.014); opacity: 0.000; }
  37.5000% { transform: translate(-108.37%, -250.12%) scale(0.960); opacity: 0.000; }
  41.6667% { transform: translate(-56.18%, -292.84%) scale(0.890); opacity: 0.000; }
  45.8333% { transform: translate(-0.16%, -315.60%) scale(0.808); opacity: 0.000; }
  50.0000% { transform: translate(55.87%, -316.85%) scale(0.720); opacity: 0.375; }
  54.1667% { transform: translate(108.09%, -296.51%) scale(0.632); opacity: 0.750; }
  58.3333% { transform: translate(152.95%, -255.96%) scale(0.550); opacity: 0.750; }
  62.5000% { transform: translate(187.38%, -197.97%) scale(0.480); opacity: 0.750; }
  66.6667% { transform: translate(209.04%, -126.49%) scale(0.426); opacity: 0.750; }
  70.8333% { transform: translate(216.46%, -46.39%) scale(0.392); opacity: 0.750; }
  75.0000% { transform: translate(209.12%, 36.87%) scale(0.380); opacity: 0.750; }
  79.1667% { transform: translate(187.54%, 117.62%) scale(0.392); opacity: 0.750; }
  83.3333% { transform: translate(153.17%, 190.36%) scale(0.426); opacity: 0.750; }
  87.5000% { transform: translate(108.37%, 250.12%) scale(0.480); opacity: 0.750; }
  91.6667% { transform: translate(56.18%, 292.84%) scale(0.550); opacity: 0.750; }
  95.8333% { transform: translate(0.16%, 315.60%) scale(0.632); opacity: 0.750; }
  100.0000% { transform: translate(-55.87%, 316.85%) scale(0.720); opacity: 0.375; }
}

/* ── El nombre dorado del 1º (en el chat y donde haga falta) ───────────────── */
.pbc-name-gold {
  background: linear-gradient(100deg, #b8860b 0%, var(--flair-gold) 25%,
                              var(--flair-gold-lit) 45%, var(--flair-gold) 65%,
                              #b8860b 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  font-weight: 800;
  animation: pbcFlairName 3.6s linear infinite;
}

/* El mismo nombre, en los otros dos tonos de la escalera. La plata va más
   oscura que el oro a propósito: sobre fondo blanco un plata claro no se lee. */
.pbc-name-silver {
  background: linear-gradient(100deg, #3f5f7a 0%, #8fb6d4 25%, #dceefc 45%,
                              #8fb6d4 65%, #3f5f7a 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  font-weight: 800;
  animation: pbcFlairName 3.6s linear infinite;
}

.pbc-name-bronze {
  background: linear-gradient(100deg, #8a5320 0%, #d19a5e 25%, #ffe6cc 45%,
                              #d19a5e 65%, #8a5320 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  font-weight: 800;
  animation: pbcFlairName 3.6s linear infinite;
}

/* ── El marco pequeño del chat ────────────────────────────────────────────── */
/* El circulito de la burbuja (.cc-ava) ya existía y lleva overflow:hidden, así
   que el aro NO puede ir dentro: va en su propia capa colgada de la burbuja,
   centrada sobre él y con la misma cuenta de siempre (el aro mide 1,5 veces la
   foto porque su agujero es dos tercios del dibujo). */
/* El circulito del chat, con marco: se le quita el aro de color que llevaba,
   porque ahora lo rodea el dibujo del rango. */
.cc-ava.pbc-fl {
  box-shadow: 0 1px 2px rgba(11, 20, 26, .28);
}

/* EL AURA EN EL CHAT, en pequeño (Guille, 24/08/2026).
   Una lista de chat pinta cientos de burbujas, así que aquí NO van las cuatro
   cintas ni las estrellas: se queda el resplandor del tono y UNA cinta, hechos
   con los dos pseudo-elementos de la capa que ya existía. Cero etiquetas nuevas
   por burbuja y se sigue viendo de lejos quién ha ganado algo. */
.cc-ava.pbc-fl[data-tone] {
  box-shadow: 0 0 7px 1px var(--au-glow);
}

.pbc-fl-ring {
  position: absolute;
  left: -3.05rem;
  top: -.5rem;
  width: 3.07rem;
  height: 3.07rem;
  background: var(--flair-img) center / contain no-repeat;
  pointer-events: none;
  z-index: 2;
}

.pbc-fl-ring[data-gm="1"] {
  filter: drop-shadow(0 0 .18rem var(--flair-light));
  animation: pbcFlairBreathe 4.5s ease-in-out infinite;
}

/* La chapita del animal, pegada debajo del circulito. Sin división: a ese tamaño
   el romano no se lee y el animal sí. */
.pbc-fl-seal {
  position: absolute;
  left: -2.55rem;
  top: 1.5rem;
  width: 2.05rem;
  text-align: center;
  font-size: .72rem;
  line-height: 1;
  z-index: 3;
  pointer-events: none;
  filter: drop-shadow(0 1px 1px rgba(11, 20, 26, .4));
}

/* La capa del aura en la burbuja: centrada en el circulito, por debajo de él. */
.pbc-fl-fx {
  position: absolute;
  left: -2.55rem;
  top: 0;
  width: 2.05rem;
  height: 2.05rem;
  pointer-events: none;
  z-index: 1;
  border-radius: 50%;
}

.pbc-fl-fx::before,
.pbc-fl-fx::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 50%;
}

/* El resplandor del tono, latiendo. Es lo que se ve de lejos en una lista. */
.pbc-fl-fx::before {
  width: 3.4rem;
  height: 3.4rem;
  margin: -1.7rem 0 0 -1.7rem;
  background: radial-gradient(circle, var(--au-glow) 0%, transparent 68%);
  opacity: .5;
  animation: auBreathe 2.6s ease-in-out infinite;
}

/* Y una cinta de luz inclinada, la misma idea que en el escudo grande pero
   entera: a este tamaño partirla en dos no se apreciaría. */
.pbc-fl-fx::after {
  width: 3.5rem;
  height: 3.5rem;
  margin: -1.75rem 0 0 -1.75rem;
  border: 1.5px solid var(--au-line);
  box-shadow: 0 0 5px var(--au-glow);
  transform: rotate(-22deg) scaleY(.34);
  animation: auBandPulse 2.4s ease-in-out infinite;
}

/* En los escalones de abajo (sin cinta todavía) se queda solo el resplandor. */
.pbc-fl-fx[data-aura="1"]::after { display: none; }

/* La corona de la burbuja: cuelga de la propia burbuja (que es position:relative
   y no recorta), justo encima del circulito. */
.cchat-msg.pbc-fl-crowned {
  /* El hueco de la corona en la lista apretada del chat: sin esto, la corona se
     comería la burbuja de arriba. */
  margin-top: 1rem;
}

.pbc-fl-crown-chat {
  position: absolute;
  left: -2.42rem;
  top: -.85rem;
  width: 1.8rem;
  height: .95rem;
  background: url("../img/podio/corona.fecb4da8c612.webp") center / contain no-repeat;
  font-size: 0;
  pointer-events: none;
  z-index: 4;
  filter: drop-shadow(0 1px 2px rgba(11, 20, 26, .35));
  animation: pbcFlairCrown 2.8s ease-in-out infinite;
}

/* ── El birrete del estudiante: YA NO EXISTE ────────────────────── */
/* Era una chapa dorada pegada al nombre con la palabra "Student" al lado. Se
   quedó sin sitio: en las filas de la liga le quitaba el hueco a los puntos y a
   las medallas, y en el perfil desalineaba los números. Guille lo cambió de
   sitio el 18/08/2026 por la noche: ahora es UNA MEDALLA MÁS, la primera de la
   vitrina del perfil, un poco más grande que el resto y con brillo, y al
   abrirla salen el dibujo y la palabra debajo. Vive en
   templates/includes/student_medal_tile.html + static/css/mobile-profile.css.
   Aquí no queda nada suyo: el oro (--flair-gold) sigue arriba, que lo usa el
   podio. */

/* ── Movimiento ───────────────────────────────────────────────────────────── */

@keyframes pbcFlairBreathe {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}


/* Los rayos del campeón: una vuelta lenta al revés que el aro partido. */

/* La onda que sale del círculo y se apaga. Empieza pegada a la cara y termina
   por fuera del marco; el resto del tiempo está apagada, así el efecto se nota
   como un latido y no como un adorno fijo. */
/* La franja de luz: entra por un lado, sale por el otro y descansa. */
/* El resplandor del chat: sube y baja, nunca se apaga del todo. */



/* El polvo de estrellas sube media capa (una pareja entera de chispas) y vuelve
   a empezar: como el dibujo de arriba y el de abajo son iguales, el salto no se
   ve. Despacio, que el aura tiene que sentirse solemne, no un chisporroteo. */


/* La vuelta completa de las estelas: 16 segundos, majestuosa. */

@keyframes pbcFlairName {
  to { background-position: -250% 0; }
}

/* La corona respira un poco, sin dar saltos: es lo que la hace ver "viva" al lado
   de una foto quieta. Solo sube y baja, porque ya va colocada con márgenes: si
   además llevara un desplazamiento lateral, se saldría de su sitio. */
@keyframes pbcFlairCrown {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9%); }
}

/* Quien pide menos movimiento NO ve nada moverse: ni giro, ni latido, ni corona
   flotando, ni nombre animado. El escudo y el dorado se quedan puestos y fijos,
   que es lo que dice quién ganó. */
@media (prefers-reduced-motion: reduce) {
  /* Quien pide menos movimiento se queda el aura QUIETA, no sin aura: las
     cintas y el resplandor siguen ahí, dejan de latir. Lo que sí desaparece son
     las piezas que solo tienen sentido moviéndose. */
  .pbc-flair[data-gm="1"]::before,
  .au-band,
  .au-glow,
  .au-flare,
  .pbc-flair-crown,
  .pbc-fl-crown-chat,
  .pbc-fl-fx::after,
  .pbc-fl-fx::before,
  .pbc-name-gold,
  .pbc-name-silver,
  .pbc-name-bronze {
    animation: none !important;
  }
  /* Una estrella en órbita parada es un punto pegado a la cara, y una chispa
     que no sube no es una chispa: fuera las dos. */
  .au-star,
  .au-spark { display: none; }
  .pbc-flair-crown,
  .pbc-fl-crown-chat { transform: none; }
  .au-flare { transform: translate(-50%, -50%); }
  .pbc-name-gold {
    background: none;
    -webkit-text-fill-color: #b8860b;
    color: #b8860b;
  }
  .pbc-name-silver {
    background: none;
    -webkit-text-fill-color: #3f5f7a;
    color: #3f5f7a;
  }
  .pbc-name-bronze {
    background: none;
    -webkit-text-fill-color: #8a5320;
    color: #8a5320;
  }
}
