/**
 * player-content-transition.css — slide in/out for the player portal's nav
 * content panels (Tab 1-7) on index.php.
 *
 * Selecting a nav tab slides its destination in; re-selecting the active tab
 * (→ overview) slides it back out. Portrait: the panel rises from the bottom
 * edge (where the tab-bar sits); landscape: it enters from the right edge
 * (where the tab-bar sits). The effect is that the panel "opens out of" the
 * menu item that was tapped — see PlayerContentTransition (player-content-
 * transition.js) which decorates the mounts on each tab change.
 *
 * Mechanism — Safari 16.6.1-safe (NO @starting-style / transition-behavior:
 * allow-discrete, which iPadOS 16 lacks). PlayerContentTransition adds
 * .hd-content-animated to the seven nav mounts. Each destination's own
 * tab-change listener already toggles the mount's [hidden] attribute; here we
 * repurpose that toggle from an instant display:none into a transform +
 * visibility transition (the classic visibility-delay trick gives a real exit
 * animation without display-discrete support). The overview and combat-
 * companion mounts are intentionally NOT animated (overview is the static base
 * layer revealed on close; combat-companion is a KAMP overlay with its own
 * show/hide).
 *
 * CASCADE — the display exemption MUST be in @layer reset. base.css's reset
 * layer has `[hidden] { display: none !important }`, and the declared layer
 * order is `reset, tokens, base, components, utilities, overrides`. For
 * !important declarations the layer order reverses, so the FIRST layer (reset)
 * outranks every later layer AND unlayered rules — only a same-layer (reset),
 * higher-specificity rule can keep an animated mount displayed while [hidden].
 * The visual mechanics (transform/visibility/transition/z-index) are normal
 * declarations with no !important competitor, so they stay in @layer components.
 *
 * Zoom-safe: at rest `transform: none`, so this is byte-identical to the prior
 * static layout at any --hd-player-content-zoom, and never establishes a
 * fixed-position containing block for descendants (e.g. the quest compose-FAB)
 * while settled. During the roll transition (--hd-motion-roll-up/down, ~480/430ms,
 * matched to the reel spin) a transform is briefly present, so a position:fixed
 * child rides with its panel — which is the intended slide.
 */

/* Keep animated mounts rendered while [hidden] so they can transition out.
 * Must outrank base.css `@layer reset { [hidden]{display:none!important} }`. */
@layer reset {
  body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated[hidden] {
    display: block !important;
  }
}

