/* ═══════════════════════════════════════════════════════════════
   CONFETTI — paper across the whole page, for a job well finished.

   Shared, like system-confirm: one layer over the viewport, thrown by
   confettiBurst() from assets/js/components/confetti.js. Every piece is
   a flat strip of paper — no rounded shapes — cut to size and coloured
   at runtime, so the only thing living here is the fall.

   Two elements per piece, because one cannot do both jobs: the outer
   drops at a steady rate, the inner flutters side to side across it.
   Sharing a transform would force the sway's easing onto the fall and
   the paper would visibly stall at the edge of every sway.
   ═══════════════════════════════════════════════════════════════ */

.cfti {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  pointer-events: none;
  overflow: hidden;
  contain: layout paint style;
}

/* The drop. Linear — paper reaches its speed almost at once and holds it,
   so anything eased reads as falling through treacle. */
.cfti__p {
  position: absolute;
  top: -28px;
  display: block;
  will-change: transform, opacity;
  animation: cfti-fall var(--cfti-d, 3000ms) linear var(--cfti-dl, 0ms) both;
}

@keyframes cfti-fall {
  0%   { opacity: 1; transform: translate3d(0, 0, 0); }
  86%  { opacity: 1; }
  100% { opacity: 0; transform: translate3d(0, var(--cfti-fall, 900px), 0); }
}

/* The flutter. One alternating pass carries the sway, the turn and the
   pinch to edge-on together — paper tips back and forth on the air rather
   than spinning like a wheel, and each piece runs it at its own rate so
   the page never falls into step. */
.cfti__f {
  display: block;
  will-change: transform;
  backface-visibility: hidden;
  animation: cfti-flutter var(--cfti-sd, 1300ms) ease-in-out var(--cfti-dl, 0ms) infinite alternate both;
}

@keyframes cfti-flutter {
  from {
    transform: translate3d(calc(var(--cfti-x, 30px) * -1), 0, 0)
               rotate(calc(var(--cfti-r, 60deg) * -1))
               scaleY(var(--cfti-flip, .35));
  }
  to {
    transform: translate3d(var(--cfti-x, 30px), 0, 0)
               rotate(var(--cfti-r, 60deg))
               scaleY(1);
  }
}

/* Nobody who asked for stillness gets paper thrown at them. The script bails
   too — this is the belt to that pair of braces. */
@media (prefers-reduced-motion: reduce) {
  .cfti { display: none; }
}
