/* ==========================================================================
   LE PROFIL PUBLIC, ET CE QUI L'HABILLE (v29).

   POURQUOI CETTE FEUILLE EXISTE, ET POURQUOI ELLE EST SEULE.
   Une teinte de pseudo, un cadre de portrait et un fond de bannière
   s'affichent à DEUX endroits : dans le jeu (index.html, site.css) et sur la
   page publique d'un profil, rendue par le serveur (fiche.css). Ces deux
   feuilles sont volontairement séparées — la page publique doit s'afficher
   entière sans style.css ni site.css, qui pèsent lourd.

   Recopier les cadres et les fonds dans les deux aurait donné deux vérités
   pour un même article payé : le jour où « Nébuleuse » change de dégradé,
   l'une des deux resterait en arrière, et le joueur verrait deux profils
   différents selon qu'il clique dans le jeu ou ouvre son propre lien. Une
   seule feuille, deux consommateurs.

   RÈGLE DE CETTE FEUILLE : elle décrit l'apparence des ARTICLES ACHETÉS et les
   BLOCS que les deux consommateurs affichent à l'identique — le disque du
   portrait, la ligne d'identité, les marques, les chiffres, les barres de
   collection. Ce sont les mêmes objets, ils doivent se ressembler.

   Ce qu'elle ne décrit PAS : la mise en page d'ensemble. La page publique est
   une colonne de 980 px ; le panneau du jeu est un voile plein écran avec une
   bannière plus haute et des cartes rendues en volume. Chacun garde la sienne.

   RÈGLE DE NOMMAGE, QUI EST UNE RÈGLE DE SÉCURITÉ : le nom de chaque classe
   est écrit dans `config.cosmetiques` et sert tel quel. Le client ne fabrique
   JAMAIS un nom de classe en concaténant une clef reçue du serveur — la CSP du
   site (`style-src 'self'`) ferme la porte du style en ligne, et une classe
   calculée la rouvrirait par la fenêtre. `tests/profil.test.mjs` vérifie que
   chaque article du catalogue trouve bien sa classe ici.
   ========================================================================== */

/* --------------------------------------------------------------- teintes --
   La palette FERMÉE du pseudo. Les valeurs sont celles de
   `config.cosmetiques.teintes` — un test les compare, parce que deux listes de
   couleurs qui dérivent, ça ne se voit pas en relecture.

   Elles vivent ici plutôt qu'en variable CSS parce que la page publique n'a
   pas de JavaScript pour poser une variable : elle écrit `class="t-ambre"` et
   c'est tout. */
