/*
 * SpaceNet — couche d'animation.
 *
 * Chargée seulement si les animations sont activées dans le Customizer.
 * Tout est en CSS : pas de SMIL (déprécié dans Edge, non contrôlable depuis
 * les réglages) et pas de JavaScript pour le mouvement lui-même.
 *
 * Trois déclencheurs, au choix dans Personnaliser → Animations :
 *   .sn-anim-on-hover  — au survol du bloc parent
 *   .sn-anim-on-view   — à l'entrée dans l'écran (classe posée par main.js)
 *   .sn-anim-on-always — en boucle
 *
 * Le brief demande des animations minimales : le défaut est « au survol »,
 * c'est-à-dire rien tant que le visiteur ne sollicite pas la page.
 */

/* ------------------------------------------------------------------ base */
/*
 * pathLength="1" est posé sur chaque tracé au rendu : quelle que soit la
 * longueur réelle du dessin, il se comporte comme s'il mesurait 1. Un seul
 * jeu de valeurs suffit donc pour les 26 icônes.
 */
.sn-anim--draw [pathLength] {
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
}

/* --------------------------------------------------------- déclencheurs */

/* Survol : l'ancêtre interactif porte le survol, pas l'icône seule —
   survoler une carte anime son icône, ce qui est le geste attendu. */
.sn-card:hover .sn-anim-on-hover.sn-anim--draw [pathLength],
.sn-iconbox:hover .sn-anim-on-hover.sn-anim--draw [pathLength],
.sn-anim-on-hover.sn-anim--draw:hover [pathLength] {
  animation: sn-draw var(--sn-anim-slow) ease forwards;
}

.sn-anim-on-view.sn-anim--draw.is-visible [pathLength] {
  animation: sn-draw var(--sn-anim-slow) ease forwards;
}

.sn-anim-on-always.sn-anim--draw [pathLength] {
  animation: sn-draw-loop calc(var(--sn-anim-slow) * 4) ease-in-out infinite;
}

/* Les animations de transformation partagent la même logique de déclenchement,
   mais portent sur le SVG entier plutôt que sur ses tracés. */
.sn-card:hover .sn-anim-on-hover:not(.sn-anim--draw),
.sn-iconbox:hover .sn-anim-on-hover:not(.sn-anim--draw),
.sn-anim-on-hover:not(.sn-anim--draw):hover,
.sn-anim-on-view.is-visible:not(.sn-anim--draw),
.sn-anim-on-always:not(.sn-anim--draw) {
  animation-duration: var(--sn-anim-slow);
  animation-timing-function: ease-in-out;
  animation-fill-mode: both;
}

.sn-anim-on-always:not(.sn-anim--draw) { animation-iteration-count: infinite; }

/* ------------------------------------------------------- comportements */
/* Chaque mouvement dit quelque chose du service qu'il illustre. */

/* Le bouclier se referme, la conformité se coche : le trait se dessine. */
@keyframes sn-draw {
  from { stroke-dashoffset: 1; opacity: .35; }
  to   { stroke-dashoffset: 0; opacity: 1; }
}
@keyframes sn-draw-loop {
  0%, 12%  { stroke-dashoffset: 1; opacity: .35; }
  45%, 88% { stroke-dashoffset: 0; opacity: 1; }
  100%     { stroke-dashoffset: -1; opacity: .35; }
}

/* Le nuage flotte. */
.sn-card:hover .sn-anim--float,
.sn-iconbox:hover .sn-anim--float,
.sn-anim--float.is-visible,
.sn-anim-on-always.sn-anim--float { animation-name: sn-float; }
@keyframes sn-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px); }
}

/* Le pouls de la santé. */
.sn-card:hover .sn-anim--beat,
.sn-iconbox:hover .sn-anim--beat,
.sn-anim--beat.is-visible,
.sn-anim-on-always.sn-anim--beat { animation-name: sn-beat; }
@keyframes sn-beat {
  0%, 100%  { transform: scale(1); }
  18%       { transform: scale(1.12); }
  32%       { transform: scale(1); }
  50%       { transform: scale(1.07); }
}

