/* =============================================================================
   70-activity-stack-focus.css  (v15.454 — initial)
   ----------------------------------------------------------------------------
   The focused stacked-activity view driven by js/71-activity-stack-focus.js.
   Shape: the tapped card pinned at the top of the screen, a sheet of condensed
   child activity cards rising underneath it. Replaces the inline horizontal
   carousel (whose CSS has been deleted from 04-activity-feed.css, not
   overridden).

   Motion rules held here:
     • Only transform and opacity animate. Nothing in this file transitions a
       layout property, so the whole sequence stays on the compositor at 120Hz.
     • The head card's lift is driven from JS (a measured FLIP translate); this
       file only owns where it comes to rest and how wide it is.
     • The drag offset arrives as --sl-stack-focus-drag and is applied to the
       same transform the open/close state uses, so a released drag animates
       from wherever the finger left it.

   Sizing is authored for iPhone 14 Pro Max (430x932) and holds from 375 up:
   every vertical measurement is either a safe-area inset, a vh fraction, or a
   clamp, so the head never eats the sheet on a 6.1" screen.
   ========================================================================== */

body.sl-stack-focus-open {
  overflow: hidden !important;
}

/* The feed card the sheet is showing — hidden while it is "lifted", so the
   original and the clone are never both on screen. Kept in flow so the feed
   does not reflow underneath and the close FLIP has a real rect to fly to. */
.sl-activity-stack-wrap.is-stack-focused {
  visibility: hidden;
}

.sl-stack-focus {
  position: fixed;
  inset: 0;
  z-index: 999998;
  display: none;
  contain: layout paint;
  /* ONE number owns the split between the pinned card and the sheet. The head
     is anchored to the top of the sheet rather than given its own height, so
     changing this can never leave the card running underneath the sheet or a
     dead band between them. */
  /* 68vh: the sheet is the thing the user came for, so it takes the room. The
     pinned stacked card is 282px tall at every iPhone width (its min-height
     clamp bottoms out below 905px of viewport) and the head now gets less than
     that — deliberately. The card is cropped from the bottom with a fade,
     which keeps the parts that identify it (avatar, headline, rating, top of
     the poster) and gives the list the rest. On 430x932 the head is ~187px. */
  --sl-stack-focus-sheet-h: min(68vh, 720px);
}
/* The overlay carries `activity-page` so the cloned card and the child cards
   keep their `.activity-page .shelfd-social-card …` styling. That class also
   paints a #0E0E0E page background (45-default-theme-tail-overrides.css) —
   which would sit behind the scrim and make the feed disappear entirely
   instead of dimming. Cancelled here; the scrim owns the backdrop.
   (`.activity-page`'s own `display:none` needs nothing: the JS sets an inline
   display, which outranks both it and the rule above.) */
.sl-stack-focus.activity-page {
  background-color: transparent !important;
}

.sl-stack-focus-scrim {
  position: absolute;
  inset: 0;
  background: rgba(3, 2, 10, 0.72);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity 260ms ease;
}
.sl-stack-focus.is-open .sl-stack-focus-scrim {
  opacity: 1;
}

/* ------------------------------------------------------------ close button */
/* Sits in the strip between the status bar and the pinned card — above the
   card, never over it, so it can't land on the timestamp in the card's own
   top-right corner. Uses the app's circular glass-button recipe (same as the
   Discovery header buttons) so it reads as Shelfd chrome rather than a
   web-page close box. Fades in with the scrim; it has nothing to close until
   the sheet is actually up. */
.sl-stack-focus-close {
  position: absolute;
  top: calc(max(var(--shelfd-safe-top, 0px), env(safe-area-inset-top, 0px)) + 6px);
  right: 14px;
  z-index: 3;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.13);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 4px 18px rgba(0, 0, 0, 0.22);
  -webkit-backdrop-filter: blur(18px) saturate(1.8);
  backdrop-filter: blur(18px) saturate(1.8);
  color: rgba(255, 255, 255, 0.92);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  opacity: 0;
  transform: scale(.86);
  transition: opacity 200ms ease, transform 260ms cubic-bezier(.22, 1, .36, 1);
}
.sl-stack-focus.is-open .sl-stack-focus-close {
  opacity: 1;
  transform: scale(1);
  /* Held back until the card has cleared its pop, so the button arrives after
     the motion instead of competing with it. */
  transition-delay: 160ms;
}
.sl-stack-focus-close svg {
  width: 18px;
  height: 18px;
  display: block;
}
.sl-stack-focus-close:active {
  background: rgba(255, 255, 255, 0.20);
}
body.light-mode .sl-stack-focus-close {
  border-color: rgba(18, 8, 46, 0.14);
  background: rgba(255, 255, 255, 0.72);
  color: #12082e;
}

