/* ════════════════════════════════════════════════════════════════
   6eHomme — chargement.css · LE BALLON QUI REBONDIT
   Remplace le rond tournant de l'écran de chargement PLEIN ÉCRAN.
   Idée de Karim (11/08). Réf : Cadrage_identite_pages_v1.md

   ⚠⚠ VERSION DANS LE NOM DU FICHIER. Toute retouche ⇒ nouveau nom + le
   <link> des pages concernées. Ne jamais modifier en place une fois déployé.

   ── PÉRIMÈTRE, ET C'EST LE POINT DÉLICAT ───────────────────────────────
   ⚠⚠ NE JAMAIS CIBLER `.spinner` TOUT SEUL. La classe sert AUSSI dans des
   BOUTONS sur les pages commissaire — `<span class="spinner"
   style="border-top-color:#fff"></span> Génération…` — où le style inline
   prouve qu'on compte sur le rond bordé. Un ballon qui rebondit dans un
   bouton serait absurde, et le `border-top-color` forcé n'aurait plus rien
   à colorer. ⇒ On ne cible que ce qui est DANS `#screen-loading`.
   Couvre 15 pages joueur ; `match.html` nomme son élément `.loading-spinner`.

   ── AUCUN BALISAGE MODIFIÉ ─────────────────────────────────────────────
   ⚡ Le rond est un <div> VIDE : ses pseudo-éléments sont libres. L'élément
   devient donc une SCÈNE fixe, `::before` porte le ballon (animé) et
   `::after` l'ombre (qui, elle, ne doit PAS bouger — sinon l'ombre
   accompagne le ballon en l'air et l'effet de poids disparaît).
   ⇒ Zéro page à retoucher, réversible en retirant un <link>.

   ── LE BALLON EST CELUI DU PRODUIT ─────────────────────────────────────
   Géométrie reprise de `icBall()` (assets/bottombar.js), l'onglet « Marché »
   de la barre du bas : même cercle, mêmes coutures. Un seul ballon dans le
   produit, pas deux.
   ══════════════════════════════════════════════════════════════════════ */

/* L'écrasement à l'impact est ce qui donne du POIDS au ballon : sans lui il
   flotte. `transform-origin` en bas — un ballon s'aplatit sur le sol, pas
   autour de son centre. */
@keyframes m6ld-ball{
  0%, 100% { transform: translateY(-20px) scale(1, 1); }
  45%      { transform: translateY(0)     scale(1, 1); }
  50%      { transform: translateY(1px)   scale(1.18, .82); }
  55%      { transform: translateY(0)     scale(1, 1); }
}
/* L'ombre ne se déplace pas : elle s'élargit et se fonce à l'impact. */
@keyframes m6ld-shadow{
  0%, 100% { transform: scaleX(.55); opacity: .16; }
  50%      { transform: scaleX(1);   opacity: .36; }
}

#screen-loading .spinner,
#screen-loading .loading-spinner{
  /* Neutralisation du rond bordé, en `!important` : chaque page redéfinit
     `.spinner` dans son propre <style>, déclaré APRÈS ce fichier (#143). */
  width: 34px !important; height: 48px !important;
  border: 0 !important; border-radius: 0 !important;
  background: none !important; animation: none !important;
  position: relative !important;
  margin-left: auto !important; margin-right: auto !important;
}

/* Le ballon. SVG en `data:` — pas de requête réseau sur un écran dont le
   rôle est justement de masquer une attente. Les `#` sont encodés `%23`. */
#screen-loading .spinner::before,
#screen-loading .loading-spinner::before{
  content: ''; position: absolute; left: 50%; bottom: 8px;
  width: 30px; height: 30px; margin-left: -15px;
  transform-origin: 50% 100%;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='9' fill='%23E8470A' stroke='%2315203A' stroke-width='1.4'/><path d='M3 12h18M12 3v18' fill='none' stroke='%2315203A' stroke-width='1.4'/><path d='M5.6 5.6C9 9 9 15 5.6 18.4M18.4 5.6C15 9 15 15 18.4 18.4' fill='none' stroke='%2315203A' stroke-width='1.4'/></svg>") center / contain no-repeat;
  animation: m6ld-ball .62s cubic-bezier(.45, 0, .55, 1) infinite;
}

/* L'ombre. `currentColor` : elle suit la couleur de texte de l'écran, donc
   elle se pose toute seule dans les DEUX thèmes sans règle dédiée. */
#screen-loading .spinner::after,
#screen-loading .loading-spinner::after{
  content: ''; position: absolute; left: 50%; bottom: 2px;
  width: 28px; height: 5px; margin-left: -14px;
  border-radius: 50%; background: currentColor;
  animation: m6ld-shadow .62s cubic-bezier(.45, 0, .55, 1) infinite;
}

/* ⚠ RÉGLAGE SYSTÈME À RESPECTER, ET IL EST GRATUIT. Un mouvement répété
   déclenche des nausées chez certaines personnes ; leur système le signale
   déjà. Le ballon reste, il cesse de bouger et respire. */
@media (prefers-reduced-motion: reduce){
  #screen-loading .spinner::before,
  #screen-loading .loading-spinner::before{
    animation: m6ld-pulse 1.6s ease-in-out infinite;
    transform: translateY(-10px);
  }
  #screen-loading .spinner::after,
  #screen-loading .loading-spinner::after{
    animation: none; opacity: .22; transform: scaleX(.8);
  }
}
@keyframes m6ld-pulse{
  0%, 100% { opacity: 1; }
  50%      { opacity: .45; }
}