/* La puce d'IA pulse — un calcul en cours. */
.sn-card:hover .sn-anim--pulse,
.sn-iconbox:hover .sn-anim--pulse,
.sn-anim--pulse.is-visible,
.sn-anim-on-always.sn-anim--pulse { animation-name: sn-pulse; }
@keyframes sn-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .45; }
}

/* Les couches d'architecture se décalent. */
.sn-card:hover .sn-anim--stack,
.sn-iconbox:hover .sn-anim--stack,
.sn-anim--stack.is-visible,
.sn-anim-on-always.sn-anim--stack { animation-name: sn-stack; }
@keyframes sn-stack {
  0%, 100% { transform: translateY(0) scaleY(1); }
  50%      { transform: translateY(-2px) scaleY(1.06); }
}

/* La sensibilisation s'allume. */
.sn-card:hover .sn-anim--glow,
.sn-iconbox:hover .sn-anim--glow,
.sn-anim--glow.is-visible,
.sn-anim-on-always.sn-anim--glow { animation-name: sn-glow; }
@keyframes sn-glow {
  0%, 100% { filter: none; }
  50%      { filter: drop-shadow(0 0 6px var(--sn-cyan)); }
}

/* Le globe tourne — utilisé par le sélecteur de langue. */
.sn-anim--spin.is-visible,
.sn-anim-on-always.sn-anim--spin { animation-name: sn-spin; animation-timing-function: linear; animation-duration: calc(var(--sn-anim-slow) * 8); }
@keyframes sn-spin {
  to { transform: rotate(360deg); }
}

/* La flèche avance. */
.sn-card:hover .sn-anim--slide,
.sn-btn:hover .sn-anim--slide { animation-name: sn-slide; }
@keyframes sn-slide {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(3px); }
}

/* ---------------------------------------------- treillis animé du héros */
/*
 * Remplace l'image de datacenter : des impulsions parcourent le réseau.
 * Trois traits animés suffisent à donner vie à la section — au-delà, le
 * mouvement distrait du texte, qui est ce que le visiteur doit lire.
 */
.sn-lattice-live { display: block; width: 100%; height: 100%; }
.sn-lattice-live .sn-pulse {
  stroke-dasharray: 26 340;
  animation: sn-trace 7s linear infinite;
}
.sn-lattice-live .sn-pulse:nth-of-type(2) { animation-duration: 9s;  animation-delay: -2.5s; }
.sn-lattice-live .sn-pulse:nth-of-type(3) { animation-duration: 11s; animation-delay: -5s; }
@keyframes sn-trace {
  from { stroke-dashoffset: 366; }
  to   { stroke-dashoffset: 0; }
}
.sn-lattice-live .sn-node { animation: sn-node 4s ease-in-out infinite; transform-origin: center; }
.sn-lattice-live .sn-node:nth-of-type(even) { animation-delay: -1.6s; }
@keyframes sn-node {
  0%, 100% { opacity: .35; }
  50%      { opacity: 1; }
}

/* ------------------------------------------------------------- respect */
/*
 * Non négociable : la préférence système coupe tout, quel que soit le
 * réglage choisi dans le Customizer. Un visiteur sujet au mal des transports
 * ou à l'épilepsie photosensible n'a pas à subir le choix de l'éditeur.
 */
@media (prefers-reduced-motion: reduce) {
  .sn-anim,
  .sn-anim [pathLength],
  .sn-lattice-live .sn-pulse,
  .sn-lattice-live .sn-node {
    animation: none !important;
    stroke-dasharray: none !important;
    stroke-dashoffset: 0 !important;
    opacity: 1 !important;
  }
}

/* ---------- apparition au défilement ----------
   Les blocs montent de quelques pixels en se révélant. L'effet est discret :
   il guide la lecture sans faire attendre le visiteur. */
.sn-reveal { opacity: 0; transform: translateY(16px); }
.sn-reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity .55s cubic-bezier(.2,.6,.2,1), transform .55s cubic-bezier(.2,.6,.2,1);
}

