/* ==========================================================================
   GI-DATABASE.CSS
   Le catalogue de la base de donnees : grille de portraits a gauche, colonne
   de filtres a droite, tuile d'entite, etat vide.

   TOUT RESTE SOMBRE. Le panneau de filtres a ete essaye sur parchemin clair le
   2 aout 2026 : refuse. La regle de surface du site tient donc telle quelle,
   le parchemin est reserve au contenu redactionnel, et une grille de cent
   vingt-quatre portraits comme son panneau de filtres sont des instruments de
   navigation.

   LES DEUX ZONES SONT AUX MEMES PLACES QUE SUR LA FICHE. La grille occupe la
   zone ou la fiche met ses onglets, la colonne de filtres occupe la zone ou la
   fiche met son portrait et ses statistiques. Passer de la liste a une fiche ne
   deplace donc aucun bloc a l'ecran.

   CE QUI N'EST PAS ECRIT ICI. Aucun nom d'element, aucun libelle de filtre,
   aucun intitule de tri : ils viennent tous du fichier servi. Les couleurs de
   rarete et d'element ci-dessous sont le seul point en dur, et elles ont toutes
   une valeur de repli : une huitieme valeur d'element ou une rarete inconnue
   s'affiche en or et rien ne casse.
   ========================================================================== */

.gi-cat {
  --cat-tuile: 10.5rem;         /* largeur minimale d'une tuile */
  --cat-gap: var(--sp-4);
  --cat-aside: 33rem;           /* MOITIE PLUS LARGE depuis le 03/08/2026 :
                                   a 22 rem, les etiquettes tenaient deux par
                                   ligne et la recherche et le tri s'empilaient.
                                   A 33 rem elles tiennent a trois, et les deux
                                   commandes partagent une ligne : la colonne
                                   gagne quatre rangees de hauteur et la grille
                                   passe a cinq portraits par ligne. La fiche de
                                   personnage suit la meme mesure. */
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--cat-aside);
  gap: var(--sp-6) var(--sp-7);
  align-items: start;
}

/* UNE LISTE IMPOSEE N'A PAS DE COLONNE DE FILTRES, donc pas de grille a deux
   colonnes : ses lots s'empilent simplement sur toute la largeur. La classe est
   posee par `dessinerSections`, jamais par le gabarit. */
.gi-cat--lots { display: block; }

/* --------------------------------------------------------------------------
   Les couleurs de rarete, conventionnelles dans le jeu et reprises telles
   quelles : gris, vert, bleu, violet, or. Elles servent le fond des portraits
   et rien d'autre. Une rarete absente ou inconnue tombe sur --cat-r0.
   -------------------------------------------------------------------------- */
/* LE PANNEAU DE SURVOL EST DANS LE PANIER, ET C'EST UNE MESURE DU 4 AOUT 2026.
   Il vit sur `document.body`, hors du bloc `.gi-cat`, donc il n'heritait
   d'AUCUNE de ces variables. `var(--rar, var(--cat-r0))` ne resolvait rien,
   `color-mix()` recevait une couleur vide, et la declaration entiere tombait :
   `background-image` valait `none`. Les six icones de ressources d'un
   personnage etaient sur fond nu depuis le 3 aout, sans que rien ne le dise.
   Nommer les deux porteurs ici coute une ligne et repare les deux pages. */
.gi-cat,
.gi-cat-apercu {
  /* LES TEINTES DE RARETE, DONNEES LE 03/08/2026 ET A NE PAS RETOUCHER.
     Elles servent les personnages, et serviront les armes et les ressources.
     Sans etoile et une etoile partagent le gris. */
  --cat-r0: #7d8083;
  --cat-r1: #7d8083;
  --cat-r2: #599479;
  --cat-r3: #5985ab;
  --cat-r4: #926eb9;
  --cat-r5: #c57b24;
}

/* ==========================================================================
   C0. LE FOND
   --------------------------------------------------------------------------
   DE LA PROFONDEUR SANS UNE SEULE PARTICULE. Les poussieres animees ont ete
   essayees le 2 aout 2026 : trop presentes derriere cent vingt-quatre
   portraits, la ou elles fonctionnent bien derriere trois cartes d'article.
   La profondeur vient donc de quatre couches fixes, et elle ne coute aucune
   image ni aucun script.

     1. deux halos elementaires tres dilues, l'un froid en haut a gauche,
        l'autre chaud en bas a droite : ils donnent la couleur ;
     2. un voile vertical qui fonce vers le bas : il donne la direction ;
     3. un semis d'etoiles minuscules en degrades radiaux, fige : il donne la
        matiere, sans le scintillement qui fatigue ;
     4. le grain a deux frequences et le vignettage, poses par les classes
        utilitaires du site sur le bloc de page.
   ========================================================================== */

.gi-cat-fond {
  position: relative;
  isolation: isolate;
  background-color: var(--gi-ink-950);
  background-image:
    radial-gradient(58% 42% at 12% 4%, rgba(79, 166, 227, 0.10), transparent 68%),
    radial-gradient(52% 44% at 88% 92%, rgba(198, 165, 93, 0.09), transparent 70%),
    radial-gradient(90% 60% at 50% 0%, rgba(177, 137, 221, 0.055), transparent 72%),
    linear-gradient(180deg, var(--gi-ink-900) 0%, var(--gi-ink-950) 62%, #060B11 100%);
}
/* Le semis. Trois tailles de points a trois pas differents : le motif ne se
   repete visiblement qu'au bout de plusieurs ecrans. */
.gi-cat-fond::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.5;
  background-image:
    radial-gradient(1.4px 1.4px at 18% 22%, rgba(241, 233, 218, 0.30), transparent 100%),
    radial-gradient(1.1px 1.1px at 73% 11%, rgba(219, 192, 132, 0.26), transparent 100%),
    radial-gradient(1.6px 1.6px at 41% 67%, rgba(241, 233, 218, 0.22), transparent 100%),
    radial-gradient(1px 1px at 88% 44%, rgba(198, 165, 93, 0.28), transparent 100%),
    radial-gradient(1.2px 1.2px at 9% 81%, rgba(241, 233, 218, 0.18), transparent 100%),
    radial-gradient(1.3px 1.3px at 61% 91%, rgba(219, 192, 132, 0.20), transparent 100%);
  background-size: 340px 300px, 470px 410px, 610px 520px, 390px 350px, 520px 470px, 430px 380px;
}

/* ==========================================================================
   C1. LA COLONNE DE FILTRES
   ========================================================================== */

/* La colonne reprend la matiere des panneaux du site : grain leger, filet
   dore, et ornements aux angles. Sans eux elle se lisait comme un aplat pose
   sur la page plutot que comme un objet du meme monde que les cartes. */
.gi-cat__aside::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  border-radius: inherit;
  opacity: 0.1;
  mix-blend-mode: overlay;
  background-image: var(--gi-noise), var(--gi-noise);
  background-size: 168px 168px, 820px 820px;
}
.gi-cat__aside > * { position: relative; z-index: 1; }
.gi-cat__aside::-webkit-scrollbar { width: 9px; }
.gi-cat__aside::-webkit-scrollbar-track { background: rgba(8, 14, 20, 0.5); border-radius: 5px; }
.gi-cat__aside::-webkit-scrollbar-thumb {
  background: var(--gi-gold-600);
  border-radius: 5px;
  border: 2px solid var(--gi-ink-900);
}
.gi-cat__aside::-webkit-scrollbar-thumb:hover { background: var(--gi-gold-500); }
.gi-cat__aside::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  border-radius: inherit;
  background:
    linear-gradient(90deg, transparent 12%, var(--gi-line-strong) 50%, transparent 88%) top / 100% 1px no-repeat;
}

.gi-cat__aside {
  position: sticky;
  /* SOUS L'EN-TETE, PAS DERRIERE. La barre du site est elle-meme collante :
     avec `top: var(--sp-4)`, la colonne se calait a 17 px du haut de la
     fenetre, donc DERRIERE l'en-tete. `--gi-header-h` est mesuree par
     gi-ui.js a chaque chargement et a chaque changement de largeur ; le repli
     vaut la hauteur de la barre au repos. */
  top: calc(var(--gi-header-h, 74px) + var(--sp-3));
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  padding: var(--sp-5);
  background: linear-gradient(180deg, var(--gi-ink-850), var(--gi-ink-900));
  border: 1px solid var(--gi-line);
  border-radius: 4px;
  /* UN DEFILEMENT INTERIEUR, ET SEULEMENT QUAND IL FAUT.
     Le commentaire ci-dessous decrivait le choix inverse, tenu jusqu'au
     03/08/2026 : sur un ecran court, les derniers groupes passaient sous le
     bas de la fenetre et devenaient inatteignables, la colonne etant collante.
     `max-height` bornee a la fenetre plus `overflow-y: auto` rend la main.
     La barre horizontale parasite de l'ancienne tentative est evitee par
     `overflow-x: clip` : c'est le filet du bord haut qui debordait d'un pixel.
     Sur un ecran assez haut, rien ne change : la colonne tient et aucune barre
     n'apparait. */
  max-height: calc(100dvh - var(--gi-header-h, 74px) - var(--sp-6));
  overflow-y: auto;
  overflow-x: clip;
  /* LA BARRE DOIT SE VOIR QUAND ELLE SERT. `scrollbar-width: thin` seul laisse
     Chrome dessiner une barre par-dessus le contenu, quasi invisible sur un
     fond sombre : on la dessine. */
  scrollbar-width: thin;
  scrollbar-color: var(--gi-gold-600) rgba(8, 14, 20, 0.5);
  scrollbar-gutter: stable;

  /* Ancienne note, gardee pour memoire :
     PAS DE DEFILEMENT INTERIEUR. Une hauteur maximale plus `overflow: auto`
     faisait apparaitre deux barres, dont une horizontale de quelques pixels
     due au filet qui deborde d'un pixel. La colonne tient dans l'ecran une
     fois les groupes replies ; si un axe futur la rallonge, c'est la page qui
     defile, pas elle.

     ET LA LIGNE QUI L'APPLIQUAIT EST RESTEE, SOUS LE NOUVEAU REGLAGE.
     `overflow: visible` etait ecrit ICI, apres `overflow-y: auto`, et la
     forme courte remet LES DEUX axes a `visible` : le defilement interieur
     n'a donc jamais fonctionne, alors que la `max-height` au dessus, elle,
     s'appliquait. Resultat mesure le 3 aout 2026 sur la page servie : la
     colonne se coupait a la hauteur de la fenetre et les 35 dernieres puces
     se dessinaient DEHORS, hors de la boite et hors d'atteinte. Une note
     gardee pour memoire ne doit jamais rester en code. */
}

