/* ════════════════════════════════════════════════════════════════════════
 * dp-attraction-panel.css — the full-screen attraction view.
 *
 * Lifted verbatim out of dp-home.css (Aug 2026) for the same reason the
 * grid was: a second page opens this panel, and the rules lived in the
 * white homepage's own stylesheet, which no other page can load.
 *
 * THE SYMPTOM WHEN IT IS MISSING is worth writing down, because it does
 * not look like a missing stylesheet. dp-attraction-panel.js pins the
 * body (position:fixed) the moment it opens; without these rules the
 * panel is a static block partway down a document nobody can scroll any
 * more, so the page simply freezes with nothing visible.
 *
 * Load it wherever partials/attraction-panel.ejs is included.
 * ════════════════════════════════════════════════════════════════════ */

/* ── The full-screen attraction view ───────────────────────────────────
 * Tapping a card opens the attraction over the whole screen, with one X
 * in the top-left.
 *
 * WHAT IS INSIDE IT IS THE SHARE PAGE'S OWN MARKUP — literally
 * views/share/share-attraction-main.ejs, fetched as an HTML fragment from
 * /share/attraction/{cid}/{slug}/fragment and injected. So there are NO
 * styles here for the CONTENT of the panel, and there should never be
 * any: it is styled by views/share/share-styles.ejs, the same partial the
 * share page uses, which views/home.ejs now includes. Everything below is
 * chrome — the scrim, the surface, the close button, the scroller.
 *
 * This replaced an <iframe> of /share/attraction/**\/embed. The isolation
 * an iframe gave was real, but it cost a whole HTML document per open and
 * its navigations pushed entries into the top-level history, which is
 * what left the address bar on the attraction after the panel closed.
 * Sharing the stylesheet gets the same one-definition guarantee without
 * either cost.
 *
 * It stays dark on a white page, because the share markup is dark: the
 * --sh-* ink set is tuned for a dark backdrop (share-styles.ejs) and a
 * white surround under it would be the only wrong thing on the screen.
 * ──────────────────────────────────────────────────────────────────── */
/* ABOVE THE SITE HEADER. The header is position:fixed at
 * z-index: var(--site-header-z, 1000) (public/css/site-header.css), so a
 * panel at 90 opened UNDER it — the close button in the top-left corner
 * was the part it covered, which is the one control the overlay has.
 *
 * Derived from the header's own token rather than hard-coded above it, so
 * raising --site-header-z somewhere cannot quietly put the header back on
 * top. Still below the shared modals at 2000 (mydreampark-ui.css) —
 * DreamShareModal opens FROM this panel and has to land over it.
 *
 * The header is left visible on purpose. It is inert while the panel is
 * open (dp-attraction-panel.js), the panel is opaque, and hiding a
 * position:fixed header buys nothing but a flicker on close. */
.dp-scrim {
  position: fixed;
  inset: 0;
  z-index: calc(var(--site-header-z, 1000) + 10);
  background: rgba(8, 4, 20, .5);
  backdrop-filter: blur(16px) saturate(.9);
  -webkit-backdrop-filter: blur(16px) saturate(.9);
  opacity: 0;
  pointer-events: none;
  transition: opacity .26s ease;
}
.dp-scrim.is-open { opacity: 1; pointer-events: auto; }

.dp-panel {
  position: fixed;
  inset: 0;
  z-index: calc(var(--site-header-z, 1000) + 11);
  /* The share page's own backdrop, so injected markup sits on what it was
   * designed for. Kept in sync with the body rule in share-head.ejs. */
  background:
    radial-gradient(ellipse at 50% 0%, rgba(106, 27, 154, .45), transparent 55%),
    radial-gradient(ellipse at 80% 50%, rgba(255, 62, 181, .14), transparent 60%),
    radial-gradient(ellipse at 20% 80%, rgba(0, 229, 255, .10), transparent 55%),
    linear-gradient(180deg, var(--mdp-ui-ink-void, #0c0220) 0%, var(--mdp-ui-ink-deep, #1a0633) 100%);
  color: var(--sh-ink-body);
  font-family: var(--mdp-ui-body);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .2s ease, transform .26s var(--dp-ease);
  will-change: transform, opacity;
}
.dp-panel[hidden] { display: none; }
.dp-panel.is-open { opacity: 1; transform: none; }

/* The close button floats over the content, so it gets a little dark at
 * its back — only at the very top, and only a gradient. */
.dp-panel::before {
  content: '';
  position: absolute;
  z-index: 1;
  inset: 0 0 auto 0;
  height: 96px;
  pointer-events: none;
  background: linear-gradient(rgba(4, 2, 10, .55), transparent);
}

/* TOP-LEFT, and outside the scroller so it holds its corner while the
 * attraction scrolls under it. */
.dp-panel-close {
  position: absolute;
  z-index: 2;
  top: max(clamp(10px, 1.6vw, 20px), env(safe-area-inset-top));
  left: max(clamp(10px, 1.6vw, 20px), env(safe-area-inset-left));
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .16);
  background: rgba(10, 6, 23, .62);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #f4f2ff;
  border-radius: 50%;
  cursor: pointer;
  transition: background .16s ease, transform .16s ease;
}
.dp-panel-close:hover { background: rgba(28, 18, 54, .92); transform: scale(1.06); }
.dp-panel-close:focus-visible { outline: 3px solid var(--dp-violet-3); outline-offset: 2px; }

/* The scroller carries .sh-embed and its child carries .sh-wrap, which is
 * exactly the pair a chrome-less share page uses — so the measure and the
 * padding come from share-styles.ejs rather than being restated here. */
.dp-panel-scroll {
  height: 100%;
  height: 100svh;
  overflow-y: auto;
  overflow-x: hidden;
  /* The page behind is position:fixed while this is open, but a rubber-band
   * at the end of this scroller still chains to it on iOS without this. */
  overscroll-behavior-y: contain;
  -webkit-overflow-scrolling: touch;
}
/* Clear the floating X. On the share page the site header does this job. */
/* The variable, not the padding: .sh-wrap's shorthand resolves it, and the
   share page's full-bleed hero pulls itself up by the same value to reach the
   top edge of the panel (--shr-hero-pull in share-styles.ejs). Setting
   padding-top directly here left the hero in a bar below it. */
.dp-panel-scroll .sh-wrap { --sh-wrap-top: clamp(64px, 8vh, 88px); }

/* While the fragment is in flight. Not a spinner: the surface is already
 * on screen and animating in, and a spinner on top of that reads as two
 * things loading. */
.dp-panel-body.is-loading {
  min-height: 60vh;
  background: linear-gradient(100deg, rgba(255, 255, 255, .03) 20%,
              rgba(255, 255, 255, .07) 40%, rgba(255, 255, 255, .03) 60%);
  background-size: 220% 100%;
  border-radius: 22px;
  animation: dpcShimmer 1.7s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  /* dp-home.css kills the same transitions for the homepage; repeated here
   * because a page that opens the panel without loading that sheet still
   * has to honour the preference. */
  .dp-panel, .dp-scrim { transition: none; }
}
