/**
 * Cursor Trail — front-end.
 *
 * Everything is pointer-events:none and fixed-position so the trail can never
 * intercept a click or affect layout. The container is painted on its own
 * layer, so spawning items does not force the page to re-layout.
 */

.da-cursor-trail {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  /* layout + paint, deliberately not `strict`: that also applies size
     containment, and betting the container's dimensions on inset:0 surviving
     it is not worth the risk. These two give the isolation that matters —
     trail repaints cannot invalidate page layout.

     No will-change here: the container never animates, and a permanent layer
     hint on a full-viewport element costs memory for nothing. The items
     promote themselves via translate3d instead. */
  contain: layout paint;
}

.da-cursor-trail__item {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  pointer-events: none;
  /* Centred on the pointer, and scaled down as it dies. translate3d promotes
     each item so the fade runs on the compositor rather than the main thread. */
  transform: translate3d(-50%, -50%, 0) scale(1);
  transition-property: opacity, transform;
  transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}

/* The live state is the resting state; removing the class is what animates.
   Items start visible at their spawn point and fade to nothing. */
.da-cursor-trail__item.is-live {
  opacity: 0 !important;
  transform: translate3d(-50%, -50%, 0) scale(0.6);
}

/* GSAP owns opacity, transform and z-index on these items: it writes them
   inline on every spawn (position via x/y, centring via xPercent/yPercent, and
   an incrementing z-index so newer items overlap older ones).

   The transition therefore has to go. Left on, CSS would re-interpolate every
   single tween write, and the two would visibly fight over the same
   properties. The base transform goes for the same reason — it is overwritten
   on first spawn, so declaring it here only misleads. */
.da-cursor-trail.is-gsap .da-cursor-trail__item {
  transition: none;
  transform: none;
}

/* ── Image ──────────────────────────────────────────────────────────────── */

.da-cursor-trail__item--image img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 6px;
  /* A dragged image would break the illusion and hijack the pointer. */
  -webkit-user-drag: none;
  user-select: none;
}

/* ── Dot ────────────────────────────────────────────────────────────────── */

.da-cursor-trail__item--dot {
  border-radius: 50%;
}

/* ── Shapes ─────────────────────────────────────────────────────────────── */

.da-cursor-trail__item--shape[data-shape='circle'] {
  border-radius: 50%;
}

.da-cursor-trail__item--shape[data-shape='square'] {
  border-radius: 4px;
}

/* clip-path rather than the border trick: it respects the element's real box,
   so the configured size stays honest. */
.da-cursor-trail__item--shape[data-shape='triangle'] {
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  border-radius: 0;
}

/* ── Text ───────────────────────────────────────────────────────────────── */

.da-cursor-trail__item--text {
  width: auto !important;
  white-space: nowrap;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  user-select: none;
}

/* The effect is decorative; anyone asking for less motion should not get a
   swarm of elements following their pointer. The script bails too — this is
   the belt to that braces, for a cached page whose script did not run. */
@media (prefers-reduced-motion: reduce) {
  .da-cursor-trail {
    display: none;
  }
}