.gi-cat__titre {
  font-family: var(--gi-font-display);
  font-size: var(--fs-t-lg);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-caps-lg);
  color: var(--gi-sand-50);
  text-align: center;
}
.gi-cat__titre + .gi-cat__count { margin-top: calc(var(--sp-2) * -1); }

.gi-cat__field { position: relative; }
.gi-cat__field svg {
  position: absolute;
  inset-block: 0;
  left: 0.85rem;
  margin: auto;
  width: 16px; height: 16px;
  color: var(--gi-sand-500);
  pointer-events: none;
}
.gi-cat__input {
  width: 100%;
  padding: 0.62rem 0.9rem 0.62rem 2.4rem;
  font-family: var(--gi-font-body);
  font-size: var(--fs-base);
  color: var(--gi-text);
  background: var(--gi-ink-900);
  border: 1px solid var(--gi-line);
  border-radius: 3px;
  transition: border-color var(--t-fast);
}
.gi-cat__input::placeholder { color: var(--gi-sand-600); }
.gi-cat__input:hover { border-color: var(--gi-line-strong); }
.gi-cat__input:focus-visible { outline: none; border-color: var(--gi-gold-500); }

/* L'intitule « Trier par » reste dans le balisage pour les lecteurs d'ecran,
   mais il ne se voit plus : les libelles du menu se suffisent. */
.gi-cat__sr {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}
/* LA RECHERCHE ET LE TRI PARTAGENT UNE LIGNE. Empiles, ils prenaient deux
   rangees pour deux commandes qui se lisent d'un coup d'oeil. */
.gi-cat__commandes {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-3);
  align-items: end;
}
.gi-cat__sort { display: flex; flex-direction: column; gap: var(--sp-2); }
.gi-cat__sort > label,
.gi-cat-group__label {
  font-family: var(--gi-font-display);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  color: var(--gi-gold-400);
  line-height: 1.3;
}
.gi-cat__select {
  width: 100%;
  padding: 0.55rem 2rem 0.55rem 0.75rem;
  font-family: var(--gi-font-body);
  font-size: var(--fs-sm);
  color: var(--gi-text);
  background-color: var(--gi-ink-900);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%238A7D6A' stroke-width='1.6' d='M1 1.6 6 6.4l5-4.8'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.7rem center;
  background-size: 10px;
  border: 1px solid var(--gi-line);
  border-radius: 3px;
  appearance: none;
  cursor: pointer;
}
.gi-cat__select:hover,
.gi-cat__select:focus-visible { outline: none; border-color: var(--gi-gold-500); }
/* PLUS CLAIR : mesure du 03/08/2026, le libelle du tri et le texte du menu
   etaient en `--gi-sand-300` sur `--gi-ink-800`, soit du sombre sur du sombre.
   Les deux remontent d'un cran. */
.gi-cat__select, .gi-cat__input { color: var(--gi-sand-50); }
.gi-cat__input::placeholder { color: var(--gi-sand-400); }
.gi-cat__sort > label { color: var(--gi-gold-300); }

.gi-cat__count {
  font-size: var(--fs-sm);
  color: var(--gi-text-faint);
}
.gi-cat__count b {
  font-weight: 600;
  color: var(--gi-sand-200);
  font-variant-numeric: tabular-nums;
}

.gi-cat__reset {
  padding: 0.5rem 0.85rem;
  font-family: var(--gi-font-body);
  font-size: var(--fs-sm);
  color: var(--gi-sand-300);
  background: transparent;
  border: 1px solid var(--gi-line);
  border-radius: 3px;
  cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.gi-cat__reset:hover { color: var(--gi-gold-300); border-color: var(--gi-line-strong); }

/* --------------------------------------------------------------------------
   Un groupe par axe du vocabulaire, dans l'ordre ou le fichier les donne.
   L'intitule vient de vocabulary.<axe>.label et JAMAIS d'ici : le meme axe
   s'appelle « Region » sur les personnages et « Lieu de farm » sur les
   artefacts.
   -------------------------------------------------------------------------- */
.gi-cat__filters {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--gi-line);
}
/* Un bloc vide ne doit pas laisser sa gouttiere : le compteur et le bouton de
   remise a zero n'existent que quand un filtre est pose, et sans ceci ils
   laissaient deux espaces morts sous le dernier groupe. */
.gi-cat__aside > :empty { display: none; }

.gi-cat-group { display: flex; flex-direction: column; gap: var(--sp-2); }
/* UN CHEVRON, ET IL EST LA A TOUTES LES LARGEURS.
   Les groupes etaient repliables depuis le debut, mais rien ne le disait sur
   ordinateur : le chevron n'apparaissait que sous 1080 px. Un affordance qui
   ne se voit pas n'existe pas. */
.gi-cat-group__label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: 0.2rem 0;
  cursor: pointer;
  list-style: none;
}
.gi-cat-group__label::-webkit-details-marker { display: none; }
.gi-cat-group__label::after {
  content: "";
  width: 8px; height: 8px;
  flex: none;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  rotate: 45deg;
  translate: 0 -2px;
  transition: rotate var(--t-fast);
}
.gi-cat-group[open] > .gi-cat-group__label::after { rotate: -135deg; translate: 0 2px; }
/* TROIS PAR LIGNE, DE LARGEUR EGALE. En flex, chaque etiquette prenait la
   largeur de son texte : « Épée à deux mains » et « Arc » ne faisaient pas la
   meme, et chaque groupe dessinait un escalier different. En grille, toutes
   les etiquettes d'un groupe font exactement un tiers de ligne. */
.gi-cat-group__chips {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-2);
}

.gi-cat-chip {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  /* TROIS PAR LIGNE, DONC CHAQUE PIXEL DE MARGE EST UN CARACTERE DE MOINS.
     Mesure du 3 aout 2026 : « Mercredi / Samedi » demandait 123 px pour 116
     disponibles, et se coupait a sept pixels pres. La gouttiere et les cotes
     ont maigri d'autant : les libelles longs des autres axes y gagnent aussi,
     et ceux qui se coupent quand meme portent un `title`. */
  gap: 0.25rem;
  min-width: 0;
  padding: 0.34rem 0.45rem;
  text-align: left;
  font-family: var(--gi-font-body);
  font-size: var(--fs-sm);
  color: var(--gi-sand-300);
  background: var(--gi-ink-800);
  border: 1px solid var(--gi-line-soft);
  border-radius: 999px;
  cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast);
}
/* Le libelle occupe la place restante et se coupe proprement ; le compteur
   reste colle a droite et ne bouge pas d'une etiquette a l'autre. */
