/* Page loader (js/loader.js): a layer over the whole screen, in the page's own background, with
   the small OW in the middle and beams of light running its outline.
   Colors only through tokens. The --loader-* properties hold the brand colors of
   brand/seinovflow-mark.js; js/loader.js sets them on the layer. */

.loader {
  position: fixed;
  inset: 0;
  z-index: 90; /* over the page; under the entrance animation (100) */
  display: grid;
  place-items: center;
  background: var(--color-bg);
  opacity: 0;
  transition: opacity var(--duration-fast) linear; /* js/loader.js sets the same duration */
}

.loader.is-visible {
  opacity: 1;
}

.loader__ow {
  display: block;
  width: 4.25rem; /* 68px */
  height: auto;
  overflow: visible; /* the beams are drawn on the outline, half of them outside it */
}

/* The OW in the gradient of the logo, in the tones of the current scheme. */
.loader__stop--from {
  stop-color: var(--color-brand-from, var(--loader-flow-from));
}

.loader__stop--to {
  stop-color: var(--color-brand-to, var(--loader-flow-to));
}

/* Beams. Each one is a thin bright stroke (core) over a wide soft one (glow).
   On a light page the core is the theme's cyan washed with the sheet color, so it shines over
   the OW, and the glow carries the theme's brand tones, so the beam also shows over the page.
   These light values are also what browsers without light-dark() get (they keep the light
   tokens); there the brand tones may be missing, hence the accent as a spare. */
.loader {
  --loader-glow-forward: var(--color-brand-to, var(--color-accent));
  --loader-glow-backward: var(--color-brand-from, var(--color-accent));
  --loader-core: color-mix(
    in srgb,
    var(--color-brand-from, var(--color-accent)) 30%,
    var(--color-surface)
  );
  --loader-glow-opacity: 0.45;
}

/* On a dark page the beams are the light ones of the entrance animation. */
@supports (color: light-dark(currentColor, currentColor)) {
  .loader {
    --loader-glow-forward: light-dark(var(--color-brand-to), var(--loader-beam));
    --loader-glow-backward: light-dark(var(--color-brand-from), var(--loader-beam-back));
    --loader-core: light-dark(
      color-mix(in srgb, var(--color-brand-from) 30%, var(--color-surface)),
      var(--loader-beam-core)
    );
  }
}

.loader__beam-core {
  stroke: var(--loader-core);
}

.loader__beam-glow {
  stroke-opacity: var(--loader-glow-opacity);
}

.loader__beam--forward .loader__beam-glow {
  stroke: var(--loader-glow-forward);
}

.loader__beam--backward .loader__beam-glow {
  stroke: var(--loader-glow-backward);
}

/* Text for screen readers only. */
.loader__label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Less motion asked on the device: no beams; the OW stays still and breathes very softly. */
@media (prefers-reduced-motion: reduce) {
  .loader__beam {
    display: none;
  }

  .loader__fill {
    animation: loader-breathe 2.4s ease-in-out infinite;
  }
}

@keyframes loader-breathe {
  50% {
    opacity: 0.6;
  }
}
