/* Chargement : le cube du logo s'anime. Classe .cube-anim sur le <svg> (écran
   de chargement .cube-loader ET spinner en ligne <CubeSpinner>).
   - les six sommets s'allument tour à tour (le réseau qui se construit) ;
   - les lignes de texte de la face gauche s'écrivent (les documents lus) ;
   - les liens de la face droite circulent ; le cœur rouge (l'IA) pulse.
   L'écran n'apparaît qu'après 180 ms : un chargement rapide ne clignote pas. */
.cube-loader {
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg, #fff);
  opacity: 0; animation: cube-fade-in .25s ease-out .18s forwards;
}
.cube-loader svg { width: 72px; height: 72px; }
.cube-anim { overflow: visible; }

/* Spinner en ligne (<CubeSpinner>) : centré par défaut dans son bloc. */
.cube-spinner { display: flex; align-items: center; justify-content: center; margin: 1.5rem auto; }
.cube-spinner.inline { display: inline-flex; margin: 0; vertical-align: -0.15em; }

/* Mini (≤ 18 px, boutons) : cube simplifié à la couleur du texte, qui bascule
   par sixièmes de tour — à cette taille les nœuds et lignes seraient illisibles. */
.cube-mini { animation: cube-tumble 1.2s cubic-bezier(.6,0,.3,1) infinite; }
@keyframes cube-tumble {
  0%, 15% { transform: rotate(0deg); }
  50%, 65% { transform: rotate(60deg); }
  100% { transform: rotate(120deg); }
}

.cube-anim .cube-node { animation: cube-node 1.8s ease-in-out infinite; }
.cube-anim .cube-node-1 { animation-delay: .15s; }
.cube-anim .cube-node-2 { animation-delay: .3s; }
.cube-anim .cube-node-3 { animation-delay: .45s; }
.cube-anim .cube-node-4 { animation-delay: .6s; }
.cube-anim .cube-node-5 { animation-delay: .75s; }

.cube-anim .cube-line { stroke-dasharray: 1; animation: cube-write 1.8s ease-in-out infinite; }
.cube-anim .cube-line-2 { animation-delay: .2s; }
.cube-anim .cube-line-3 { animation-delay: .4s; }

.cube-anim .cube-link { stroke-dasharray: .25 .15; animation: cube-flow 1.2s linear infinite; }

.cube-anim .cube-core {
  transform-box: fill-box; transform-origin: center;
  animation: cube-core 1.8s ease-in-out infinite;
}

@keyframes cube-fade-in { to { opacity: 1; } }
@keyframes cube-node {
  0%, 60%, 100% { fill: var(--logo-node, #fff); }
  20% { fill: #E63946; }
}
@keyframes cube-write {
  0% { stroke-dashoffset: 1; }
  45%, 70% { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: -1; }
}
@keyframes cube-flow { to { stroke-dashoffset: -.4; } }
@keyframes cube-core {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.35); }
}

@media (prefers-reduced-motion: reduce) {
  .cube-anim .cube-node, .cube-anim .cube-line,
  .cube-anim .cube-link, .cube-anim .cube-core, .cube-mini { animation: none; }
  .cube-anim .cube-core { animation: cube-fade-in 1.8s ease-in-out infinite alternate; opacity: .4; }
}

.content-loader {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 280px;
}
