/* =============================================================================
   101-friend-shelf-return.css — v16.153
   THE PAGE YOU CAME FROM, WAITING UNDER A FRIEND'S SHELF. ONE OWNER.

   WHAT THIS FILE IS FOR
   Everything that makes backing out of a viewed shelf reveal the surface you
   opened it from — the frozen snapshot frame, the one state class that uncovers
   it, and the gesture reservation the swipe needs. Three rules. Nothing else in
   the stylesheet stack touches them.

   ---------------------------------------------------------------------------
   WHY THE SNAPSHOT EXISTS AT ALL

   Opening someone's shelf REPURPOSES the live views: #mylist-view is refilled
   with their data and the body is restyled as `viewing-other-user`. The page you
   came from is therefore gone by the time you swipe back — there is nothing left
   to slide off and reveal. js/16 takes a static copy of the source route into an
   iframe first (prepareFriendShelfReturnUnderlay), which keeps that route's own
   body classes and CSS intact in a separate document while the live one changes
   underneath it.

   ---------------------------------------------------------------------------
   THE STACKING RULE, AND WHY IT IS NOW ONE LINE INSTEAD OF THREE

   Until v16.153 the frame sat ON TOP of the app at z-index 2140, hidden, and
   the reveal worked by shoving #app-container ABOVE it (z-index 2141) and
   making it transparent. Two elements, three properties, and a full-screen
   iframe permanently over the live app — which is exactly what broke:

     • `visibility: hidden` meant the snapshot was laid out but never painted,
       so it only started rasterising on the frame it was revealed. The reveal
       was a black slide (the frame's own fill) racing a 300ms drag.

     • Keeping it painted instead put a LIVE full-screen frame over the app, and
       WKWebView gives a live frame with an overflowing document its own native
       UIScrollView. That scroller is native, not CSS, so `pointer-events: none`
       on the <iframe> never reached it: it swallowed both vertical scrolling
       and the left-edge swipe on every viewed shelf.

   The frame is now a SIBLING BEFORE #app-container and carries no z-index at
   all. While a shelf is being viewed, 35-shelf-banner.css already makes
   #app-container `position: relative` — two positioned boxes at z-index auto
   paint in tree order, so the app is above the frame by construction, and the
   frame is covered by the one opaque surface on the page: #app-container's own
   background. (The header and #mylist-view are both transparent on a viewed
   shelf — see 35 — so app-container IS the ground.)

   That makes the reveal a single property change on a single element: uncover
   the frame by making the ground transparent. No z-index, no visibility flip on
   the moving parts, and nothing of ours is ever above the app to intercept a
   gesture.

   ---------------------------------------------------------------------------
   `is-warm` IS A PAINT GATE, NOT A VISIBILITY TOGGLE

   The frame is built while the friend's data is still loading, and at that
   moment the body is still on the ORIGINAL route, where #app-container may be
   `position: static` — an unpositioned box paints BELOW a positioned sibling,
   so an already-visible frame would flash over the page you are leaving.

   So it stays `visibility: hidden` for exactly as long as that is true, and js/16
   adds `is-warm` once the shelf has mounted and `viewing-other-user` is on the
   body — the point from which app-container is guaranteed to cover it. From
   there it is a normal painted layer with time to rasterise, so the reveal is
   already-drawn pixels whenever the finger arrives. There is deliberately no
   second class for the reveal itself; the ground moving out of the way is the
   whole mechanism.
   ============================================================================= */

.friend-shelf-return-underlay-frame {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  margin: 0;
  padding: 0;
  /* Matches the app's ground, so the single frame the snapshot needs to lay
     itself out is this colour rather than white. */
  background: #0E0E0E;
  /* Belt to the `scrolling="no"` attribute and the snapshot's own
     `overflow: hidden` (js/16): nothing here is interactive, ever. */
  pointer-events: none;
  /* Hidden until the app is guaranteed to be painting above it — see above. */
  visibility: hidden;
  /* The frame never moves, never resizes and has no descendants the page cares
     about, so it can be taken out of the rest of the page's layout and paint
     work entirely. */
  contain: strict;
}

.friend-shelf-return-underlay-frame.is-warm {
  visibility: visible;
}

/* THE REVEAL. #app-container carries the theme's opaque page fill
   (17-auth-flow-setup.css) and is the only thing covering the frame, so
   dropping that fill for the length of the departure is the entire effect.

   v16.154: this works because BOTH of 17's ground rules exclude this state at
   the source (`#app-container:not(.friend-shelf-return-revealing)`), so during
   a reveal no rule paints the ground at all and this one stands unopposed.
   The first shipped version instead tried to out-declare them and lost
   silently: 17's dark-ground selector is (1,1,1) with !important against this
   rule's (1,1,0) — the swipe tracked perfectly and revealed flat black. If
   this ever regresses, the thing to check is that those two exclusions in 17
   are still present, NOT to add weight here. */
#app-container.friend-shelf-return-revealing {
  background: transparent !important;
  background-color: transparent !important;
}

/* THE GESTURE RESERVATION.

   A friend's shelf page spans four sibling layers (header, banner, shelf,
   avatar), and the swipe is bound at the document with pointer capture, so the
   whole surface has to agree that VERTICAL panning is the browser's and
   horizontal is the app's. Without this the compositor claims a horizontal drag
   as a scroll on the frames before the handler has decided, and the gesture
   drops mid-track. */
body.viewing-other-user #app-container {
  touch-action: pan-y;
}
