/* Pull-to-refresh indicator — the AJAW gear, spinning.

   Matched to Alibaba's, captured frame by frame while Giuliano dragged their
   home screen (docs/alibaba-mobile/raw/refresh2/). What they actually do:

     - the bare brand mark, centred, revealed in the gap the pull opens
     - NO button, NO disc, NO pill — just the logo on the page background
     - it fades in and scales up as the pull deepens
     - it spins while the feed reloads

   The first version here wrapped the gear in a white circle with a shadow,
   which read as a floating button rather than a brand moment. Gone.

   Lives outside #app (app.js rewrites that on every route) and is fixed to the
   viewport, so it survives navigation and never joins the page's scroll. */

.ptr {
  position: fixed;
  top: 10px;
  left: 50%;
  z-index: 60;
  opacity: 0;
  pointer-events: none;                 /* never blocks a tap underneath */
  transform: translate(-50%, 0);
  will-change: transform, opacity;
}
/* Only the snap-back is animated. While the finger is down the position is set
   directly from the touch, and a transition there would lag behind the thumb. */
.ptr.is-returning { transition: transform .26s cubic-bezier(.22,1,.36,1), opacity .26s ease; }

/* Alibaba's mark is pulled over white, so a bare logo reads fine. Ours is pulled
   over the purple campaign banner, where a purple gear on purple is invisible —
   the first attempt proved that in a screenshot. A frosted circle gives it a
   surface to sit on at any background, without becoming the floating white
   button this started as: it is translucent and blurred, not a chip. */
.ptr-disc {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .82);
  -webkit-backdrop-filter: blur(7px) saturate(1.4);
          backdrop-filter: blur(7px) saturate(1.4);
  box-shadow: 0 3px 12px rgba(9, 9, 11, .18);
}

.ptr-gear {
  display: block;
  width: 26px;
  height: 26px;
}

/* Past the threshold it reaches full size — the commit point is felt before the
   finger lifts, without adding a second element to say so. */
.ptr.is-ready .ptr-gear { transform-origin: 50% 50%; }

/* Released: the gear spins under its own power until the route finishes. */
.ptr.is-busy .ptr-gear {
  animation: ptr-spin .8s linear infinite;
  transform: none !important;           /* beats the inline pull rotation */
}
@keyframes ptr-spin { to { transform: rotate(360deg); } }

/* Desktop has native overscroll and no pull gesture; the script is touch-only
   but this keeps the element out of the way regardless. */
@media (min-width: 761px) { .ptr { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .ptr.is-busy .ptr-gear { animation-duration: 2.4s; }
  .ptr.is-returning { transition: opacity .2s ease; }
}
