/* Planar lattice network-spinner — shared styles for the header + footer marks.
 *
 * The mark is 8 <canvas> beam-bucket layers (rasterised once in network-spinner.js)
 * stacked over a static nodes canvas. The CSS animates each layer's opacity — a pure
 * compositor op on a cached bitmap, no per-frame re-rasterisation (a promoted <svg>
 * would re-tessellate its vectors every frame on WebKit). 8 buckets staggered 0.4s
 * apart over a 3.2s cycle. Colour is baked into the canvas (see network-spinner.js). */
.header-spinner,
.footer-spinner {
  position: relative;
  display: inline-block;
  width: 80px;
  height: 56px;
  flex-shrink: 0;
}
.header-spinner canvas,
.footer-spinner canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}
@media (max-width: 640px) {
  .header-spinner,
  .footer-spinner {
    width: 64px;
    height: 45px;
  }
}

@keyframes nw-pulse {
  0%, 100% { opacity: 0; }
  15% { opacity: 1; }
  40% { opacity: 0.55; }
  60% { opacity: 0; }
}
.header-spinner [class^="nw-l"],
.footer-spinner [class^="nw-l"] {
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .header-spinner [class^="nw-l"],
  .footer-spinner [class^="nw-l"] {
    will-change: opacity;
  }
  .nw-l0 { animation: nw-pulse 3.2s ease-in-out 0s infinite; }
  .nw-l1 { animation: nw-pulse 3.2s ease-in-out 0.4s infinite; }
  .nw-l2 { animation: nw-pulse 3.2s ease-in-out 0.8s infinite; }
  .nw-l3 { animation: nw-pulse 3.2s ease-in-out 1.2s infinite; }
  .nw-l4 { animation: nw-pulse 3.2s ease-in-out 1.6s infinite; }
  .nw-l5 { animation: nw-pulse 3.2s ease-in-out 2s infinite; }
  .nw-l6 { animation: nw-pulse 3.2s ease-in-out 2.4s infinite; }
  .nw-l7 { animation: nw-pulse 3.2s ease-in-out 2.8s infinite; }
}
@media (prefers-reduced-motion: reduce) {
  .header-spinner [class^="nw-l"],
  .footer-spinner [class^="nw-l"] {
    opacity: 0.5;
  }
}
