/* ══════════════════════════════
   THÈME PRINCIPAL — anciennement la refonte bêta, promue thème par défaut.
   Chargé après style.css : ces règles priment sur les déclarations de base
   (boutons en pilule, ombres portées, hover cartes, animations).
══════════════════════════════ */

:root {
  --card-radius: 14px;
}

/* ── Boutons en pilule ── */
.btn {
  border-radius: 999px;
}

/* ── Ombres portées : plus sombres/marquées pour rester visibles même sur fond quasi noir ── */
.media-card,
.stat-card,
.modal,
.auth-box,
.search-box,
.toast {
  box-shadow: 0 4px 10px rgba(0,0,0,0.55), 0 14px 32px rgba(0,0,0,0.5);
}
.navbar {
  box-shadow: 0 4px 18px rgba(0,0,0,0.55);
}
.btn-primary {
  box-shadow: 0 2px 8px rgb(var(--accent-rgb) / 0.3);
}

/* ── Cartes média : le titre/la note glissent par-dessus le poster au survol ──
   Uniquement sur les appareils avec un vrai pointeur (souris) : sur tactile,
   :hover ne se déclenche jamais avant le tap, ce qui rendrait les infos illisibles.
   Sur mobile/tactile, la carte garde son affichage classique (infos toujours visibles). */
@media (hover: hover) and (pointer: fine) {
  .media-card {
    overflow: hidden;
  }
  .media-card-body {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    background: linear-gradient(180deg, transparent, rgba(0,0,0,0.55) 30%, rgba(0,0,0,0.92) 100%);
    padding: 24px 12px 12px;
    transform: translateY(100%);
    opacity: 0;
    transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.2s ease;
    pointer-events: none;
  }
  .media-card:hover .media-card-body {
    transform: translateY(0);
    opacity: 1;
    pointer-events: auto;
  }
  .media-card {
    transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.25s ease, border-color 0.25s ease;
  }
  .media-card:hover {
    transform: scale(1.06) translateY(-6px);
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent), 0 0 26px 6px rgb(var(--accent-rgb) / 0.55), 0 16px 36px rgba(0,0,0,0.5);
    z-index: 2;
  }
}

