    /* the order after a drop, from the store the page publishes — which is
       what the backend kept, the page having re-read its rows by now */
    "playlist-dragged": (i) => i.plOrder === "Track 4|Track 1|Track 2|Track 3|One More Time|ID" && i.plfirst.startsWith("Track 4"),
    "playlist-dragged-back": (i) => i.plOrder === "Track 1|Track 2|Track 3|Track 4|One More Time|ID" && i.plfirst.startsWith("Track 1"),
    /* a filtered list's visible order is not the stored one, so the drag is
       refused outright and the note under the field says why */
    "playlist-drag-filtered": (i) => i.plOrder === "Track 1|Track 2|Track 3|Track 4|One More Time|ID" && i.plrows === 4 && /Clear the search/.test(i.plNote),
    /* pressed and released without moving: still the row's sheet */
    "playlist-drag-held": (i) => i.half.includes("up") && /Remove from playlist/.test(i.halfText),
    /* the optimistic order snapped back, and the app said so */
    "playlist-drag-refused": (i) => i.plOrder === "Track 1|Track 2|Track 3|Track 4|One More Time|ID" && !!i.toast,
    "queue-drag-arm": (i) => { globalThis.__q0 = i.qOrder; return i.qrows >= 3 && !!i.qOrder; },
    "queue-dragged": (i) => { const a = String(globalThis.__q0 || "").split("|"); if (a.length < 3) return false; const [x] = a.splice(0, 1); a.splice(2, 0, x); return i.qOrder === a.join("|"); },
    "queue-dragged-back": (i) => !!i.qOrder && i.qOrder === globalThis.__q0,