.t-ambre{color:#F5D072}
.t-jade{color:#7FE3D0}
.t-corail{color:#FF8B6B}
.t-givre{color:#8FB8FF}
.t-iris{color:#A97BFF}
.t-prisme{
  background:linear-gradient(90deg,#F5D072,#FF8B6B,#A97BFF,#8FB8FF,#7FE3D0,#F5D072);
  background-size:300% 100%;animation:parure-prisme 6s linear infinite;
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
@keyframes parure-prisme{to{background-position:300% 0}}

/* ---------------------------------------------------------------- portrait --
   Le disque qui porte la carte choisie. Sans cadre acheté, il a déjà un
   liseré : un portrait nu aurait l'air d'un trou dans la page, et une page qui
   a l'air cassée ne donne envie de rien acheter. */
.profil-portrait{
  position:relative;display:grid;place-items:center;flex:0 0 auto;
  width:var(--portrait,104px);height:var(--portrait,104px);border-radius:50%;
  overflow:hidden;background:#12141D;
  border:2px solid rgba(255,255,255,.14);
  box-shadow:0 10px 30px rgba(0,0,0,.45);
}
.profil-portrait img{width:100%;height:100%;object-fit:cover;display:block}
/* Le repli : l'initiale. Elle doit être aussi soignée que le portrait payant,
   sinon le rayon vend par la honte — ce qui ne vend pas. */
.profil-portrait.vide{
  font-size:calc(var(--portrait,104px) * .42);font-weight:800;line-height:1;
  color:#C3C9DA;
  background:radial-gradient(120% 120% at 30% 20%,#242840,#12141D 70%);
}

/* ------------------------------------------------------------------ cadres --
   Quatre traitements du même disque. Aucun ne recadre l'image : le cadre se
   pose AUTOUR (bordure, halo, encoche), jamais par-dessus le visage de la
   carte. */

/* Halo — une lueur douce, la plus discrète des quatre. */
.profil-portrait.cadre-halo{
  border-color:rgba(79,227,208,.55);
  box-shadow:0 0 0 4px rgba(79,227,208,.12), 0 0 26px rgba(79,227,208,.38),
             0 10px 30px rgba(0,0,0,.45);
}

/* Iris — le dégradé de la maison en anneau. Le fond dégradé déborde du
   `border-box` sous une bordure transparente : c'est ce qui donne un anneau
   coloré net sans seconde boîte ni pseudo-élément qui masquerait l'image. */
.profil-portrait.cadre-iris{
  border-color:transparent;
  background:
    linear-gradient(#12141D,#12141D) padding-box,
    linear-gradient(102deg,#4FE3D0,#5AA8FF 34%,#A97BFF 62%,#FF77C4) border-box;
  border-width:3px;
  box-shadow:0 0 22px rgba(169,123,255,.35), 0 10px 30px rgba(0,0,0,.45);
}

/* Facette — la pierre taillée : un hexagone, pas un disque. */
.profil-portrait.cadre-facette{
  border-radius:14%;
  clip-path:polygon(50% 0%,93% 25%,93% 75%,50% 100%,7% 75%,7% 25%);
  border-color:rgba(255,196,107,.7);
  box-shadow:0 0 20px rgba(255,196,107,.3), 0 10px 30px rgba(0,0,0,.45);
}

/* Éclipse — l'anneau sombre et le croissant de lumière. Le croissant est un
   dégradé conique posé sur l'anneau, donc il tourne avec la boîte et ne coûte
   aucune image. */
.profil-portrait.cadre-eclipse{
  border-color:transparent;border-width:3px;
  background:
    linear-gradient(#12141D,#12141D) padding-box,
    conic-gradient(from 210deg,
      rgba(255,255,255,.92) 0deg, rgba(143,184,255,.75) 42deg,
      rgba(10,10,18,.9) 120deg, rgba(10,10,18,.9) 300deg,
      rgba(255,255,255,.92) 360deg) border-box;
  box-shadow:0 0 24px rgba(143,184,255,.32), 0 10px 30px rgba(0,0,0,.45);
}

/* ------------------------------------------------------------------- fonds --
   La bannière du profil. SANS achat, elle n'est pas vide : le consommateur y
   pose l'illustration de la plus belle carte du joueur, floutée (`.profil-decor`).
   C'est ce qui rend le rayon vendable — on n'achète pas ce qui répare une page
   laide, on achète ce qui distingue une page qu'on aime déjà. */
.profil-tete{
  position:relative;overflow:hidden;border-radius:20px;
  /* Le fond PAR DEFAUT n’est pas un aplat noir : une bannière vide aurait l’air
     cassée, et une page qui a l’air cassée ne donne envie de rien acheter. Ce
     dégradé très sourd tient tout seul pour un compte sans une seule carte, et
     passe sous l’illustration floutée dès qu’il y en a une. */
  background:
    radial-gradient(120% 130% at 20% 0%, rgba(90,168,255,.14), transparent 62%),
    radial-gradient(110% 120% at 85% 10%, rgba(169,123,255,.12), transparent 60%),
    #0D0F17;
  border:1px solid rgba(255,255,255,.10);
  isolation:isolate;
}
/* L'illustration de repli. `aria-hidden` côté balise : c'est un décor, et le
   nom de la carte est déjà dit ailleurs sur la page. */
.profil-decor{
  position:absolute;inset:-8%;width:116%;height:116%;object-fit:cover;
  filter:blur(26px) saturate(130%);opacity:.5;z-index:-1;
  transform:scale(1.06);
}
/* Le flou se règle sur la HAUTEUR de la boîte, pas dans l’absolu. A 26 px sur
   une vignette d’annuaire haute de 64, il ne reste plus qu’une moyenne grise :
   l’illustration est bien là, et elle ne se voit pas. La règle est chez le
   consommateur qui connaît sa taille (site.css, .an-fond). */
/* Le voile qui garde le texte lisible quelle que soit l'image dessous. Il est
   posé par le consommateur (une boîte à lui), jamais ici : le dégradé dépend
   de l'endroit où le texte tombe, et il ne tombe pas au même endroit dans le
   jeu et sur la page publique. */

.fond-nebuleuse{
  background:
    radial-gradient(120% 130% at 18% 12%, rgba(169,123,255,.55), transparent 62%),
    radial-gradient(110% 120% at 84% 22%, rgba(255,119,196,.42), transparent 60%),
    radial-gradient(140% 140% at 60% 110%, rgba(79,227,208,.28), transparent 66%),
    #0A0912;
}
.fond-aurore{
  background:
    linear-gradient(168deg, rgba(63,214,164,.42) 0%, transparent 52%),
    radial-gradient(120% 90% at 22% 0%, rgba(79,227,208,.5), transparent 64%),
    radial-gradient(120% 90% at 78% 6%, rgba(90,168,255,.42), transparent 62%),
    #06110F;
}
.fond-trame{
  background:
    repeating-linear-gradient(0deg, rgba(143,184,255,.13) 0 1px, transparent 1px 26px),
    repeating-linear-gradient(90deg, rgba(143,184,255,.13) 0 1px, transparent 1px 26px),
    radial-gradient(120% 120% at 50% 0%, rgba(90,168,255,.26), transparent 70%),
    #080B14;
}
.fond-onde{
  background:
    repeating-radial-gradient(circle at 20% 120%,
      rgba(255,196,107,.20) 0 2px, transparent 2px 22px),
    radial-gradient(120% 120% at 20% 110%, rgba(255,139,107,.34), transparent 62%),
    #100A08;
}

/* ==========================================================================
   LES BLOCS DU PROFIL, communs à la page publique et au panneau du jeu.
   Ils décrivent des OBJETS, pas une mise en page : une ligne d'identité, une
   rangée de marques, un tableau de chiffres, une barre de collection. Les deux
   consommateurs les posent dans des cadres différents, et c'est très bien —
   mais un chiffre et une marque doivent se ressembler des deux côtés.

   Les couleurs sont écrites en dur plutôt qu'en variables : la page publique
   n'a ni style.css ni site.css, donc `--gris` et `--bord` n'y existent que
   parce que fiche.css les déclare. Une valeur littérale tient dans les deux
   mondes sans dépendre de qui a été chargé.
   ========================================================================== */

.profil-identite{position:relative;z-index:1;display:flex;gap:clamp(14px,2.5vw,22px);
  align-items:flex-end;padding:clamp(16px,3vw,24px);width:100%}
.profil-qui{min-width:0}
.profil-titre{margin:4px 0 0;font-size:14px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:#C5BEDE}
.profil-depuis{margin:6px 0 0;color:#9BA2B8;font-size:13.5px}

/* Les MARQUES — ce qui ne s'achète pas. Elles portent l'or, seules : c'est ce
   qui les distingue d'un titre acheté, qui est gris et sous le pseudo. */
.profil-marques{display:flex;flex-wrap:wrap;gap:7px;margin:10px 0 0;padding:0;list-style:none}
.profil-marques li{font-size:11.5px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;padding:3px 10px;border-radius:999px;
  border:1px solid rgba(255,196,107,.45);color:#FFC46B;background:rgba(255,196,107,.08)}

.profil-chiffres{display:grid;gap:1px;margin:22px 0 0;
  background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.10);
  border-radius:14px;overflow:hidden;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,150px),1fr))}
.profil-chiffres div{background:#07080E;padding:14px 16px}
.profil-chiffres dt{color:#9BA2B8;font-size:12px;letter-spacing:.06em;
  text-transform:uppercase}
.profil-chiffres dd{margin:4px 0 0;font-size:clamp(20px,3vw,26px);font-weight:800;
  letter-spacing:-.02em}

/* Les collections. `<progress>` plutôt qu'une barre en `<div>` : l'élément
   porte sa valeur en attribut — donc aucun style en ligne, que la CSP du site
   ignorerait — et un lecteur d'écran l'annonce sans qu'on ait rien à ajouter. */
.profil-series{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.profil-series li{display:grid;gap:4px 14px;align-items:center;
  grid-template-columns:minmax(0,1fr) auto}
.profil-serie-nom{font-weight:650;font-size:14.5px}
.profil-serie-n{color:#9BA2B8;font-size:13px;font-variant-numeric:tabular-nums}
.profil-series progress{grid-column:1/-1;width:100%;height:7px;border:0;
  border-radius:999px;background:rgba(255,255,255,.08);appearance:none}
.profil-series progress::-webkit-progress-bar{background:rgba(255,255,255,.08);
  border-radius:999px}
.profil-series progress::-webkit-progress-value{border-radius:999px;
  background:linear-gradient(102deg,#4FE3D0,#5AA8FF 34%,#A97BFF 62%,#FF77C4)}
.profil-series progress::-moz-progress-bar{border-radius:999px;
  background:linear-gradient(102deg,#4FE3D0,#5AA8FF 34%,#A97BFF 62%,#FF77C4)}

@media (max-width:520px){
  .profil-identite{flex-direction:column;align-items:flex-start;gap:12px}
}

/* Mouvement réduit : la teinte reste, l'animation s'arrête. Une préférence
   système ne doit jamais priver quelqu'un de ce qu'il a payé — seulement du
   mouvement qui le gêne. */
/* Mode sobre (DECISIONS §52) : ex-@media prefers-reduced-motion. */ html.sobre .t-prisme{animation:none}
