/* =============================================================
   Socle · Squelette (.sc-skeleton)
   Formes : --text, --circle, --media (défaut : bloc)
   Pile : .sc-skeleton-group (--row) · Annonce : .sc-skeleton-status
   Dimensions en style inline, comme .sc-progress__bar.
   ============================================================= */

.sc-skeleton {
  /* Tokens de composant : les formes ne font que réassigner ceci. */
  /* L'aplat d'attente. Un squelette n'est pas une gouttière : il ne
     contient rien, il occupe la place du contenu absent et doit rester
     muet, d'où le premier cran neutre, celui des zones secondaires. Il
     faut de plus qu'il reste assez clair pour que --color-bg-shimmer
     passe dessus en se voyant. La piste de la progression exprime une
     autre intention et lit un autre rôle, voir progress.css. */
  --_skeleton-bg: var(--color-bg-subtle);
  --_skeleton-sweep: var(--color-bg-shimmer);
  --_skeleton-radius: var(--radius-control-s);
  --_skeleton-cycle: var(--motion-duration-loop);
  /* Structurel : aucun rôle ne dit la taille d'une attente. */
  --_skeleton-width: 100%;
  --_skeleton-height: var(--space-40);

  position: relative;
  display: block;
  flex-shrink: 0;
  width: var(--_skeleton-width);
  height: var(--_skeleton-height);
  border-radius: var(--_skeleton-radius);
  background: var(--_skeleton-bg);
  overflow: hidden;
}

/* Le dégradé s'éteint aux deux bords : sinon une arête nette
   traverse l'aplat. */
.sc-skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to right,
    transparent,
    var(--_skeleton-sweep),
    transparent
  );
  animation: sc-skeleton-sweep var(--_skeleton-cycle) var(--motion-ease-loop) infinite;
}

@keyframes sc-skeleton-sweep {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(100%);
  }
}

/* ---- Formes ---- */

/* Boîte = taille x interlignage, barre à la hauteur des glyphes :
   une barre prise pour toute la ligne raccourcit le squelette et la
   page saute au remplacement. 1em suit le contexte. */
.sc-skeleton--text {
  --_skeleton-radius: var(--radius-pill);
  --_skeleton-text-size: 1em;
  --_skeleton-text-leading: var(--leading-normal);
  --_skeleton-height: calc(var(--_skeleton-text-size) * var(--_skeleton-text-leading));
  /* Le demi-interligne, au-dessus et au-dessous de la barre. */
  --_skeleton-text-space: calc((var(--_skeleton-height) - var(--_skeleton-text-size)) / 2);

  /* L'aplat se replie sur la barre, l'interligne reste vide. */
  background: none;
}

.sc-skeleton--text::before {
  content: '';
  position: absolute;
  inset-block: var(--_skeleton-text-space);
  inset-inline: 0;
  border-radius: var(--_skeleton-radius);
  background: var(--_skeleton-bg);
}

/* Le balayage suit la barre et ne traverse pas l'interligne. */
.sc-skeleton--text::after {
  inset-block: var(--_skeleton-text-space);
  border-radius: var(--_skeleton-radius);
}

/* Pastille. Le rapport de forme plutôt qu'une variable : une hauteur
   posée en style inline emporte la largeur avec elle. */
.sc-skeleton--circle {
  --_skeleton-radius: var(--radius-pill);
  --_skeleton-width: auto;
  aspect-ratio: 1;
}

/* Vignette : image, aperçu, carte. Le rayon des surfaces. */
.sc-skeleton--media {
  --_skeleton-radius: var(--radius-surface);
  --_skeleton-height: var(--space-80);
}

/* ---- Pile ----
   Un squelette n'a pas de marge propre : la pile pose le rythme. */

.sc-skeleton-group {
  display: flex;
  flex-direction: column;
  gap: var(--gap-s);
}

/* Des lignes de texte seules ne prennent aucun intervalle : leurs
   boîtes portent déjà l'interligne, comme un vrai paragraphe. */
.sc-skeleton-group:not(.sc-skeleton-group--row):not(:has(> :not(.sc-skeleton--text))) {
  gap: 0;
}

/* En ligne : une pastille puis des lignes, comme un en-tête. */
.sc-skeleton-group--row {
  flex-direction: row;
  align-items: center;
  gap: var(--gap-m);
}

/* Une pile imbriquée dans une ligne prend la place restante. */
.sc-skeleton-group--row > .sc-skeleton-group {
  flex: 1;
}

/* ---- Annonce ----
   Le squelette étant masqué aux lecteurs d'écran, c'est ce texte
   qui dit que quelque chose se charge. */

.sc-skeleton-status {
  /* Structurel : présent pour la synthèse, invisible à l'œil. */
  --_status-size: 1px;

  position: absolute;
  width: var(--_status-size);
  height: var(--_status-size);
  margin: calc(var(--_status-size) * -1);
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- Mouvement réduit ----
   base.css fige l'animation, ce qui laisserait une bande claire en
   travers du bloc. On l'efface : l'attente se voit, sans bouger. */

@media (prefers-reduced-motion: reduce) {
  .sc-skeleton::after {
    display: none;
  }
}