@layer components {
  /* Rest state: in place, visible, ready to animate. */
  body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated {
    transform: none;
    visibility: visible;
    transition:
      transform var(--hd-motion-roll-up) var(--hd-ease-in-out-cubic),
      visibility 0s linear 0s;
  }

  /* Hidden = slide OUT to the bottom edge (close-to-overview). The panel stays
   * visible for the duration, then drops below the bottom edge, under the
   * tab-bar. visibility flips to hidden only after the slide completes. */
  body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated[hidden] {
    position: fixed;
    margin-top: 0;
    top: calc(var(--hd-visual-viewport-offset-top, 0px) + var(--player-top-bar-height, 0px));
    right: 0;
    bottom: var(--player-tab-bar-size, 0px);
    left: 0;
    width: auto;
    height: auto;
    min-height: 0;
    overflow-y: auto;
    transform: translateY(100%);
    visibility: hidden;
    pointer-events: none;
    transition:
      transform var(--hd-motion-roll-down) var(--hd-ease-in-out-cubic),
      visibility 0s linear var(--hd-motion-roll-down);
  }

  /* Covered = a new panel is rising over this one (tab→tab switch). Held at rest
   * (no slide) WHILE the riser covers it, then SNAPPED down to the stowed
   * position (translateY(100%)) the instant it is fully hidden. The snap is
   * invisible (it coincides with visibility:hidden, behind the now-covering
   * riser), and it leaves the panel stowed below the bottom edge — so the NEXT
   * time it is opened it rises from the bottom again (#6: a panel left via a
   * tab→tab switch used to stay at transform:none, so re-opening it produced no
   * transform delta and therefore no roll-up). Both transform and visibility
   * change only after the roll-up delay, so the cover stays motionless. */
  body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated.hd-content-instant[hidden] {
    transform: translateY(100%);
    transition:
      transform 0s linear var(--hd-motion-roll-up),
      visibility 0s linear var(--hd-motion-roll-up);
  }

  /* Forced-stowed hidden panels are old menu sheets that were covered by a
   * later menu and must not become the backdrop if that later menu is closed
   * before the delayed cover-hide has elapsed. They are hidden immediately and
   * without animation so close-to-overview always reveals the forside. */
  body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated.hd-content-stowed[hidden] {
    transform: translateY(100%);
    visibility: hidden;
    pointer-events: none;
    transition: none;
  }

  /* The moving panel rides above its neighbour for the transition. Stays far
   * below the chrome (--hd-player-chrome-z: 12000) and modals (--hd-z-modal). */
  body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated.hd-content-raised {
    z-index: 45;
  }

  /* (#8) The quest compose-FAB used to be hidden here while the panel was raised,
   * because as a position:fixed child of the transformed mount it rode up and then
   * snapped by the tab-bar height. It now lives in the portal chrome (sibling of
   * the mount, quest-feed.js) with its own synced roll-up entrance, so no
   * hide-during-raise rule is needed. */

  /* Landscape: the tab-bar is on the right edge, so panels enter/leave the
   * right side ("opens out of where the menu is tapped"). */
  @media (min-aspect-ratio: 1/1) {
    body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated[hidden] {
      right: var(--player-tab-bar-size, 0px);
      bottom: 0;
      transform: translateX(100%);
    }
    body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated.hd-content-instant[hidden] {
      /* Landscape stows to the right edge (matches the entry edge) — same
       * delayed-snap behaviour as portrait (transition inherited above). */
      transform: translateX(100%);
    }
    body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated.hd-content-stowed[hidden] {
      transform: translateX(100%);
    }
  }

  /* Tab→tab cover exit: PlayerContentTransition measures the outgoing sheet
   * before its destination sets [hidden]. While the incoming sheet rolls up,
   * the old sheet keeps that exact fixed rectangle and rolls down underneath it
   * instead of adopting the generic hidden viewport geometry above; otherwise
   * grid/typography can reflow visibly underneath the riser before it is fully
   * covered. The delayed .hd-content-instant cleanup still stows it after the
   * incoming sheet has covered it. */
  body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated.hd-content-cover-freeze[hidden] {
    position: fixed;
    margin-top: 0;
    top: var(--hd-content-cover-top, 0px);
    right: auto;
    bottom: auto;
    left: var(--hd-content-cover-left, 0px);
    width: var(--hd-content-cover-width, auto);
    height: var(--hd-content-cover-height, auto);
    min-height: 0;
    transform: translateY(100%);
    visibility: visible;
    pointer-events: none;
    transition:
      transform var(--hd-motion-roll-down) var(--hd-ease-in-out-cubic),
      visibility 0s linear var(--hd-motion-roll-down);
  }

  @media (min-aspect-ratio: 1/1) {
    body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-animated.hd-content-cover-freeze[hidden] {
      transform: translateX(100%);
    }
  }

  /* Parchment backdrop now lives in the scroll-stack paper layer
     (player-content-zoom.css §surface stack), so it scrolls with the slot
     content without background-attachment: local repaint coupling (#7). */

  /* Frayed parchment top edge ("the sheet's end") on nav panels that roll up.
     Overview (Forside) does NOT get it — it is the static backdrop.

     The scroll mount stays on the shared top-bar geometry: same margin, same
     height, same scroll owner. Only the decorative paper layer gets the deckle,
     so the visible sheet edge rides with the panel transform and sits under the
     top-bar crease shadow without clipping content or shifting scroll bounds.
     Deckle depth is FIXED px (X stays %) so it never scales with the tall mount. */
  body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-frayed {
    --hd-player-surface-pad-top: var(--hd-roller-crease-h);
    background-color: transparent;
  }

  body:is(.hd-player-mode-player-portal, .hd-player-mode-dm) .hd-player-content-mount.hd-content-frayed .hd-player-surface-paper {
    transform: translateY(0);
    transform-origin: top center;
    transition: transform var(--hd-motion-roll-up) var(--hd-ease-in-out-cubic);
    -webkit-clip-path: polygon(0% 11px,7% 3px,14% 9px,21% 4px,28% 11px,35% 5px,42% 10px,50% 2px,57% 10px,64% 4px,71% 12px,78% 4px,85% 9px,92% 3px,100% 8px,100% 100%,0% 100%);
    clip-path: polygon(0% 11px,7% 3px,14% 9px,21% 4px,28% 11px,35% 5px,42% 10px,50% 2px,57% 10px,64% 4px,71% 12px,78% 4px,85% 9px,92% 3px,100% 8px,100% 100%,0% 100%);
  }
}