/* ---------------------------------------------------------------- the head */
/* The pinned card. Width comes from the source card (set inline by the JS) so
   the FLIP is a pure translate — a scale here would blur the card's text mid
   flight and is the single thing this layout must not do. */
.sl-stack-focus-head {
  position: absolute;
  /* Clears the close button's 40px row plus its 6px inset and a 6px gap. */
  top: calc(max(var(--shelfd-safe-top, 0px), env(safe-area-inset-top, 0px)) + 52px);
  left: 0;
  right: 0;
  /* Width is the SOURCE card's measured width (set inline on open). The card
     itself is `width: 100% !important` from the feed's own rules, so sizing it
     here — not on the card — is what keeps the FLIP a pure translate. */
  width: var(--sl-stack-focus-card-w, 100%);
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
  /* Bottom-anchored to the sheet: the head is exactly the room left over. */
  bottom: calc(var(--sl-stack-focus-sheet-h) + 8px);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow: hidden;
  pointer-events: none;
  /* Fades the card's own bottom edge, so the crop reads as the card carrying
     on behind the sheet rather than as a card with its bottom sliced off. The
     head is now shorter than the card by design, so this fade is always in
     play — 82% keeps the identifying rows (avatar, headline, rating) fully
     solid and spends only the last fifth of the head on the falloff. */
  -webkit-mask-image: linear-gradient(to bottom, #000 82%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 82%, transparent 100%);
}
/* While the card is in flight it is mostly OUTSIDE this box — it starts down
   in the feed and swells past these bounds as it pops. The clip and the fade
   are what hold a too-tall card at rest, so both are suspended for the
   duration of the lift; leaving them on would simply hide the animation the
   whole way up. */
.sl-stack-focus.is-flying .sl-stack-focus-head {
  overflow: visible;
  -webkit-mask-image: none;
  mask-image: none;
}
.sl-stack-focus-head > .sl-stack-focus-card {
  max-width: 100%;
  margin: 0;
  pointer-events: auto;
  transform-origin: 50% 0%;
}

/* --------------------------------------------------------------- the sheet */
.sl-stack-focus-sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: auto;
  display: flex;
  flex-direction: column;
  height: var(--sl-stack-focus-sheet-h);
  padding: 0;
  border-radius: 26px 26px 0 0;
  background: #0E0E0E;
  box-shadow: 0 -20px 70px rgba(0, 0, 0, 0.55);
  transform: translate3d(0, calc(100% + var(--sl-stack-focus-drag, 0px)), 0);
  transition: transform 340ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
  touch-action: pan-y;
}
.sl-stack-focus.is-open .sl-stack-focus-sheet {
  transform: translate3d(0, var(--sl-stack-focus-drag, 0px), 0);
}
/* While a finger is on the sheet it tracks 1:1 — no easing between frames. */
.sl-stack-focus.is-dragging .sl-stack-focus-sheet {
  transition: none;
}

.sl-stack-focus-grip {
  flex: 0 0 auto;
  padding: 9px 0 5px;
  display: flex;
  justify-content: center;
  cursor: grab;
}
.sl-stack-focus-grip > span {
  display: block;
  width: 44px;
  height: 5px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.22);
}

.sl-stack-focus-caption {
  flex: 0 0 auto;
  padding: 2px 20px 10px;
  font: 500 calc(13 * var(--shelfd-px, 1px))/1.3 'Sohne', 'DM Sans', sans-serif;
  letter-spacing: 0.00em;
  color: rgba(255, 255, 255, 0.46);
  border-bottom: var(--sl-activity-divider-thickness, 0.6px) solid var(--sl-activity-divider-color, rgba(255, 255, 255, 0.12));
}