/* ---------- figures décoratives ---------- */
.sn-fig-sweep { stroke-dasharray: .18 1; animation: sn-sweep 9s linear infinite; transform-origin: center; }
@keyframes sn-sweep { to { transform: rotate(360deg); } }
.sn-fig-node { animation: sn-fig-pulse 3.2s ease-in-out infinite; transform-origin: center; }
@keyframes sn-fig-pulse { 0%,100% { opacity: .35; } 50% { opacity: 1; } }
.sn-fig-line { stroke-dasharray: 1; stroke-dashoffset: 1; animation: sn-fig-draw 2.4s ease forwards; }
@keyframes sn-fig-draw { to { stroke-dashoffset: 0; } }
.sn-fig-step { opacity: 0; animation: sn-fig-in .6s ease forwards; }
@keyframes sn-fig-in { to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .sn-reveal { opacity: 1 !important; transform: none !important; }
  .sn-fig-sweep, .sn-fig-node, .sn-fig-line, .sn-fig-step {
    animation: none !important; stroke-dashoffset: 0 !important; opacity: 1 !important;
  }
}

/* ---------- fond animé du site ----------
   Chargé avec cette feuille, donc seulement si les animations sont actives.
   Les durées sont longues (40 s à 2 min) : le décor bouge sans jamais attirer
   l'œil pendant la lecture. Seuls `transform` et `opacity` sont animés. */

.sn-bg__grid { animation: sn-bg-drift 48s linear infinite; }
@keyframes sn-bg-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(64px, 64px, 0); } /* un pas de trame exactement : la boucle est invisible */
}

.sn-bg__glow--a { animation: sn-bg-float-a 34s ease-in-out infinite; }
.sn-bg__glow--b { animation: sn-bg-float-b 42s ease-in-out infinite; }
@keyframes sn-bg-float-a {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(6vw, 5vh, 0) scale(1.12); }
}
@keyframes sn-bg-float-b {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1.08); }
  50%      { transform: translate3d(-7vw, -4vh, 0) scale(1); }
}

.sn-bg__scan { animation: sn-bg-scan 22s ease-in-out infinite; }
@keyframes sn-bg-scan {
  0%, 70%, 100% { opacity: 0; transform: translate3d(-30%, 0, 0); }
  35%           { opacity: 1; transform: translate3d(30%, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .sn-bg__grid, .sn-bg__glow, .sn-bg__scan { animation: none !important; }
  .sn-bg__scan { opacity: 0 !important; }
}

/* SpaceNet 8.0 hero decision map: slow, decorative motion only. */
.sn-risk-map__ring--a { animation: sn-risk-ring-a 16s linear infinite; }
.sn-risk-map__ring--b { animation: sn-risk-ring-b 24s linear infinite reverse; }
.sn-risk-map__halo { animation: sn-risk-halo 7s ease-in-out infinite; }
.sn-risk-map__node { animation: sn-risk-node 6s ease-in-out infinite; }
.sn-risk-map__node--gov { animation-delay: -1.5s; }
.sn-risk-map__node--res { animation-delay: -3s; }
.sn-risk-map__node--dec { animation-delay: -4.5s; }

@keyframes sn-risk-ring-a {
  to { transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes sn-risk-ring-b {
  to { transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes sn-risk-halo {
  0%, 100% { opacity: .7; transform: scale(.96); }
  50% { opacity: 1; transform: scale(1.08); }
}
@keyframes sn-risk-node {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); }
}

@media (prefers-reduced-motion: reduce) {
  .sn-risk-map__ring,
  .sn-risk-map__halo,
  .sn-risk-map__node { animation: none !important; }
}

/* SpaceNet 8.0 LTS — restrained signature motion. */
.sn-service-signature__ring--b { animation: sn-v8-orbit 28s linear infinite; }
.sn-service-signature__node { animation: sn-v8-node 5.6s ease-in-out infinite; }
.sn-service-signature__node--b { animation-delay: -1.8s; }
.sn-service-signature__node--c { animation-delay: -3.6s; }
@keyframes sn-v8-orbit { to { transform: translate(-50%, -50%) rotate(360deg); } }
@keyframes sn-v8-node { 0%,100% { opacity: .45; } 50% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .sn-service-signature__ring--b,
  .sn-service-signature__node { animation: none !important; }
}