.gi-cat-chip > .gi-cat-chip__t {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gi-cat-chip:hover { color: var(--gi-sand-100); border-color: var(--gi-line-strong); }
.gi-cat-chip:focus-visible { outline: 2px solid var(--gi-gold-500); outline-offset: 2px; }
.gi-cat-chip__n {
  margin-left: auto;
  font-size: var(--fs-xs);
  color: var(--gi-sand-600);
  font-variant-numeric: tabular-nums;
}
.gi-cat-chip[aria-pressed="true"] {
  color: var(--gi-ink-900);
  background: var(--gi-gold-400);
  border-color: var(--gi-gold-300);
  font-weight: 600;
}
.gi-cat-chip[aria-pressed="true"] .gi-cat-chip__n { color: rgba(13, 22, 32, 0.62); }

/* ==========================================================================
   C2. LES SYMBOLES
   --------------------------------------------------------------------------
   UN SYMBOLE VIENT DE LA DONNEE, PAS D'ICI. Le versement peut donner une image
   a chaque valeur de vocabulaire, sous la cle `icon`. Quand elle existe, le
   script pose une image ; quand elle manque, il pose la pastille de couleur
   ci-dessous. Les deux portent la meme classe, se placent au meme endroit, et
   passer de l'une a l'autre ne demande aucune modification de cette feuille.
   ========================================================================== */

.gi-sym {
  width: 1.15em;
  height: 1.15em;
  flex: none;
  object-fit: contain;
  border-radius: 50%;
}
/* LE SYMBOLE PEINT. L'icone sert de MASQUE et la couleur vient de `--chip`,
   que `data-v` pose. C'est ainsi que les sept elements cessent de se
   ressembler. `--ico` est ecrite par le script, jamais ici. */
/* NEUTRE PAR DEFAUT, COLORE SEULEMENT QUAND UNE TEINTE EXISTE. `--chip` n'est
   posee que par `[data-v]` des sept elements : partout ailleurs le symbole
   reste clair, et c'est ce qui fait ressortir l'element. */
.gi-sym--peint {
  background: var(--chip, var(--gi-sand-100));
  -webkit-mask: var(--ico) center / contain no-repeat;
          mask: var(--ico) center / contain no-repeat;
  border-radius: 0;
}
.gi-cat-chip[aria-pressed="true"] .gi-sym--peint { background: var(--gi-ink-900); }
/* PLUS DE ROND CREUX DANS UNE ETIQUETTE DE FILTRE.
   Il tenait la place d'une icone a venir, mais sur l'axe des regions, le seul
   concerne, il n'y en aura peut-etre jamais : sept ronds vides alignes ne
   disaient rien et volaient la place du libelle. Il reste dans la COLONNE de
   la tuile, ou il annonce vraiment un symbole manquant. */
.gi-cat-chip .gi-sym--creux { display: none; }
.gi-sym--creux {
  width: 0.72em;
  height: 0.72em;
  box-shadow: inset 0 0 0 1px var(--gi-sand-600);
}
.gi-cat-chip[aria-pressed="true"] .gi-sym--creux { box-shadow: inset 0 0 0 1px rgba(13, 22, 32, 0.45); }

/* La forme de repli : une pastille pleine, teintee par --chip. Quand aucune
   couleur n'est connue pour la valeur, --chip-on vaut zero et la pastille
   prend une largeur nulle : elle disparait au lieu de poser un point dore
   qui ne veut rien dire devant « Arme d'hast ». */
.gi-sym--point {
  width: calc(0.62em * var(--chip-on, 0));
  height: 0.62em;
  background: var(--chip, transparent);
}
.gi-cat-chip[aria-pressed="true"] .gi-sym--point { box-shadow: 0 0 0 1px rgba(13, 22, 32, 0.35); }

/* Les sept elements de Teyvat. Une huitieme valeur tombe sur l'or de repli
   declare dans .gi-sym--point, et la barre reste lisible. */
[data-v="anemo"]   { --chip: var(--el-anemo);   --chip-on: 1; --fx: var(--el-anemo); }
[data-v="geo"]     { --chip: var(--el-geo);     --chip-on: 1; --fx: var(--el-geo); }
[data-v="electro"] { --chip: var(--el-electro); --chip-on: 1; --fx: var(--el-electro); }
[data-v="dendro"]  { --chip: var(--el-dendro);  --chip-on: 1; --fx: var(--el-dendro); }
[data-v="hydro"]   { --chip: var(--el-hydro);   --chip-on: 1; --fx: var(--el-hydro); }
[data-v="pyro"]    { --chip: var(--el-pyro);    --chip-on: 1; --fx: var(--el-pyro); }
[data-v="cryo"]    { --chip: var(--el-cryo);    --chip-on: 1; --fx: var(--el-cryo); }

/* L'etoile du jeu, reprise du jeton --gi-star : quatre branches effilees.
   Elle sert la rarete partout, en puce de filtre comme sur un portrait. */
.gi-etoile {
  width: 1em;
  height: 1em;
  flex: none;
  background: var(--et, var(--gi-gold-400));
  -webkit-mask: var(--gi-star) center / contain no-repeat;
          mask: var(--gi-star) center / contain no-repeat;
}
.gi-cat-chip[aria-pressed="true"] .gi-etoile { --et: var(--gi-ink-900); }

/* ==========================================================================
   C3. LA GRILLE ET LA TUILE
   ========================================================================== */

/* SIX COLONNES, ET C'EST UN NOMBRE, PAS UNE LARGEUR MINIMALE.
   En `auto-fill`, la grille rendait cinq ou sept colonnes selon l'ecran et la
   tuile changeait de taille a chaque palier. Un nombre fixe par palier garde
   des rangees pleines et une tuile qui suit la largeur disponible. */
.gi-cat__grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--cat-gap);
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Le <li> est l'hote du nuage de particules : il doit pouvoir le laisser
   deborder, sinon les etincelles sont coupees au ras de la tuile. */
.gi-cat__grid > li {
  min-width: 0;
  display: flex;
  position: relative;
}

.gi-cat-card {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  width: 100%;
  overflow: hidden;
  text-decoration: none;
  background: var(--gi-ink-850);
  border: 1px solid var(--gi-line-soft);
  border-radius: 4px;
  /* AU REPOS AUSSI, LA TUILE SE DETACHE. Trois couches, et aucune n'est un
     effet de survol : une ombre portee large et tres douce qui creuse le fond
     sous la tuile, une ombre courte qui la pose, et un liseré interieur clair
     sur le bord haut, qui simule la lumiere rasante et donne l'epaisseur. Sans
     elles, cent vingt-quatre rectangles sombres flottaient sur un fond sombre
     et la grille n'avait de relief qu'au passage du curseur. */
  box-shadow:
    0 14px 30px -18px rgba(0, 0, 0, 0.85),
    0 3px 8px -4px rgba(0, 0, 0, 0.55),
    inset 0 1px 0 rgba(241, 233, 218, 0.07);
  transition: border-color var(--t-base) var(--ease-out),
              translate var(--t-base) var(--ease-out),
              box-shadow var(--t-base) var(--ease-out);
}
/* LE MOUVEMENT NE DOIT PLUS DEPENDRE DU LIEN, IL DOIT DEPENDRE DE LA PAGE.
   Regle du 3 aout : une tuile sans lien ne bouge pas, pour ne pas ressembler
   a un lien qui ne marche pas. Elle valait quand UNE tuile sur 124 etait sans
   lien. La page des armes en compte 237 sur 237, la categorie n'etant pas
   ouverte : la grille entiere etait figee, et c'est ca qui se lisait comme une
   panne. `.gi-cat--sans-lien` est posee par le script quand le fichier servi
   dit `published: false`, donc quand AUCUNE tuile ne cliquera. Une tuile qui
   bouge ne peut alors se confondre avec rien. Sur une page ou les liens
   existent, la tuile muette reste immobile, et le signal tient. */
a.gi-cat-card:hover,
a.gi-cat-card:focus-visible,
.gi-cat--sans-lien .gi-cat-card:hover {
  border-color: var(--gi-line-strong);
  translate: 0 -3px;
  box-shadow:
    0 22px 42px -18px rgba(0, 0, 0, 0.9),
    0 6px 14px -6px rgba(0, 0, 0, 0.6),
    inset 0 1px 0 rgba(241, 233, 218, 0.12);
}
a.gi-cat-card:focus-visible { outline: 2px solid var(--gi-gold-500); outline-offset: 2px; }
/* Une tuile sans lien reste une tuile : meme dessin, sans le mouvement. Elle
   ne doit surtout pas ressembler a un lien qui ne marche pas. */
.gi-cat-card--muet { cursor: default; }

/* Le fond suit la rarete, et c'est la premiere information que l'oeil prend
   sur une grille de cent vingt-quatre portraits. */
/* LE GRAIN TEXTURE LE FOND, PAS LE PERSONNAGE.
   Pose PAR-DESSUS l'image en `mix-blend-mode: overlay`, il assombrissait les
   demi-teintes du portrait : c'est de la qu'ils paraissaient tous ternes. Il
   passe donc SOUS l'image, avec le filigrane, et le personnage se rend tel
   qu'il est verse. */
.gi-cat-card__portrait::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.22;
  mix-blend-mode: overlay;
  background-image: var(--gi-noise), var(--gi-noise);
  background-size: 158px 158px, 780px 780px;
}
/* PLUS DE VIGNETTAGE. Il reste une ombre BASSE, tres douce, qui pose le
   personnage sur son fond sans toucher aux bords ni a la couleur.

   ET LE LOGO DE L'ELEMENT, EN GRAND ET PRESQUE NOIR, EN FILIGRANE. Il donne au
   fond une texture qui lui manquait sans ajouter une couleur de plus : c'est
   une ombre, pas un dessin. `--elem-ico` est posee par le script sur la tuile
   quand l'element a une icone ; absente, la regle ne peint rien. */