/* --------------------------------------------------------- the child list */
.sl-stack-focus-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 4px 0 calc(22px + env(safe-area-inset-bottom, 0px));
}

.sl-stack-focus-item {
  position: relative;
  border-bottom: var(--sl-activity-divider-thickness, 0.6px) solid var(--sl-activity-divider-color, rgba(255, 255, 255, 0.10));
  /* Entrance stagger. Only the first handful are visible on open, so the
     stagger is capped — a 30-child list must not spend a second settling. */
  opacity: 0;
  transform: translate3d(0, 10px, 0);
  transition: transform 260ms cubic-bezier(.22, 1, .36, 1), opacity 200ms ease;
  transition-delay: calc(min(var(--stack-index, 0), 7) * 26ms);
}
.sl-stack-focus-list.is-open .sl-stack-focus-item {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}
.sl-stack-focus-item:last-of-type {
  border-bottom: 0;
}

/* ------------------------------------------------------------- the collapse */
/* Placed after the open-state rules so it wins the tie on source order. The
   leave curves accelerate (ease-IN) where the entry curves decelerate — the
   open motion has to settle, the close motion has to commit and get out. */
.sl-stack-focus.is-closing .sl-stack-focus-sheet {
  transition: transform 300ms cubic-bezier(0.4, 0, 1, 1);
}
.sl-stack-focus.is-closing .sl-stack-focus-scrim {
  transition: opacity 260ms ease-in;
}
.sl-stack-focus.is-closing .sl-stack-focus-item {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  transition: transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 150ms ease-in;
  /* Front-most child leaves first, so the list reads as being pulled down
     after the sheet rather than dissolving in place. */
  transition-delay: calc(min(var(--stack-index, 0), 5) * 12ms);
}
.sl-stack-focus.is-closing .sl-stack-focus-close {
  opacity: 0;
  transform: scale(.86);
  transition: opacity 140ms ease-in, transform 200ms cubic-bezier(0.4, 0, 1, 1);
  transition-delay: 0ms;
}

.sl-stack-focus-more {
  display: block;
  width: calc(100% - 40px);
  margin: 12px 20px 4px;
  padding: 11px 0;
  border: 1px solid rgba(216, 203, 255, 0.24);
  border-radius: 999px;
  background: rgba(167, 139, 250, 0.14);
  color: rgba(244, 240, 255, 0.94);
  font: 600 calc(14.1 * var(--shelfd-px, 1px))/1 'Sohne', 'DM Sans', sans-serif;
  letter-spacing: 0.00em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sl-stack-focus-more:active {
  background: rgba(167, 139, 250, 0.24);
}

/* ------------------------------------------------------------- small phones */
/* Short viewports (SE-class, and any phone in a split/keyboard state): hand the
   room back to the head so the pinned card is not cropped to a sliver. The card
   is the whole point of the lift — a list with no visible subject above it just
   reads as a random sheet. */
@media (max-height: 800px) {
  .sl-stack-focus {
    --sl-stack-focus-sheet-h: 62vh;
  }
}

/* --------------------------------------------------------------- light mode */
body.light-mode .sl-stack-focus-sheet {
  background: #ffffff;
  box-shadow: 0 -20px 70px rgba(18, 8, 46, 0.22);
}
body.light-mode .sl-stack-focus-grip > span {
  background: rgba(18, 8, 46, 0.18);
}
body.light-mode .sl-stack-focus-caption {
  color: rgba(18, 8, 46, 0.52);
  border-bottom-color: rgba(18, 8, 46, 0.10);
}
body.light-mode .sl-stack-focus-item {
  border-bottom-color: rgba(18, 8, 46, 0.08);
}
body.light-mode .sl-stack-focus-more {
  border-color: rgba(124, 58, 237, 0.28);
  background: rgba(124, 58, 237, 0.10);
  color: #3b1f7a;
}

/* ------------------------------------------------------------ reduced motion */
@media (prefers-reduced-motion: reduce) {
  .sl-stack-focus-scrim,
  .sl-stack-focus-sheet,
  .sl-stack-focus-item,
  .sl-stack-focus-close {
    transition: none !important;
  }
  .sl-stack-focus-item {
    opacity: 1;
    transform: none;
  }
  .sl-stack-focus-close {
    opacity: 1;
    transform: none;
  }
}
