/* ==========================================================================
   motion-kit — scroll reveal, idle float and marquee for static builds.
   No dependencies. ~4KB. Pairs with motion.js.

   Three rules the whole library is built on:

   1. Nothing rests in a hidden state. Every effect is a @keyframes driven by
      `animation`, never an `opacity: 0` / `transform` resting rule. Anything
      that kills animations — a screenshot harness injecting
      `*{animation:none!important}`, a print stylesheet, an old browser —
      resolves the page to its natural, fully visible layout.
   2. Everything is scoped to `html.mk`, which you set inline in <head> before
      first paint. With JS off or broken the page renders fully visible.
   3. `prefers-reduced-motion: reduce` opts out completely, in CSS and in JS.

   Boot snippet, first thing in <head>:
     <script>document.documentElement.classList.add(mk)</script>
   ========================================================================== */

:root {
  --mk-ease: cubic-bezier(.22, .61, .36, 1);
  --mk-dur: .68s;
  --mk-stagger: 70ms;
  --mk-rise: 30px;
  --mk-shift: 0px;
  --mk-scale: 1;
}

/* ---------------------------------------------------------------- reveal -- */

@keyframes mk-reveal {
  from {
    opacity: 0;
    transform: translate3d(var(--mk-shift), var(--mk-rise), 0) scale(var(--mk-scale));
  }
  to { opacity: 1; transform: none; }
}

.mk [data-reveal] {
  animation: mk-reveal var(--mk-dur) var(--mk-ease)
             calc(var(--mk-i, 0) * var(--mk-stagger)) both paused;
}
.mk [data-reveal].is-in { animation-play-state: running; }

/* `both` pins transform to the to-state for good, which silently beats every
   :hover transform on the element. Drop the animation once it has finished. */
.mk [data-reveal].is-done { animation: none; }

/* variants — `up` is the default and needs no rule */
.mk [data-reveal="down"]  { --mk-rise: -26px; }
.mk [data-reveal="left"]  { --mk-rise: 0px; --mk-shift: -34px; }
.mk [data-reveal="right"] { --mk-rise: 0px; --mk-shift: 34px; }
.mk [data-reveal="fade"]  { --mk-rise: 0px; }
.mk [data-reveal="zoom"]  { --mk-rise: 0px; --mk-scale: .94; }
.mk [data-reveal="sm"]    { --mk-rise: 16px; --mk-dur: .5s; }
.mk [data-reveal="lg"]    { --mk-rise: 48px; --mk-dur: .8s; }

/* ----------------------------------------------------------------- float -- */
/* No fill-mode and a delay longer than the reveal: during that delay the float
   contributes nothing, so the reveal owns `transform` until it has finished.
   The float then takes over from translateY(0) — exactly where it ended. */

@keyframes mk-float {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, var(--mk-float-to, -12px), 0); }
}

.mk [data-float] {
  animation: mk-float var(--mk-float-dur, 6s) ease-in-out
             var(--mk-float-delay, .8s) infinite;
}
/* the reveal has been dropped, so restart the float with no delay */
.mk [data-float].is-done {
  animation: mk-float var(--mk-float-dur, 6s) ease-in-out infinite;
}
/* both, while the reveal is still running */
.mk [data-float][data-reveal]:not(.is-done) {
  animation: mk-reveal var(--mk-dur) var(--mk-ease)
             calc(var(--mk-i, 0) * var(--mk-stagger)) both paused,
             mk-float var(--mk-float-dur, 6s) ease-in-out
             var(--mk-float-delay, .8s) infinite paused;
}
.mk [data-float][data-reveal].is-in { animation-play-state: running, running; }

/* a floating element cannot also take a :hover transform, so it pauses instead */
.mk [data-float]:hover { animation-play-state: paused; }

/* --------------------------------------------------------------- marquee -- */
/* The track carries two identical sets — motion.js clones the second and marks
   it aria-hidden. `--mk-marquee-shift` is -50% minus half the column gap, which
   motion.js measures, so the seam closes and the loop has no visible jump. */

.mk-marquee { position: relative; overflow: hidden; }
/* doiuse reports intrinsic-width here. That is about the stretch keyword in
   Firefox; max-content itself has been unprefixed since Chrome 46 / Firefox 66
   / Safari 11, all below any floor this library targets.
   Keep comments out of declaration blocks: doiuses tokenizer bails on them and
   silently stops checking the rest of the file. */
.mk-marquee__track {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  width: max-content;
  max-width: none;
}

@keyframes mk-marquee {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(var(--mk-marquee-shift, -50%), 0, 0); }
}

.mk .mk-marquee__track {
  animation: mk-marquee var(--mk-marquee-dur, 38s) linear infinite;
}
.mk-marquee--reverse .mk-marquee__track { animation-direction: reverse; }
.mk-marquee:hover .mk-marquee__track,
.mk-marquee:focus-within .mk-marquee__track { animation-play-state: paused; }

/* Opt-in edge fade. Gradient overlays rather than mask-image, which is only
   partially supported down at a Chrome 109 floor — set --mk-fade to the colour
   the row sits on. Only correct over a flat fill; skip it over a photo. */
.mk-marquee[data-fade]::before,
.mk-marquee[data-fade]::after {
  content: "";
  position: absolute; top: 0; bottom: 0; z-index: 1;
  width: var(--mk-fade-width, 64px);
  pointer-events: none;
}
.mk-marquee[data-fade]::before {
  left: 0;  background: linear-gradient(90deg, var(--mk-fade, #fff), transparent);
}
.mk-marquee[data-fade]::after {
  right: 0; background: linear-gradient(270deg, var(--mk-fade, #fff), transparent);
}

/* A wrapped grid cannot scroll. Set --mk-marquee-stop at the breakpoint where
   your track becomes a grid, or add .mk-marquee--off there. */
.mk-marquee--off { overflow: visible; }
.mk-marquee--off::before,
.mk-marquee--off::after { display: none; }
.mk-marquee--off .mk-marquee__track { animation: none; width: auto; flex-wrap: wrap; }
.mk-marquee--off [aria-hidden="true"] { display: none; }

/* -------------------------------------------------------------- opt out -- */
/* motion.js also tags nothing when this matches, so nothing is left paused. */

@media (prefers-reduced-motion: reduce) {
  .mk [data-reveal],
  .mk [data-float],
  .mk .mk-marquee__track { animation: none !important; }
  .mk-marquee { overflow: visible; }
  .mk-marquee::before, .mk-marquee::after { display: none; }
  .mk-marquee__track { flex-wrap: wrap; width: auto; }
  .mk-marquee [aria-hidden="true"] { display: none; }
}