/* ── Animation d'ouverture des popups/modales ── */
.modal-overlay.open {
  animation: redesignOverlayFade 0.15s ease both;
}
.modal-overlay.open .modal {
  animation: redesignModalPop 0.18s cubic-bezier(0.16, 1, 0.3, 1) both;
}
/* ── Apparition douce d'un nouveau message dans un fil de conversation (tickets) ── */
.ticket-msg-in {
  animation: ticketMsgIn 0.25s ease both;
}
@keyframes ticketMsgIn {
  from { opacity: 0; transform: translateY(6px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .ticket-msg-in { animation: none; }
}

@keyframes redesignOverlayFade {
  from { background: rgba(0,0,0,0); }
  to { background: rgba(0,0,0,0.6); }
}
@keyframes redesignModalPop {
  from { opacity: 0; transform: scale(0.96) translateY(8px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

/* ── Transition d'entrée de page : fondu + léger glissement, non bloquant ── */
.main {
  animation: redesignPageEnter 0.2s ease both;
}
@keyframes redesignPageEnter {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ── Cartes en cascade : chacune glisse et apparaît avec un léger décalage ── */
.media-card {
  /* "backwards" (pas "both") : une fois l'animation terminée, le cascade CSS normal
     reprend la main sur transform, au lieu de rester bloqué sur la valeur finale de
     l'animation — nécessaire pour que le thème 3D puisse ensuite piloter transform. */
  animation: redesignCardIn 0.35s cubic-bezier(0.2, 0.8, 0.2, 1) backwards;
}
.media-card:nth-child(1) { animation-delay: 0.02s; }
.media-card:nth-child(2) { animation-delay: 0.04s; }
.media-card:nth-child(3) { animation-delay: 0.06s; }
.media-card:nth-child(4) { animation-delay: 0.08s; }
.media-card:nth-child(5) { animation-delay: 0.1s; }
.media-card:nth-child(6) { animation-delay: 0.12s; }
.media-card:nth-child(7) { animation-delay: 0.14s; }
.media-card:nth-child(8) { animation-delay: 0.16s; }
.media-card:nth-child(9) { animation-delay: 0.18s; }
.media-card:nth-child(10) { animation-delay: 0.2s; }
.media-card:nth-child(11) { animation-delay: 0.22s; }
.media-card:nth-child(12) { animation-delay: 0.24s; }
.media-card:nth-child(13) { animation-delay: 0.26s; }
.media-card:nth-child(14) { animation-delay: 0.28s; }
.media-card:nth-child(15) { animation-delay: 0.3s; }
.media-card:nth-child(16) { animation-delay: 0.32s; }
.media-card:nth-child(17) { animation-delay: 0.34s; }
.media-card:nth-child(18) { animation-delay: 0.36s; }
@keyframes redesignCardIn {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ── Indicateur de l'onglet actif : glisse d'un onglet à l'autre au lieu de sauter ── */
.nav-links {
  position: relative;
}
.nav-indicator {
  position: absolute;
  top: 0; bottom: 0; left: 0;
  background: var(--bg3);
  border-radius: 8px;
  width: 0;
  opacity: 0;
  transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), width 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.15s ease;
  pointer-events: none;
  z-index: 0;
}
.nav-links .nav-link {
  position: relative;
  z-index: 1;
}
.nav-links .nav-link.active {
  background: transparent;
}

/* ══════════════════════════════
   INTERFACE 3D — promue thème principal pour tout le monde le 2026-08-10.
   Étagère qui s'incline vers la souris + spot lumineux qui la suit (public/js/theme.js).
══════════════════════════════ */
.media-grid {
  --tilt-rx: 0deg;
  --tilt-ry: 0deg;
}
.media-card {
  --card-tilt-rx: 0deg;
  --card-tilt-ry: 0deg;
  /* Défauts déclarés ici (ancêtre), PAS sur .media-card-status : une custom property
     déclarée directement sur l'élément qui la consomme court-circuite l'héritage
     depuis le parent, même à faible spécificité — bug rencontré en testant ce fix. */
  --badge-shift-x: 0px;
  --badge-shift-y: 0px;
  transform: perspective(1000px) rotateX(calc(var(--tilt-rx) + var(--card-tilt-rx))) rotateY(calc(var(--tilt-ry) + var(--card-tilt-ry)));
}
/* Badge de statut : fond sombre + flou pour rester lisible sur n'importe quel poster
   (au lieu du fond juste teinté à faible opacité, qui se fond dans un poster clair).
   Le "flottement" est un décalage translate(x,y) exagéré par rapport à la position du
   curseur sur la carte (--badge-shift-x/y, posés par public/js/theme.js sur .media-card
   et hérités ici) — PAS un vrai translateZ : sur un enfant, translateZ n'a d'effet que si
   un ANCÊTRE porte une vraie propriété CSS "perspective" (pas juste perspective() dans son
   propre transform), ce qui n'est pas le cas ici. Le translate(x,y) imite le même effet de
   couche "plus proche qui bouge plus", de façon fiable. */
.media-card-status {
  transform: translate(var(--badge-shift-x), var(--badge-shift-y));
}
/* Même flottement sur le titre/note qui glissent au survol. Appliqué au titre et à la
   meta directement (pas à .media-card-body, qui porte déjà une transition sur transform
   pour l'animation de glissement) : combiner les deux dans la même transition aurait
   réintroduit le bug de latence déjà rencontré avec la carte et le badge (une transition
   qui rejoue à chaque mousemove combat la mise à jour instantanée). */
.media-card-title,
.media-card-meta,
.media-card-platforms,
.media-card-next-ep,
.media-card-social-actions {
  transform: translate(var(--badge-shift-x), var(--badge-shift-y));
}
/* will-change: transform n'est PAS déclaré ici en statique (comme il l'était avant) :
   posé en permanence sur .media-card et tous ses enfants, ça crée une couche GPU par
   carte visible en continu (dizaines, voire centaines sur Découvrir/Ma liste) même sans
   interaction — coût mémoire/fluidité pour rien. will-change est appliqué/retiré par
   public/js/theme.js uniquement sur la carte activement survolée. */
.media-card-status .badge {
  background: rgba(10, 10, 12, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.4);
}
.theme3d-spotlight {
  position: fixed;
  width: 480px;
  height: 480px;
  border-radius: 50%;
  left: 0;
  top: 0;
  /* Positionné via transform (posé par public/js/theme.js à chaque mousemove), jamais via
     left/top : changer left/top invalide la mise en page (coûteux, potentiellement un
     recalcul synchrone à chaque pixel de mouvement de souris) alors que transform ne coûte
     qu'un recomposite GPU. */
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgb(var(--accent-rgb) / 0.16), transparent 70%);
  pointer-events: none;
  z-index: 5;
  opacity: 0;
  transition: opacity 0.2s ease;
}
@media (hover: hover) and (pointer: fine) {
  .media-card:hover {
    transform: perspective(1000px) rotateX(calc(var(--tilt-rx) + var(--card-tilt-rx))) rotateY(calc(var(--tilt-ry) + var(--card-tilt-ry))) translateZ(23px) scale(1.05) translateY(-4px);
    box-shadow: 0 0 0 1px var(--accent), 0 0 30px 8px rgb(var(--accent-rgb) / 0.5), 0 22px 40px rgba(0, 0, 0, 0.55);
  }
}
@media (prefers-reduced-motion: reduce) {
  .theme3d-spotlight {
    display: none;
  }
}

/* ══════════════════════════════
   Fantôme "rien ici" — page 404 et profil introuvable/privé.
   Yeux qui regardent à droite/gauche puis choc (pupilles dilatées, bouche ouverte),
   inclinaison 3D à la souris comme les cartes.
══════════════════════════════ */
.ghost404 {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: 60px 24px; perspective: 900px;
}
.ghost404-bubble-wrap {
  position: relative;
  margin-bottom: 8px;
  opacity: 0;
  animation: ghostBubbleIn 0.5s 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.ghost404-bubble {
  background: var(--bg3);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 10px 18px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  max-width: 320px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}
.ghost404-bubble::after {
  content: '';
  position: absolute;
  left: 50%; bottom: -7px; transform: translateX(-50%) rotate(45deg);
  width: 14px; height: 14px;
  background: var(--bg3);
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.ghost404-holder {
  width: 180px; height: 200px;
  animation: ghostFloatY 3.2s ease-in-out infinite;
}
.ghost404-tilt {
  width: 100%; height: 100%;
  transition: transform 0.15s ease-out;
  filter: drop-shadow(0 18px 22px rgba(0, 0, 0, 0.5)) drop-shadow(0 0 30px rgb(var(--accent-rgb) / 0.18));
}
.ghost404-eye, .ghost404-pupil, .ghost404-mouth {
  transform-box: fill-box;
  transform-origin: center;
}
.ghost404-eye { animation: ghostEyeWiden 4.5s ease-in-out infinite; }
.ghost404-pupil { animation: ghostPupilMove 4.5s ease-in-out infinite; }
.ghost404-mouth { animation: ghostMouthPop 4.5s ease-in-out infinite; }

.ghost404 h2 { font-size: 1.4rem; font-weight: 700; margin: 22px 0 6px; text-wrap: balance; }
.ghost404 p.ghost404-sub { color: var(--muted); font-size: 0.9rem; margin: 0 0 22px; max-width: 320px; }

@keyframes ghostFloatY {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-10px); }
}
@keyframes ghostBubbleIn {
  from { opacity: 0; transform: translateY(6px) scale(0.94); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
/* Le fantôme regarde à gauche puis à droite (pupilles + yeux ensemble), puis se fige,
   choqué : pupilles dilatées, yeux écarquillés, bouche ouverte en "O" — avant de se
   détendre et de recommencer la boucle. */
@keyframes ghostPupilMove {
  0%, 8% { transform: translateX(0) scale(1); }
  20%, 30% { transform: translateX(-4.5px) scale(1); }
  42%, 52% { transform: translateX(4.5px) scale(1); }
  60% { transform: translateX(0) scale(1); }
  66%, 80% { transform: translateX(0) scale(1.45); }
  92%, 100% { transform: translateX(0) scale(1); }
}
@keyframes ghostEyeWiden {
  0%, 60% { transform: scale(1); }
  66%, 80% { transform: scale(1.18, 1.3); }
  92%, 100% { transform: scale(1); }
}
@keyframes ghostMouthPop {
  0%, 60% { opacity: 0; transform: scale(0.5); }
  66%, 80% { opacity: 1; transform: scale(1); }
  92%, 100% { opacity: 0; transform: scale(0.5); }
}

@media (prefers-reduced-motion: reduce) {
  .ghost404-holder, .ghost404-eye, .ghost404-pupil, .ghost404-mouth, .ghost404-bubble-wrap {
    animation: none;
    opacity: 1;
  }
}
