/* ============================================================
   ux-polish.css — couche additive de finition UI/UX
   Chargée APRÈS world-academy.css. N'écrase aucune règle existante :
   uniquement des ajouts (focus clavier, états de chargement, skeleton).
   Réutilise les tokens de :root et s'adapte au thème sombre.
   Respecte prefers-reduced-motion.
   ============================================================ */

/* --- 0. Skip-nav : visible au focus clavier uniquement ---------------- */
.skip-nav {
  position: absolute;
  left: 12px;
  top: -48px;
  z-index: 1080;
  padding: 8px 14px;
  border-radius: var(--radius-sm, 8px);
  background: var(--brand, #4a6287);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
}
.skip-nav:focus,
.skip-nav:focus-visible {
  top: 12px;
}

/* --- 1. Accessibilité : anneau de focus clavier cohérent ---------------
   Absent du CSS de base. Ne s'affiche qu'à la navigation clavier
   (:focus-visible), donc invisible à la souris : zéro impact visuel
   pour l'usage courant, gain WCAG net. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible,
.btn:focus-visible,
.btn-favori-sm:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}
/* Retire l'anneau au clic souris quand :focus-visible est supporté. */
a:focus:not(:focus-visible),
button:focus:not(:focus-visible),
.btn:focus:not(:focus-visible) {
  outline: none;
}

/* --- 2. Cible tactile minimale (confort mobile) ------------------------
   S'applique seulement aux petits boutons icône déjà présents. */
@media (max-width: 576px) {
  .btn-favori-sm,
  .btn-panier-icon {
    min-width: 40px;
    min-height: 40px;
  }
}

/* --- 3. Boutons : état de chargement (opt-in via .is-loading) ----------
   À poser sur un bouton pendant une action asynchrone (panier, formulaire).
   Empêche le double-clic ressenti et donne un feedback immédiat. */
.btn.is-loading {
  position: relative;
  color: transparent !important;
  pointer-events: none;
}
.btn.is-loading::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1.1em;
  height: 1.1em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: #fff;
  animation: ux-spin .6s linear infinite;
}
.btn.btn-ghost.is-loading::after,
.btn.btn-outline.is-loading::after { color: var(--brand); }

@keyframes ux-spin { to { transform: rotate(360deg); } }

/* --- 4. Skeleton de chargement (opt-in via .skeleton) ------------------
   Placeholder scintillant pour les zones chargées en asynchrone
   (listes, cartes, avatars) avant l'arrivée du contenu. */
.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--line-soft);
  border-radius: var(--radius-sm);
  color: transparent !important;
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, .55),
    transparent
  );
  animation: ux-shimmer 1.4s infinite;
}
.skeleton--text { height: .8em; margin: .35em 0; }
.skeleton--title { height: 1.2em; width: 70%; margin: .4em 0; }
.skeleton--avatar { width: 40px; height: 40px; border-radius: 50%; }
.skeleton--card { height: 180px; }

@keyframes ux-shimmer { to { transform: translateX(100%); } }

/* --- 5. Apparition douce du contenu (opt-in via .u-reveal) -------------
   À poser sur un bloc pour un fondu/montée léger à l'affichage.
   Opt-in : n'affecte jamais un élément non ciblé (pas de risque
   d'image ou de bloc restant invisible). */
.u-reveal {
  animation: ux-reveal var(--duration-fast, .35s) var(--ease-out, ease-out) both;
}
@keyframes ux-reveal {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* --- 6. Respect de prefers-reduced-motion -----------------------------
   Coupe toutes les animations ajoutées ci-dessus pour les utilisateurs
   qui le demandent (le spinner reste, mais figé sans clignotement). */
@media (prefers-reduced-motion: reduce) {
  .skeleton::after,
  .u-reveal { animation: none; }
  .skeleton::after { display: none; }
  .u-reveal { opacity: 1; transform: none; }
}

/* --- Liens de navigation epingles ------------------------------------
   Le bouton vit DANS le lien : il reste discret au repos et n'apparait
   qu'au survol ou au focus clavier, pour ne pas alourdir la barre. Une
   epingle active reste visible en permanence, sinon on ne saurait plus
   quels liens sont epingles. */
.sidebar-link, .sidebar-sublink { position: relative; }

.sidebar-epingle-btn {
  margin-left: auto;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-muted, #a1acb8);
  font-size: 0.75rem;
  cursor: pointer;
  opacity: 0;
  transition: opacity .12s ease, color .12s ease, background-color .12s ease;
}
.sidebar-link:hover .sidebar-epingle-btn,
.sidebar-sublink:hover .sidebar-epingle-btn,
.sidebar-epingle-btn:focus-visible,
.sidebar-epingle-btn.is-epingle { opacity: 1; }

.sidebar-epingle-btn:hover { background: var(--line-soft, rgba(148,163,184,.18)); }
.sidebar-epingle-btn.is-epingle { color: var(--brand, #4a6287); }
.sidebar-epingle-btn.is-epingle i { transform: rotate(-45deg); }
.sidebar-epingle-btn[disabled] { cursor: progress; }

.sidebar-epingles .sidebar-sublink { padding-right: 8px; }
.sidebar-epingle-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (prefers-reduced-motion: reduce) {
  .sidebar-epingle-btn { transition: none; }
}
