/* Swipe to uncover a confirm. The gesture is in core/js/swipe.js.
 *
 * Two layers in one item. `.swipe-behind` is the confirm, fixed against the
 * trailing edge; `.swipe-face` carries the content and translates to uncover
 * it. The face is OPAQUE and paints its own background, so the confirm is
 * genuinely hidden under it rather than merely sitting behind a transparent
 * sheet.
 */

.swipe-item {
  position: relative;
  overflow: hidden;
}

.swipe-behind {
  position: absolute;
  inset: 0 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-inline: .75rem;
  /* A tinted slot rather than bare page behind the row, so what the swipe
     uncovers reads as a dismiss zone at a glance instead of a hole. */
  background: rgba(var(--bs-danger-rgb, 220, 53, 69), .12);
  /* Hidden until the item is actually being moved. The face is opaque and
     should cover this on its own, but "should" is how the first version of
     this pattern shipped a red Dismiss painted across every closed row: the
     face's background token resolved to nothing.
     opacity rather than visibility/display on purpose - the button stays in
     the accessibility tree, which is why it lives in the markup instead of
     being injected by the gesture, and keyboard activation does not go through
     pointer-events so Enter still works. Whether it is also a TAB STOP is the
     caller's call: where the gesture is the only route to the action it should
     be, and where a visible control does the same job it should not. */
  opacity: 0;
  pointer-events: none;
}

.swipe-item.swipe-dragging .swipe-behind,
.swipe-item.swipe-open .swipe-behind {
  opacity: 1;
  pointer-events: auto;
}

.swipe-face {
  position: relative;
  /* --bs-paper-bg is the palette's own surface token. NOT --bs-card-bg, which
     Bootstrap's .card redefines locally to the vendor colour, so it means one
     thing read from html and another read from inside a card; and NOT
     --bs-list-group-bg, which is defined AND EMPTY, and an empty custom
     property is a valid value, so var()'s fallback never fires. A caller whose
     item has its own colour overrides this. */
  background: var(--bs-paper-bg, var(--bs-card-bg, #fff));
  transform: translateX(0);
  transition: transform .22s ease;
  /* The browser keeps vertical scrolling; only horizontal reaches the script.
     Without this the first vertical drag on an item scrolls nothing. */
  touch-action: pan-y;
}

/* While a finger is down the script sets --swipe-dx and the transition comes
   off, so the face tracks the thumb rather than lagging behind it. */
.swipe-item.swipe-dragging .swipe-face {
  transition: none;
  transform: translateX(var(--swipe-dx, 0px));
}

.swipe-item.swipe-open .swipe-face {
  transform: translateX(calc(-1 * var(--swipe-reveal, 7.5rem)));
}
[dir="rtl"] .swipe-item.swipe-open .swipe-face {
  transform: translateX(var(--swipe-reveal, 7.5rem));
}
[dir="rtl"] .swipe-behind {
  inset: 0 auto 0 0;
  justify-content: flex-start;
}

/* Leaving: collapse as well as fade, so anything below does not jump up a beat
   before the gap closes. */
.swipe-item.swipe-going {
  opacity: 0;
  transform: translateX(-100%);
  transition: opacity .18s ease, transform .18s ease;
}

/* Where there is a real mouse the gesture does not exist: the face never moves
   and the hidden confirm stays hidden.
   Gated on the INPUT rather than on width, which is the question actually
   being asked. A tablet at 1024px has no mouse and wants the gesture; a
   desktop window narrowed to 700px has one and does not. Width answers
   neither. */
@media (hover: hover) and (pointer: fine) {
  .swipe-face {
    transform: none !important;
    touch-action: auto;
  }
  .swipe-behind {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .swipe-face,
  .swipe-item.swipe-going {
    transition: none;
  }
}
