/* Cadres d'avatar et titres équipés. Chargé par le SPA et par les gabarits
   Django : le même joueur doit se reconnaître d'une page à l'autre.

   Un cadre est une **image carrée** avec un creux au milieu. Elle se pose donc
   exactement sur la boîte de l'avatar, centrée et entière, et c'est l'avatar
   qui rétrécit pour venir s'asseoir dans le creux — l'inverse ferait déborder
   la photo par-dessus le dessin.

   Sans image téléversée, il reste l'anneau à la couleur de la rareté : il ne
   dit pas quel cadre on porte, mais il dit qu'on en porte un. */

.ud-avatar-cadre {
  position: relative;
  display: inline-block;
  flex-shrink: 0;
  line-height: 0;

  /* Part de la boîte occupée par la photo quand un cadre l'entoure. À ajuster
     d'ici si les illustrations de cadres ont un creux plus large ou plus
     étroit que prévu. */
  --ud-cadre-creux: 76%;
}

.ud-avatar-cadre-photo,
.ud-avatar-cadre > .profile-icon {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

/* L'anneau est un `box-shadow` et non une bordure : il n'entre pas dans la
   boîte, donc poser un cadre ne déplace pas ce qui suit. */
.ud-avatar-cadre[data-cadre]:not([data-cadre-image]) > .ud-avatar-cadre-photo,
.ud-avatar-cadre[data-cadre]:not([data-cadre-image]) > .profile-icon {
  box-shadow: 0 0 0 3px var(--ud-cadre, var(--ud-border-strong));
}

/* Avec une vraie illustration, l'anneau ferait doublon : c'est le dessin qui
   est le cadre. La photo se replie au centre pour tenir dans son creux. */
.ud-avatar-cadre[data-cadre-image] > .ud-avatar-cadre-photo,
.ud-avatar-cadre[data-cadre-image] > .profile-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--ud-cadre-creux);
  height: var(--ud-cadre-creux);
  transform: translate(-50%, -50%);
}

/* L'image du cadre couvre la boîte entière, sans la déborder : elle est carrée
   et `contain` la garde entière quelle que soit sa proportion réelle. */
.ud-avatar-cadre-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  pointer-events: none;
  object-fit: contain;
}

/* Dans un commentaire, l'avatar garde sa bordure discrète quand aucun cadre
   n'est équipé : sans elle, il flotte sur le fond de la bulle. */
.commentaire-avatar:not([data-cadre]) > .ud-avatar-cadre-photo {
  border: 1px solid var(--ud-border);
}

.ud-titre-equipe {
  font-weight: 700;
  /* La couleur du titre n'est jamais posée telle quelle : elle vient de la
     base, choisie sur fond sombre, et le thème clair la rendrait illisible —
     le défaut du modèle est le blanc, donc invisible sur blanc. L'ancrage la
     ramène vers la couleur du texte, juste assez pour qu'elle se lise. */
  color: color-mix(in oklab,
      var(--ud-titre, var(--ud-text-strong)) var(--ud-titre-ancrage),
      var(--ud-text-strong));
  overflow-wrap: anywhere;
}

@media (prefers-reduced-motion: no-preference) {
  /* Réservé aux légendaires, et seulement à l'anneau : une illustration de
     cadre a son propre dessin, le faire clignoter le trahirait. */
  .ud-avatar-cadre[data-cadre="LEGENDARY"]:not([data-cadre-image]) > .ud-avatar-cadre-photo,
  .ud-avatar-cadre[data-cadre="LEGENDARY"]:not([data-cadre-image]) > .profile-icon {
    animation: ud-cadre-legendaire 2.8s ease-in-out infinite;
  }

  /* Même règle pour les titres : seuls les légendaires respirent. Un épique et
     un rare se distinguent par ce qu'ils disent, pas par une animation. */
  .ud-titre-equipe[data-titre="LEGENDARY"] {
    animation: ud-titre-legendaire 3.2s ease-in-out infinite;
  }
}

@keyframes ud-cadre-legendaire {
  0%, 100% { box-shadow: 0 0 0 3px var(--ud-cadre), 0 0 0 3px transparent; }
  50% { box-shadow: 0 0 0 3px var(--ud-cadre), 0 0 10px 3px var(--ud-cadre); }
}

@keyframes ud-titre-legendaire {
  0%, 100% { text-shadow: none; }
  50% { text-shadow: 0 0 .5em color-mix(in oklab, currentColor 55%, transparent); }
}