.gi-cat-card__portrait::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg, transparent 62%, rgba(6, 11, 18, 0.28) 100%);
}
.gi-cat-card__portrait > .gi-cat-card__fili {
  position: absolute;
  inset: -12% -12% auto -12%;
  aspect-ratio: 1;
  z-index: 0;
  pointer-events: none;
  opacity: 0.13;
  background: #05090f;
  -webkit-mask: var(--gi-fili) center / contain no-repeat;
          mask: var(--gi-fili) center / contain no-repeat;
}
.gi-cat-card__portrait {
  position: relative;
  isolation: isolate;
  aspect-ratio: 1;
  overflow: hidden;
  /* LE FOND DE RARETE, ET C'EST LA RECETTE DE TOUT LE SITE.
     Elle sert la grille, les emplacements d'equipe, et servira les armes et
     les ressources : partout ou l'on pose l'icone d'une entite, on pose ce
     fond-la, a la couleur de SA rarete.

     UN DEGRADE, PLUS UN VIGNETTAGE. Le vignettage a ete essaye deux fois et
     refuse les deux fois : il assombrit les bords, donc il mange la couleur
     par les quatre cotes, et c'est justement la couleur qu'on veut lire. Un
     simple degrade vertical, le haut un peu plus sombre, donne le relief sans
     rien reprendre. Le grain fait le reste. */
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--rar, var(--cat-r0)) 78%, #060b12) 0%,
      var(--rar, var(--cat-r0)) 62%,
      color-mix(in srgb, var(--rar, var(--cat-r0)) 88%, #f1e9da) 100%);
}
.gi-cat-card[data-r="1"] { --rar: var(--cat-r1); }
.gi-cat-card[data-r="2"] { --rar: var(--cat-r2); }
.gi-cat-card[data-r="3"] { --rar: var(--cat-r3); }
.gi-cat-card[data-r="4"] { --rar: var(--cat-r4); }
.gi-cat-card[data-r="5"] { --rar: var(--cat-r5); }

/* Deux portraits sur cent vingt-quatre ne sont pas carres : `contain` les
   laisse entiers au lieu de les rogner, et les dimensions ecrites dans le
   balisage evitent que la grille saute a chaque image chargee. */
.gi-cat-card__portrait img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
  display: block;
  transition: scale var(--t-slow) var(--ease-out);
}
a.gi-cat-card:hover .gi-cat-card__portrait img,
.gi-cat--sans-lien .gi-cat-card:hover .gi-cat-card__portrait img { scale: 1.06; }

/* UNE ICONE D'OBJET N'EST PAS UN PORTRAIT, MAIS ELLE NE S'AGRANDIT PAS POUR
   AUTANT. Un agrandissement permanent a ete essaye le 4 aout 2026 pour que
   l'icone d'arme remplisse sa tuile comme un portrait : refuse. Il donnait a
   toute la grille l'air d'etre deja survolee, et il ne restait plus rien a
   gagner au passage du curseur. Le repos doit etre le repos.

   Ce que le cadrage « objet » garde, c'est le CENTRAGE. Les portraits sont
   cadres pour etre cales en bas ; une icone d'arme, elle, flotte au milieu de
   sa reserve transparente, et calee en bas elle pend sous son cadre. */
.gi-cat--objet .gi-cat-card__portrait img { object-position: center; }

/* La colonne de symboles, contre le bord gauche du portrait : arme, statistique
   d'elevation, element. Elle ne contient que ce qui existe. */
.gi-cat-card__ico {
  position: absolute;
  /* MEME ECART EN HAUT ET A GAUCHE, ET IL SE MESURE SUR LE SYMBOLE.
     La pastille est un rond plus large que le symbole qu'elle porte : a
     `inset` egal, l'oeil comparait le haut du ROND au bord haut de l'image, et
     la gauche du SYMBOLE au bord gauche. D'ou le decalage vers la droite qui
     se voyait. On rentre donc la colonne de la moitie de cet ecart. */
  inset: 0.3rem auto auto 0.3rem;
  display: flex;
  flex-direction: column;
  /* CALEE A GAUCHE, ET C'ETAIT TOUT LE PROBLEME. La colonne est plus large que
     ses pastilles, et un `align-items` centre les poussait de quatorze pixels
     vers la droite : mesure du 03/08/2026, la colonne commencait a 4,8 px du
     bord mais la premiere pastille a 18,8. L'ecart du haut, lui, etait juste,
     d'ou l'impression d'un decalage a droite seulement. */
  align-items: flex-start;
  width: fit-content;
  gap: 0.28rem;
  margin: 0;
  padding: 0;
  list-style: none;
  z-index: 2;
}
/* ET IL FAUT ALLER CHERCHER LE PERSONNALISATEUR DE DIVI, DEUXIEME FOIS.
   Mesure du 03/08/2026 : la colonne portait un `padding-left: 14px` que
   `padding: 0` ne battait pas. Divi emet `.et-db #et-boc .et-l ul` avec son
   IDENTIFIANT `#et-boc`, qui bat toute regle a simple classe. C'est le meme
   defaut que l'en-tete a 184 px, et il vaut pour TOUTE liste que nous posons
   dans le contenu Divi. Ne pas passer par `!important` : se hisser d'une
   classe au dessus suffit. */
.et-db #et-boc .et-l ul.gi-cat-card__ico,
ul.gi-cat-card__ico.gi-cat-card__ico { padding: 0; margin: 0; }
.et-db #et-boc .et-l ul.gi-fiche-ids,
ul.gi-fiche-ids.gi-fiche-ids { padding: 0; }
.et-db #et-boc .et-l ul.gi-cat__grid,
ul.gi-cat__grid.gi-cat__grid { padding: 0; }

.gi-cat-card__ico li {
  display: grid;
  place-items: center;
  width: 1.65rem;
  height: 1.65rem;
  font-size: 0.9rem;
  background: rgba(8, 14, 20, 0.6);
  border: 1px solid color-mix(in srgb, var(--chip, var(--gi-gold-600)) 42%, transparent);
  border-radius: 50%;
  backdrop-filter: blur(3px);
}
/* LE LOGO D'ELEMENT PREND LA COULEUR DE SON ELEMENT.
   L'image versee est blanche sur fond transparent : posee telle quelle, les
   sept elements se ressemblaient tous. En MASQUE, elle prend `--chip`, que
   `[data-v]` pose deja. Le type d'arme, lui, garde son image : elle porte un
   cartouche decoratif qu'un masque effacerait. */
.gi-cat-card__ico li[data-v] .gi-sym {
  background: var(--chip, var(--gi-gold-400));
  -webkit-mask: var(--ico) center / contain no-repeat;
          mask: var(--ico) center / contain no-repeat;
  border-radius: 0;
}
.gi-cat-card__ico li[data-v] img.gi-sym { background: var(--chip, var(--gi-gold-400)); }

/* UN EMPLACEMENT PLUTOT QU'UN TROU. Tant que le versement ne porte pas
   d'icone, un axe sans couleur garde son rond, avec un point sourd dedans :
   la colonne montre des le premier jour combien de symboles elle recevra, et
   la tuile ne changera pas de hauteur quand ils arriveront. */
.gi-cat-card__ico li:not(:has(img)):not([data-v])::after {
  content: "";
  width: 0.42rem;
  height: 0.42rem;
  border-radius: 50%;
  background: var(--gi-sand-600);
}
/* L'emplacement d'un axe que le versement ne porte pas encore du tout. */
.gi-cat-card__ico li[data-attente]::after { background: transparent; box-shadow: inset 0 0 0 1px var(--gi-sand-600); }

.gi-cat-card__rank {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  display: flex;
  justify-content: center;
  gap: 1px;
  padding: 1.2rem 0 0.35rem;
  background: linear-gradient(180deg, transparent, rgba(8, 14, 20, 0.8));
}
/* Grandes, parce que c'est ce qu'on lit en premier sur une grille. */
.gi-cat-card__rank .gi-etoile { width: 1.2rem; height: 1.2rem; }

/* LE PIED FAIT TOUJOURS DEUX LIGNES.
   Le parchemin y a ete essaye le 2 aout 2026 : refuse, le sombre tenait mieux.
   Ne pas le represser.

   LA HAUTEUR N'EST PAS RESERVEE, ELLE EST PARTAGEE PAR RANGEE.
   Mesure du 2 aout 2026 : « Uumemizuki Mizuki » passait a la ligne et faisait
   grandir la rangee entiere, donc Citlali, Lan Yan et Mavuika avec elle. Le
   premier remede, deux lignes reservees partout, corrigeait le decalage mais
   grossissait AUSSI les rangees qui n'ont que des noms courts.

   Le bon remede tient en une ligne : `flex: 1` sur le pied. La grille etire
   deja toutes les tuiles d'une meme rangee a la meme hauteur ; c'est le pied
   qui absorbe cet etirement, au lieu de le laisser au portrait. Une rangee
   sans nom long garde donc un pied d'une seule ligne, et seule la rangee qui
   porte un nom long grandit. Au-dela de deux lignes, on coupe. */
