/* ====================================================================
   Cover Flow gallery — shared by the homepage hero and the top of the
   Events page. The centered cover faces front; neighbours fan to both
   sides, angled toward the middle and receding in depth.

   Markup (built by assets/js/coverflow.js):
     <div class="coverflow"><div class="cf-track">…covers…</div></div>

   Per-cover transforms arrive as CSS custom properties written by that
   script, so the geometry constants live in one place (the JS) and this
   file only says how a cover paints.

   Load order: after style.css, before the page's own stylesheet — pages
   layer their own wrapper/caption styles on top.
   ==================================================================== */

.coverflow {
  position: relative;
  width: 100%;
  height: 340px;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: pan-y;
}
.coverflow.is-dragging { cursor: grabbing; }
.cf-track {
  position: absolute;
  left: 50%;
  top: 40px;
  width: 0;
  height: 0;
}
.cover {
  position: absolute;
  left: 0;
  top: 0;
  width: 300px;
  height: 300px;
  margin-left: -150px;          /* center the tile on the track origin */
  /* Perspective is baked into each cover's own transform rather than
     inherited from a `perspective` ancestor through `preserve-3d`. That
     inherited chain renders flat-squished intermittently on JS-inserted
     nodes (the old card stack hit the same bug and fixed it the same way).
     Depth ordering comes from z-index, not 3D, so no preserve-3d needed.
     Fallbacks keep the transform valid if a cover paints before JS runs. */
  transform: perspective(2200px)
             translate3d(var(--x, 0px), 0, var(--z, 0px))
             rotateY(var(--ry, 0deg)) scale(var(--s, 1));
  z-index: var(--zi, 1);
  cursor: pointer;
  will-change: transform;
}
/* Transition is enabled by JS only after the initial flat transforms have
   been applied to the freshly-inserted covers, so the first move animates
   cleanly instead of snapping from "none" on a fast refresh. */
.coverflow.is-ready .cover {
  transition: transform 0.5s cubic-bezier(0.22, 0.72, 0.16, 1);
}
.cover img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.26);
  pointer-events: none;
}
/* White wash on side covers so the centered one reads as focused —
   echoes the progressive tint of the old stack. */
.cover::after {
  content: '';
  position: absolute;
  inset: 0;
  background: #fff;
  opacity: var(--tint, 0);
  transition: opacity 0.5s ease;
  pointer-events: none;
}
/* The centered cover is a link to its show (see coverflow.js), so it gets
   the link cursor — overriding the original deliberate `default`. */
.cover.is-active { cursor: pointer; }
/* "Draft" pill on an unpublished show's tile — only ever rendered for a
   logged-in editor (the templates pass `draft` only for pages that
   voxel_visible_shows kept). Deliberately the same amber pill as the flag
   on the draft page itself (snippets/draft-banner.php) so "this isn't live"
   reads identically wherever it appears. It rotates and recedes with its
   cover, but sits above the side-cover white wash (.cover::after, which
   paints after the card's children) so it stays legible off-center. */
.cover-draft {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 2;
  padding: 0.3em 0.7em;
  background: #FFB000;
  color: #000;
  border: 1px solid #000;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
  pointer-events: none;
}
