/* ==========================================================================
   HVR Confetti v01 — CSS
   --------------------------------------------------------------------------
   Self-contained confetti-burst styles. Every selector and @keyframes name
   is prefixed with `hvr-confetti-` so nothing here affects the rest of the
   site. Pair with hvr_confetti_v01.js and call launch_confetti().

   Requires a browser that supports the CSS cos()/sin() trig functions
   (Chrome 111+, Safari 15.4+, Firefox 128+).
   ========================================================================== */

/* Full-viewport overlay that holds the burst. Forced to LTR so positioning
   is predictable even on pages using dir="rtl". */
.hvr-confetti-stage {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 9999;
  direction: ltr;
}

/* A zero-size point from which particles emit. Its left/top are set in JS. */
.hvr-confetti-burst {
  position: absolute;
  width: 0;
  height: 0;
}

/* A single confetti piece — all per-particle values come in via CSS vars. */
.hvr-confetti-piece {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--hvr-c-w, 10px);
  height: var(--hvr-c-h, 14px);
  background: var(--hvr-c-color, #ff4fa1);
  border-radius: var(--hvr-c-radius, 2px);
  transform: translate(-50%, -50%) scale(0);
  filter: blur(0);
  animation: hvr-confetti-burst var(--hvr-c-duration, 2.8s)
             linear var(--hvr-c-delay, 0s) forwards;
  will-change: transform, opacity, filter;
}

/* The full flight: emerge → streak outward with motion blur → peak →
   tumble + fall off-screen. Each segment has its own timing function. */
@keyframes hvr-confetti-burst {
  0% {
    transform:
      translate(-50%, -50%)
      rotate(var(--hvr-c-start-rot, 0deg))
      scale(0, 0);
    opacity: 0;
    filter: blur(0);
    animation-timing-function: cubic-bezier(.2, .9, .3, 1);
  }
  4% {
    /* Emerged at center, oriented along travel direction */
    transform:
      translate(-50%, -50%)
      rotate(var(--hvr-c-start-rot, 0deg))
      scale(1, 1);
    opacity: 1;
    filter: blur(0);
    animation-timing-function: cubic-bezier(.2, .8, .35, 1);
  }
  10% {
    /* Peak velocity — radial streak + motion blur */
    transform:
      translate(
        calc(-50% + cos(var(--hvr-c-angle)) * var(--hvr-c-distance) * 0.55),
        calc(-50% + sin(var(--hvr-c-angle)) * var(--hvr-c-distance) * 0.55)
      )
      rotate(var(--hvr-c-start-rot, 0deg))
      scale(var(--hvr-c-streak-x, 4), 0.7);
    opacity: 1;
    filter: blur(var(--hvr-c-motion-blur, 3px));
    animation-timing-function: cubic-bezier(.3, .7, .4, 1);
  }
  20% {
    /* Peak position — shape and blur settle, free tumble takes over */
    transform:
      translate(
        calc(-50% + cos(var(--hvr-c-angle)) * var(--hvr-c-distance)),
        calc(-50% + sin(var(--hvr-c-angle)) * var(--hvr-c-distance))
      )
      rotate(var(--hvr-c-mid-rot, 180deg))
      scale(var(--hvr-c-mid-scale, 1), var(--hvr-c-mid-scale, 1));
    opacity: 1;
    filter: blur(0);
    animation-timing-function: cubic-bezier(.45, 0, .9, .55);
  }
  100% {
    /* Gravity takes over — drift sideways, fall off-screen */
    transform:
      translate(
        calc(-50% + cos(var(--hvr-c-angle)) * var(--hvr-c-distance)
                  + var(--hvr-c-drift, 0px)),
        calc(-50% + sin(var(--hvr-c-angle)) * var(--hvr-c-distance)
                  + var(--hvr-c-fall, 100vh))
      )
      rotate(var(--hvr-c-end-rot, 720deg))
      scale(var(--hvr-c-end-scale, 1), var(--hvr-c-end-scale, 1));
    opacity: 1;
    filter: blur(0);
  }
}