.gi-cat-card__name {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  /* PADDING SYMETRIQUE ET LIGNE NORMALISEE. Le pied grandit pour egaliser la
     rangee, et le texte doit rester au milieu de ce qu'il devient : sans
     `min-height` ni `line-height` fixe, la boite a deux lignes laissait un
     blanc en bas sur les noms courts. */
  min-height: 3.4rem;
  padding: var(--sp-2) var(--sp-3);
  font-family: var(--gi-font-title);
  font-size: var(--fs-t-sm);
  font-weight: 600;
  letter-spacing: -0.014em;
  line-height: var(--lh-snug);
  text-align: center;
  text-wrap: balance;
  color: var(--gi-sand-50);
  /* LE BLEU DES PANNEAUX, PAS L'ENCRE. Sous un fond de rarete franc, un pied
     presque noir faisait un trou. Il prend donc la matiere de la colonne de
     filtres : le meme degrade, le meme grain, et un vignettage doux qui le
     recentre. */
  background: linear-gradient(180deg, var(--gi-ink-800), var(--gi-ink-850));
  border-top: 1px solid var(--gi-line);
  overflow: hidden;
  isolation: isolate;
}
.gi-cat-card__name::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0.12;
  mix-blend-mode: overlay;
  background-image: var(--gi-noise), var(--gi-noise);
  background-size: 128px 128px, 620px 620px;
}
.gi-cat-card__name::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(120% 160% at 50% 0%, transparent 34%, rgba(6, 11, 18, 0.42) 100%);
}
.gi-cat-card__name > span {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
a.gi-cat-card:hover .gi-cat-card__name,
.gi-cat--sans-lien .gi-cat-card:hover .gi-cat-card__name { color: var(--gi-gold-300); }

/* ==========================================================================
   C3 bis. LES ETINCELLES DU SURVOL
   --------------------------------------------------------------------------
   La tuile emprunte le nuage de particules de gi-hover.js, dans la teinte de
   son element. Deux reglages sont necessaires, et tous deux ont ete trouves en
   regardant l'ecran.

   PAS DE LAMPE. `.gi-card--hover` apporte AUSSI la lueur qui suit le curseur,
   dessinee par un degrade elliptique en fond de carte. Sur une tuile de
   portrait elle se lit comme une tache ovale etiree, et non comme une lampe :
   on la coupe et on ne garde que les etincelles.

   LE NUAGE PASSE DERRIERE LES TUILES VOISINES. La feuille de jetons ne
   remonte que `.gi-card`, or nos tuiles s'appellent `.gi-cat-card` : sans les
   deux regles ci-dessous, le canvas d'une tuile se dessine PAR-DESSUS ses
   voisines. C'est le porteur qui monte au survol, pas la tuile, pour que le
   nuage puisse deborder au-dessus des rangees du dessus.
   ========================================================================== */

/* `!important` parce que gi-hover.js ecrit --lamp en style en ligne sur la
   carte : sans lui, la lueur revient au premier survol. */
/* LE NUAGE PASSE DERRIERE TOUTES LES TUILES, PAS SEULEMENT LES VOISINES.
   Aucun z-index sur le porteur : s'il en portait un, il ouvrirait son propre
   contexte d'empilement et son canvas ne pourrait plus passer sous les tuiles
   des autres porteurs. Sans lui, canvas et tuiles s'empilent tous dans le meme
   contexte, celui de la grille, et le 1 des tuiles bat le 0 des canvas
   quelle que soit leur place dans la page. */
.gi-cat-card.gi-card--hover { --lamp: 0 !important; }

/* PAS DE SOULEVEMENT GENERIQUE NON PLUS, ET C'EST LE DEFAUT DU 3 AOUT 2026.
   `.gi-card--hover:hover` pose `transform: translateY(-7px)`. La tuile de
   grille, elle, a son propre soulevement, plus discret, ecrit en `translate:
   0 -3px`, et sa liste de transitions ne nomme QUE `border-color`, `translate`
   et `box-shadow`.

   `transform` et `translate` sont deux proprietes differentes : les sept pixels
   du soulevement generique n'etaient donc jamais fondus. Mesure sur la page
   servie : au survol, `transform` valait `matrix(1, 0, 0, 1, 0, -7)` alors que
   `transition-property` ne le contenait pas. La tuile sautait a l'entree et
   RETOMBAIT D'UN COUP a la sortie, pendant que l'ombre et la bordure, elles,
   fondaient tranquillement : c'est cette rupture qu'on lisait comme un
   assombrissement sec.

   On coupe le soulevement generique plutot que d'ajouter `transform` a la
   liste : la tuile en aurait eu deux, sept pixels plus trois, alors qu'un seul
   a ete dessine. Meme parti pris que la lampe, juste au-dessus.

   L'hypothese ecrite dans la passation, un fondu de `--lamp` qui vivrait sur
   `.gi-card`, est ECARTEE : la ligne ci-dessus eteint la lampe sur ces tuiles,
   elle ne s'allume jamais et ne peut donc rien assombrir. */
.gi-cat-card.gi-card--hover:hover { transform: none; }

/* LES DEUX BOUTS D'UNE TRANSITION DOIVENT ETRE DES NOMBRES, JAMAIS UN
   MOT-CLE, ET C'EST LE DEFAUT QUE L'UTILISATEUR VOYAIT ENCORE.

   Ce qu'il decrivait comme une saturation qui monte puis retombe d'un coup
   n'est pas une saturation : c'est le PORTRAIT QUI ZOOME DE 6 %. Mesure du
   3 aout, en comparant les pixels d'une tuile au repos et survolee — le
   meilleur accord tombe exactement sur un agrandissement de 1,06, et l'ecart
   de teinte est nul. Le personnage grandit, il couvre davantage le fond
   colore, et la tuile se lit comme plus riche.

   Pourquoi la montee fondait et la descente non. Au repos, ni `scale` ni
   `translate` n'etaient DECLARES : leur valeur calculee valait le mot-cle
   `none`. Au survol elles valent `1.06` et `0 -3px`. Interpoler de `none`
   vers un nombre marche partout, parce que `none` se lit comme l'identite ;
   interpoler d'un nombre VERS `none` est le cas fragile, et c'est celui de la
   sortie. L'utilisateur est sous Firefox, ou il se voit.

   Les deux lignes ci-dessous ne changent rien a l'oeil : elles ecrivent
   l'identite a la place du mot-cle, et les deux bouts de chaque transition
   deviennent des nombres. `.gi-card--hover::after` declarait deja son
   `scale: 0 1` au repos — c'est le meme reflexe, il manquait ici. */
.gi-cat-card { translate: 0 0; }
.gi-cat-card__portrait img { scale: 1; }

/* LE CANVAS DEBORDE LA TUILE, IL NE DOIT PAS ETRE BORNE PAR ELLE. La feuille
   de jetons pose `max-width: 100%` sur tout canvas. Mesure du 2 aout 2026 :
   le nuage demandait 317 px de large, la regle le ramenait a 193 alors que sa
   surface de dessin en faisait toujours 317. Les etincelles etaient donc
   ECRASEES d'un facteur 1,64 a l'horizontale, et rondes a la verticale : d'ou
   les ovales. */
.gi-cat__grid .gi-fx { max-width: none; }
.gi-cat__grid > li > .gi-cat-card { position: relative; z-index: 1; }
.gi-cat__grid .gi-fx { z-index: 0; }

/* ==========================================================================
   C4. LE RESUME AU SURVOL
   --------------------------------------------------------------------------
   Un panneau unique, deplace d'une tuile a l'autre : cent vingt-quatre
   panneaux poses d'avance couteraient cent vingt-quatre fois leur balisage
   pour un seul visible a la fois.
   ========================================================================== */

.gi-cat-apercu {
  position: fixed;
  z-index: 60;
  width: 17rem;
  padding: var(--sp-4);
  background: linear-gradient(180deg, var(--gi-ink-800), var(--gi-ink-900));
  border: 1px solid var(--gi-line-strong);
  border-radius: 4px;
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.9);
  pointer-events: none;
  opacity: 0;
  translate: 0 6px;
  transition: opacity var(--t-fast), translate var(--t-fast);
}
.gi-cat-apercu[data-ouvert="1"] { opacity: 1; translate: 0; }
/* PLUS LARGE QUAND IL PORTE UN PASSIF. 17 rem suffisent a un nom, deux
   libelles et six icones ; un texte de deux cent soixante-douze signes y
   descendrait sur une quinzaine de lignes. La classe est posee par le script
   quand la page declare un fichier de passifs, jamais devinee du contenu. */
.gi-cat-apercu--large { width: 21rem; }
.gi-cat-apercu__tete { display: flex; align-items: center; gap: var(--sp-3); }
.gi-cat-apercu__tete > div { min-width: 0; }
/* NOM ET ETOILES COLLES, ET LE COUPLE CENTRE SUR L'IMAGE. Ils se lisent
   ensemble ; cales en bas, ils pendaient sous la vignette. */
.gi-cat-apercu__tete { align-items: center; }
.gi-cat-apercu__img {
  width: 3.4rem; height: 3.4rem;
  flex: none;
  object-fit: contain;
  background: linear-gradient(180deg, var(--gi-ink-750), var(--gi-ink-850));
  border: 1px solid var(--gi-line-soft);
  border-radius: 3px;
}
/* LE NOM DESCEND SE COLLER AUX ETOILES : elles se lisent ensemble, et le
   sous-titre qui s'intercalait separait deux informations qui n'en font
   qu'une. */
/* LE PANNEAU EST POSE SUR `body`, ET DIVI Y ARRIVE QUAND MEME.
   Mesure du 3 aout 2026 : le nom tenait sur 42 px pour une ligne de 23,8 px.
   Les 18 px de trop etaient le `padding-bottom: 1em` que Divi pose sur TOUT
   `p` de la page, panneau compris. Le nom flottait donc a 22 px de ses
   etoiles, alors que la feuille n'en demandait que 4. Deux paragraphes du
   panneau se defendaient deja, un par un ; la regle vaut pour tous, et pour
   ceux qu'on ajoutera. Une seule classe suffit a battre un `p` nu — pas
   besoin de `!important`, ni de se hisser au rang de `#et-boc` : le panneau
   vit hors du contenu Divi. */
.gi-cat-apercu p { padding-bottom: 0; }

.gi-cat-apercu__tete > div { display: flex; flex-direction: column; justify-content: center; gap: 0.1rem; }
.gi-cat-apercu__et { display: flex; gap: 1px; margin-top: 0.15rem; }
.gi-cat-apercu__et .gi-etoile { width: 0.8rem; height: 0.8rem; }
.gi-cat-apercu__t {
  font-family: var(--gi-font-title);
  font-size: var(--fs-t-sm);
  font-weight: 600;
  color: var(--gi-sand-50);
}
.gi-cat-apercu__sub {
  margin-top: 0.15rem;
  font-size: var(--fs-xs);
  font-style: italic;
  color: var(--gi-gold-300);
}
/* UNE LIGNE PAR AXE PAR DEFAUT. En rangee qui passe a la ligne, l'element et
   l'arme se retrouvaient parfois cote a cote et parfois non, selon la longueur
   des libelles : le panneau changeait de hauteur d'une tuile a l'autre.

   UNE GRILLE, ET PAS UNE RANGEE QUI S'AJUSTE, quand la page en demande deux.
   C'est la meme raison, prise par l'autre bout : a nombre de colonnes fixe,
   la deuxieme colonne commence au meme pixel sur toutes les tuiles, quelle que
   soit la longueur du premier libelle. Les armes en demandent deux, les
   personnages en gardent une. */
.gi-cat-apercu__l {
  display: grid;
  grid-template-columns: repeat(var(--gi-apercu-cols, 1), minmax(0, 1fr));
  justify-items: start;
  gap: 0.3rem var(--sp-3);
  margin-top: var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--gi-sand-300);
}
.gi-cat-apercu__l span { display: inline-flex; align-items: center; gap: 0.32rem; min-width: 0; }
/* Un libelle long ne pousse pas sa colonne, il passe a la ligne dans la
   sienne : « Maitrise elementaire » deborde sinon la moitie du panneau. */
.gi-cat-apercu__l span { flex-wrap: wrap; }

/* LE PASSIF DE L'ARME.
   Il vient du versement sous forme de gabarit a trous, deja echappe, et ne
   porte que les huit classes de couleur ci-dessous. Mesure du 4 aout 2026 sur
   les 227 armes qui en ont un : 44 signes pour la plus courte, 272 pour la
   mediane, 1 155 pour « Les chroniques de l'aube ». C'est cet ecart de un a
   vingt-six qui commande le plafond : sans lui, le panneau ferait la hauteur
   de l'ecran sur une arme et trois lignes sur la suivante. */
.gi-cat-apercu__passif {
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--gi-line-soft);
  font-size: var(--fs-xs);
  line-height: 1.45;
  color: var(--gi-sand-200);
  /* QUATORZE LIGNES, ET LE NOMBRE EST MESURE. Rendus dans ce panneau le
     4 aout 2026, les 227 passifs font 33 px pour le plus court, 127 px de
     mediane, 465 px pour le plus long — « Les chroniques de l'aube ». Sans
     plafond, le panneau montait a 699 px : il tient sur un grand ecran et se
     fait couper en bas sur un portable. A quatorze lignes il plafonne vers
     500 px et 15 passifs sur 227 sont tronques, 6,6 %. La coupure tombe sur
     une fin de ligne et pose des points de suspension : on voit qu'il en reste,
     et la fiche de l'arme portera le texte entier. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 14;
  line-clamp: 14;
  overflow: hidden;
}

/* LES TEXTES DECLARES, ET POURQUOI CE N'EST PAS UN PASSIF.
   Un passif d'arme est UN texte : une seule regle suffit. Un set d'artefacts
   en porte deux, parfois un, et il faut dire lequel est lequel — « 2 pieces »
   et « 4 pieces » ne se devinent pas de l'ordre de lecture. D'ou l'etiquette,
   et d'ou le bloc qui les tient ensemble : un seul filet au-dessus, pas un
   par paragraphe. Trois filets pour deux effets couperaient l'infobulle en
   tranches.

   LE PLAFOND EST PAR PARAGRAPHE, ET IL EST MESURE. Sur les 118 bonus servis
   le 5 aout 2026, le plus long fait 994 signes — Palourde aux teintes
   oceaniques — pour une mediane bien plus basse. Dans les 21 rem du panneau
   large, 994 signes descendent sur une vingtaine de lignes, et deux effets
   pareils feraient un panneau plus haut que l'ecran. Dix lignes chacun
   plafonnent le couple vers 300 px ; la coupure tombe en fin de ligne et pose
   des points de suspension, donc on voit qu'il en reste. */
.gi-cat-apercu__textes {
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--gi-line-soft);
}
.gi-cat-apercu__textes p {
  font-size: var(--fs-xs);
  line-height: 1.45;
  color: var(--gi-sand-200);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 10;
  line-clamp: 10;
  overflow: hidden;
}
.gi-cat-apercu__textes p + p { margin-top: var(--sp-2); }
/* L'ETIQUETTE RESTE DANS LE FLUX DU TEXTE, ET C'EST VOULU. En bloc, elle
   prendrait une ligne a elle seule et doublerait la hauteur du couple ; en
   `inline-block` elle ouvre la premiere ligne et le texte reprend derriere,
   comme une entree de glossaire. Elle ne se coupe jamais en deux. */
.gi-cat-apercu__etiq {
  display: inline-block;
  margin-right: 0.4rem;
  padding: 0.05rem 0.3rem;
  border: 1px solid var(--gi-line-soft);
  border-radius: 3px;
  font-size: 0.6875rem;
  font-weight: 700;
  white-space: nowrap;
  color: var(--gi-gold-200);
  background: var(--gi-ink-750);
}

/* LES HUIT COULEURS DE LA SOURCE, ET ELLES SONT UN ENSEMBLE FERME.
   Le versement ne pose aucun style en ligne : laisser la source decider d'une
   couleur d'ecran serait lui laisser decider de la charte. Une neuvieme
   couleur s'afficherait sans emphase, et le versement s'en plaindrait dans ses
   avertissements. */
.gidb-c-or       { color: #ffd780; }
.gidb-c-cyan     { color: #99ffff; }
.gidb-c-bleu     { color: #80c0ff; }
.gidb-c-rouge    { color: #ff9999; }
.gidb-c-mauve    { color: #ffacff; }
.gidb-c-vert-eau { color: #80ffd7; }
.gidb-c-sable    { color: #ffe699; }
.gidb-c-vert     { color: #99ff88; }

/* LES FAMILLES DE MATERIAUX, EN RANGEE ET PAS EN COLONNE. `__l` empile une
   ligne par axe : six icones y descendraient l'une sous l'autre et le panneau
   ferait le double de sa hauteur. La rangee passe a la ligne d'elle-meme
   quand il y en a huit, ce qui est le cas des Voyageurs. */
/* SIX ICONES REMPLISSENT LA LARGEUR DU PANNEAU, ET C'EST LA MESURE.
   Six colonnes egales, pas une rangee qui s'ajuste : la taille d'une vignette
   ne doit pas dependre du nombre de familles, sinon Manekin, qui n'en a que
   trois, aurait des icones deux fois plus grosses que tout le monde. A six on
   remplit, a trois on remplit la moitie, a huit — les Voyageurs — la rangee
   passe a la ligne sans changer de calibre. */
/* TROIS RESSOURCES DANS UN PANNEAU LARGE, ET LE CALIBRE NE DOIT PAS SUIVRE.
   Mesure du 4 aout 2026 : trois pistes fluides dans les 21 rem du panneau des
   armes donnaient des icones de 105 px, trois fois le calibre des
   personnages ; la rangee ecrasait le passif qu'elle suit. Le plafond de
   3,6 rem les ramene a 58 px, et `justify-items: center` les repartit dans la
   largeur au lieu de les tasser a gauche. Les six pistes des personnages font
   37 px et n'atteignent jamais ce plafond : leur panneau ne bouge pas. */
.gi-cat-apercu__mats {
  display: grid;
  grid-template-columns: repeat(var(--gi-mats-cols, 6), minmax(0, 1fr));
  justify-items: center;
  gap: 0.3rem;
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--gi-line-soft);
}
/* MEME RECETTE QUE LA GRILLE : partout ou l'on pose l'icone d'une entite, on
   pose le fond de SA rarete. Le degrade est celui du portrait, en plus court.
   Une rarete absente tombe sur --cat-r0, comme ailleurs. */
.gi-cat-apercu__mat {
  width: 100%;
  max-width: 3.6rem;
  height: auto;
  aspect-ratio: 1;
  display: block;
  object-fit: contain;
  border: 1px solid var(--gi-line-soft);
  border-radius: 3px;
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--rar, var(--cat-r0)) 74%, #060b12) 0%,
      var(--rar, var(--cat-r0)) 100%);
}
.gi-cat-apercu__mat[data-r="1"] { --rar: var(--cat-r1); }
.gi-cat-apercu__mat[data-r="2"] { --rar: var(--cat-r2); }
.gi-cat-apercu__mat[data-r="3"] { --rar: var(--cat-r3); }
.gi-cat-apercu__mat[data-r="4"] { --rar: var(--cat-r4); }
.gi-cat-apercu__mat[data-r="5"] { --rar: var(--cat-r5); }
.gi-cat-apercu__note {
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  font-size: 0.6875rem;
  color: var(--gi-sand-600);
  border-top: 1px solid var(--gi-line-soft);
}

/* ==========================================================================
   C5. ATTENTE, ETAT VIDE, PANNE
   ========================================================================== */

.gi-cat__note { padding: var(--sp-8) var(--sp-4); text-align: center; }
.gi-cat__note-star {
  width: 20px; height: 20px;
  margin: 0 auto var(--sp-4);
  background: var(--gi-gold-600);
  -webkit-mask: var(--gi-star) center / contain no-repeat;
          mask: var(--gi-star) center / contain no-repeat;
}
.gi-cat__note-title {
  font-family: var(--gi-font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: var(--ls-caps-md);
  text-transform: uppercase;
  color: var(--gi-sand-200);
}
.gi-cat__note-desc { margin-top: var(--sp-2); font-size: var(--fs-base); color: var(--gi-text-faint); }

.gi-cat__skel {
  aspect-ratio: 0.82;
  width: 100%;
  border-radius: 4px;
  background: linear-gradient(180deg, var(--gi-ink-800), var(--gi-ink-850));
  border: 1px solid var(--gi-line-soft);
  animation: gi-cat-pulse 1.4s var(--ease-in-out) infinite;
}
@keyframes gi-cat-pulse { 50% { opacity: 0.45; } }
@media (prefers-reduced-motion: reduce) {
  .gi-cat__skel { animation: none; }
  .gi-cat-card, .gi-cat-card__portrait img, .gi-cat-apercu { transition: none; }
}

/* ==========================================================================
   C6. PALIERS
   --------------------------------------------------------------------------
   Sous 1080 px, la colonne de filtres repasse au-dessus de la grille : a cette
   largeur elle mangerait plus de place qu'elle n'en rend.
   ========================================================================== */

@media (max-width: 1080px) {
  .gi-cat { grid-template-columns: minmax(0, 1fr); }
  .gi-cat__aside {
    position: static;
    max-height: none;
    order: -1;
  }
  .gi-cat__filters { flex-direction: row; flex-wrap: wrap; gap: var(--sp-3) var(--sp-5); }
  .gi-cat-group { flex: 1 1 16rem; }

  /* SUR PETIT ECRAN, LES GROUPES SE REPLIENT, ET ILS S'OUVRENT FERMES. Quatre
     axes deroules poussaient la grille a plus d'un ecran de haut avant le
     premier portrait. Le script pose `open`, la feuille le retire ici :
     l'attribut reste dans le DOM, donc rouvrir un groupe le rouvre pour de
     bon, et l'ordinateur n'est pas concerne. */
  .gi-cat-group__label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: 0.35rem 0;
    cursor: pointer;
  }
  .gi-cat-group__label::after {
    content: "";
    width: 9px; height: 9px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    rotate: 45deg;
    translate: 0 -2px;
    transition: rotate var(--t-fast);
  }
  .gi-cat-group[open] > .gi-cat-group__label::after { rotate: -135deg; translate: 0 2px; }
}
@media (max-width: 1400px) { .gi-cat__grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (max-width: 1180px) { .gi-cat__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 860px)  { .gi-cat__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .gi-cat__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

@media (max-width: 760px) {
  .gi-cat { --cat-tuile: 8rem; --cat-gap: var(--sp-3); }
  /* ET IL FAUT ALLER CHERCHER LE PERSONNALISATEUR DE DIVI, DEUXIEME FOIS.
   Mesure du 03/08/2026 : la colonne portait un `padding-left: 14px` que
   `padding: 0` ne battait pas. Divi emet `.et-db #et-boc .et-l ul` avec son
   IDENTIFIANT `#et-boc`, qui bat toute regle a simple classe. C'est le meme
   defaut que l'en-tete a 184 px, et il vaut pour TOUTE liste que nous posons
   dans le contenu Divi. Ne pas passer par `!important` : se hisser d'une
   classe au dessus suffit. */
.et-db #et-boc .et-l ul.gi-cat-card__ico,
ul.gi-cat-card__ico.gi-cat-card__ico { padding: 0; margin: 0; }
.et-db #et-boc .et-l ul.gi-fiche-ids,
ul.gi-fiche-ids.gi-fiche-ids { padding: 0; }
.et-db #et-boc .et-l ul.gi-cat__grid,
ul.gi-cat__grid.gi-cat__grid { padding: 0; }

.gi-cat-card__ico li { width: 1.4rem; height: 1.4rem; font-size: 0.78rem; }
}
@media (max-width: 400px) {
  .gi-cat { --cat-tuile: 6.8rem; }
  .gi-cat-card__name { padding: var(--sp-2); font-size: var(--fs-sm); }
}

/* --------------------------------------------------------------------------
   L'INFOBULLE D'UNE ARME : LE TYPE ET L'ATQ SUR UNE LIGNE, LE RESTE DESSOUS

   Retouche du 4 aout 2026, puis du 5. La premiere version mettait le type
   d'arme et la statistique secondaire cote a cote sur deux colonnes ; la
   deuxieme gardait le type et l'ATQ ensemble et renvoyait le reste a la ligne.

   La troisieme ne garde plus rien ensemble : UNE LIGNE PAR INFORMATION. Deux
   colonnes se lisent bien tant que les libelles sont courts et cassent le jour
   ou l'un s'allonge, et « Maitrise elementaire » comme « Recharge d'energie »
   sont deja a la limite. Un libelle qui tient aujourd'hui n'est pas un libelle
   qui tient : la version suivante du jeu peut en ajouter un plus long sans
   prevenir. La ligne pleine est la seule forme dont on n'aura pas a revenir.

   La regle vit desormais dans le JS, qui pose la classe sur TOUTES les lignes.
   Elle est gardee ici parce que la grille, elle, existe toujours.
   -------------------------------------------------------------------------- */
.gi-cat-apercu__l-plein { grid-column: 1 / -1; }

/* La valeur, et elle seule, en chiffres alignes : deux armes survolees l'une
   apres l'autre doivent comparer leurs ATQ sans que le chiffre se decale. */
.gi-cat-apercu__mes {
  margin-left: 0.4rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--gi-gold-200);
}


/* ==========================================================================
   LES ONZE SYMBOLES DES MONSTRES, DESSINES ICI ET NON VERSES

   Le Backend les a cherches dans les 18 004 fichiers de la bibliotheque
   d'assets, puis regardes : il n'existe aucune icone de famille de bestiaire,
   et les quatre fichiers `UI_Codex*` qui concernent les monstres dessinent
   quatre variantes d'un seul masque cornu generique. Il n'y a pas non plus
   d'icone de statut. Ces onze symboles ne peuvent donc pas venir du versement,
   et ils sont dessines a la main dans cette feuille.

   ILS PASSENT PAR LE MEME MECANISME QUE LES ICONES VERSEES, et c'est ce qui
   les rend jetables : `--ico` sert de MASQUE, `--chip` donne la couleur. La
   seule difference est que `--ico` est ecrite ici au lieu de l'etre par le
   script. Le jour ou la source publierait de vraies icones, le script poserait
   un `.gi-sym--peint` avec son propre `--ico` en style en ligne, qui bat
   celui-ci, et ces regles cesseraient de s'appliquer sans qu'on y touche.

   SEUL LE STATUT EST EN COULEUR, LES SEPT FAMILLES RESTENT CLAIRES. C'est la
   regle du projet, celle qui garde l'element seul colore sur une tuile de
   personnage : trois couleurs dans une colonne de deux symboles se
   disputeraient l'oeil.

   LES SELECTEURS SONT GLOBAUX, comme ceux des sept elements plus haut, et pour
   la meme raison : le panneau de survol vit dans le <body>, hors du bloc du
   catalogue, et une regle scopee sur [data-gi-cat] ne l'atteindrait jamais.
   ========================================================================== */

/* Le statut, quatre valeurs, et la rampe monte comme la rarete : vert, bleu,
   violet, or. Ce sont les teintes 2 a 5 du site, celles des raretes, et elles
   sont reprises telles quelles parce qu'un monstre n'a pas de rarete et que
   cette rampe est deja le langage du site pour dire « celui-ci compte plus que
   le precedent ». */
[data-v="normal"]      { --chip: var(--cat-r2); --chip-on: 1; }
[data-v="elite"]       { --chip: var(--cat-r3); --chip-on: 1; }
[data-v="boss"]        { --chip: var(--cat-r4); --chip-on: 1; }
[data-v="weekly_boss"] { --chip: var(--cat-r5); --chip-on: 1; }

/* LE FOND DE LA TUILE PREND LA TEINTE DU STATUT, ET IL PASSE PAR :has().

   Partout ailleurs, --rar est posee par data-r, que le script ecrit depuis
   l'axe des etoiles. Ici l'axe des etoiles est vide : un monstre n'a pas de
   rarete, et nommer rank comme axe d'etoiles lui retirerait son symbole sur la
   tuile ET sa ligne dans le panneau de survol. La tuile prend donc la teinte
   du symbole qu'elle porte deja, ce qui ne demande aucun code neuf.

   MESURE DU 6 AOUT 2026, sur 30 monstres tires dans tout le fichier : les
   icones de bestiaire sont transparentes a 24 % en mediane, de 0 a 42 %. Le
   fond se voit donc sur la quasi-totalite des tuiles. Deux sur trente sont
   opaques a plus de 98 % et mangent la teinte : c'est un defaut d'image, pas
   un defaut de regle, et il ne se repare pas ici. */
.gi-cat-card:has(.gi-sym--point[data-v="normal"])      { --rar: var(--cat-r2); }
.gi-cat-card:has(.gi-sym--point[data-v="elite"])       { --rar: var(--cat-r3); }
.gi-cat-card:has(.gi-sym--point[data-v="boss"])        { --rar: var(--cat-r4); }
.gi-cat-card:has(.gi-sym--point[data-v="weekly_boss"]) { --rar: var(--cat-r5); }

/* Les sept familles, en clair neutre. */
[data-v="beast"],
[data-v="human"],
[data-v="elemental"],
[data-v="automaton"],
[data-v="hilichurl"],
[data-v="fatui"],
[data-v="abyss"]       { --chip: var(--gi-sand-100); --chip-on: 1; }

/* Un losange plein : le monstre ordinaire. */
[data-v="normal"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3.4 L19 12 L12 20.6 L5 12 Z'/%3E%3C/svg%3E");
}
/* Le meme losange, plus etroit, flanque de deux ailerons : l'elite.
   LES AILERONS ONT ETE GROSSIS DEUX FOIS. Ce symbole et le precedent ne se
   distinguent que par eux : a 18 px, calibre de la colonne d'une tuile, la
   premiere version rendait deux points a peine visibles et l'elite se lisait
   « monstre ordinaire ». */
[data-v="elite"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.8 L16.6 12 L12 22.2 L7.4 12 Z M1.2 12 L5.6 6.6 L5.6 17.4 Z M22.8 12 L18.4 6.6 L18.4 17.4 Z'/%3E%3C/svg%3E");
}
/* Une couronne : le boss de terrain. */
[data-v="boss"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2.6 19.6 L2.6 6.2 L8.2 11.4 L12 3.8 L15.8 11.4 L21.4 6.2 L21.4 19.6 Z'/%3E%3C/svg%3E");
}
/* L'etoile a quatre branches, celle des raretes du jeu : le boss hebdomadaire. */
[data-v="weekly_boss"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.2 C13.2 8 16 10.8 22.8 12 C16 13.2 13.2 16 12 22.8 C10.8 16 8 13.2 1.2 12 C8 10.8 10.8 8 12 1.2 Z'/%3E%3C/svg%3E");
}

/* Une empreinte de patte : les betes mystiques.
   TROIS GRIFFES ONT ETE ESSAYEES AVANT, ET REFUSEES SUR PLANCHE. Rendues a
   24 px, trois lames verticales se lisent « ||| », et fanees en eventail elles
   se lisent « W ». L'empreinte, elle, se reconnait aux deux calibres. */
[data-v="beast"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 11.6 C15.6 11.6 18.6 14 18.6 16.9 C18.6 19.5 16.2 21.4 12 21.4 C7.8 21.4 5.4 19.5 5.4 16.9 C5.4 14 8.4 11.6 12 11.6 Z'/%3E%3Cellipse cx='4.6' cy='10.4' rx='2.5' ry='3.2' transform='rotate(-18 4.6 10.4)'/%3E%3Cellipse cx='9.4' cy='6.2' rx='2.5' ry='3.4'/%3E%3Cellipse cx='14.6' cy='6.2' rx='2.5' ry='3.4'/%3E%3Cellipse cx='19.4' cy='10.4' rx='2.5' ry='3.2' transform='rotate(18 19.4 10.4)'/%3E%3C/svg%3E");
}
/* Un buste : les humains. */
[data-v="human"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.2 a4.3 4.3 0 1 0 0.01 0 Z M3 21.6 C4.3 15.5 7.8 12.4 12 12.4 C16.2 12.4 19.7 15.5 21 21.6 Z'/%3E%3C/svg%3E");
}
/* Un slime, dome et deux yeux : les entites elementaires.
   Le dome nu a ete essaye : il se lit « arche » et n'apprend rien. Les deux
   yeux survivent au calibre de 24 px, verifie sur planche. */
[data-v="elemental"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.6 20.2 C2.6 11.2 6.8 4 12 4 C17.2 4 21.4 11.2 21.4 20.2 Z M8.6 11.4 a1.9 2.6 0 1 0 0.01 0 Z M15.4 11.4 a1.9 2.6 0 1 0 0.01 0 Z'/%3E%3C/svg%3E");
}
/* Un engrenage : les automates. */
[data-v="automaton"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M9.8 4.7 L10.1 1.0 L13.9 1.0 L14.2 4.7 L15.6 5.3 L18.4 2.8 L21.2 5.6 L18.7 8.4 L19.3 9.8 L23.0 10.1 L23.0 13.9 L19.3 14.2 L18.7 15.6 L21.2 18.4 L18.4 21.2 L15.6 18.7 L14.2 19.3 L13.9 23.0 L10.1 23.0 L9.8 19.3 L8.4 18.7 L5.6 21.2 L2.8 18.4 L5.3 15.6 L4.7 14.2 L1.0 13.9 L1.0 10.1 L4.7 9.8 L5.3 8.4 L2.8 5.6 L5.6 2.8 L8.4 5.3 Z M12 8.5 a3.5 3.5 0 1 0 0.01 0 Z'/%3E%3C/svg%3E");
}
/* Un masque a deux cornes : les brutocollinus. */
[data-v="hilichurl"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 21.4 C6.6 21.4 4 17.4 4 12.8 C4 11.3 4.2 9.9 4.6 8.7 L2.4 2.8 L7.6 6.1 C8.9 5.3 10.4 4.9 12 4.9 C13.6 4.9 15.1 5.3 16.4 6.1 L21.6 2.8 L19.4 8.7 C19.8 9.9 20 11.3 20 12.8 C20 17.4 17.4 21.4 12 21.4 Z'/%3E%3C/svg%3E");
}
/* Un masque de bal a deux yeux : les Fatui. */
[data-v="fatui"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M1.8 7.6 C6 6.2 18 6.2 22.2 7.6 C22.2 13.4 19 17.4 15.4 17.4 C13.4 17.4 12.6 15.7 12 14.4 C11.4 15.7 10.6 17.4 8.6 17.4 C5 17.4 1.8 13.4 1.8 7.6 Z M7 9.6 a2.1 2.1 0 1 0 0.01 0 Z M17 9.6 a2.1 2.1 0 1 0 0.01 0 Z'/%3E%3C/svg%3E");
}
/* Un oeil : l'Ordre de l'Abime. */
[data-v="abyss"] {
  --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M1.4 12 C5.4 6 8.7 3.8 12 3.8 C15.3 3.8 18.6 6 22.6 12 C18.6 18 15.3 20.2 12 20.2 C8.7 20.2 5.4 18 1.4 12 Z M12 8.4 a3.6 3.6 0 1 0 0.01 0 Z'/%3E%3C/svg%3E");
}

/* LA PASTILLE DEVIENT UN SYMBOLE. .gi-sym--point est la forme de repli du
   script quand le vocabulaire ne porte pas d'icone : un disque plein. Ces onze
   valeurs la reprennent et la masquent, ce qui donne exactement le rendu d'un
   .gi-sym--peint. Le border-radius et l'ombre de la forme de repli sont
   annules : un masque decoupe deja la silhouette, un rond derriere lui la
   trahirait. */
.gi-sym--point:is([data-v="normal"], [data-v="elite"], [data-v="boss"],
                  [data-v="weekly_boss"], [data-v="beast"], [data-v="human"],
                  [data-v="elemental"], [data-v="automaton"],
                  [data-v="hilichurl"], [data-v="fatui"], [data-v="abyss"]) {
  width: 1.15em;
  height: 1.15em;
  border-radius: 0;
  box-shadow: none;
  -webkit-mask: var(--ico) center / contain no-repeat;
          mask: var(--ico) center / contain no-repeat;
}
/* Une etiquette enfoncee a un fond clair : le symbole y passe a l'encre, comme
   le fait deja .gi-sym--peint. Sans cette ligne, l'etoile doree du boss
   hebdomadaire disparaissait sur l'or de l'etiquette active. */
.gi-cat-chip[aria-pressed="true"] .gi-sym--point:is([data-v="normal"],
  [data-v="elite"], [data-v="boss"], [data-v="weekly_boss"], [data-v="beast"],
  [data-v="human"], [data-v="elemental"], [data-v="automaton"],
  [data-v="hilichurl"], [data-v="fatui"], [data-v="abyss"]) {
  background: var(--gi-ink-900);
  box-shadow: none;
}
