.infinite-grid {
  touch-action: none;
  width: 100%;
  height: 100svh;
  position: relative;
  overflow: clip;
  cursor: grab;
  opacity: 1;
}

.infinite-grid[data-infinite-grid-status="dragging"] {
  cursor: grabbing;
}

.infinite-grid__collection {
  will-change: transform;
  width: 100%;
  height: 100%;
  position: absolute;
}

.infinite-grid__list {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

.infinite-grid__item {
  aspect-ratio: 1;
  will-change: transform;
  backface-visibility: hidden;
  justify-content: center;
  align-items: center;
  width: 13em;
  /* Definite dimensions keep percentage-height media consistent on mobile. */
  height: 13em;
  padding: 2.25em;
  font-size: clamp(1.5em, 2vw, 3em);
  display: flex;
  position: absolute;
  top: 0;
  left: 0;
}

.infinite-grid__card {
  -webkit-user-select: none;
  user-select: none;
  will-change: transform;
  backface-visibility: hidden;
  border-radius: .125em;
  width: 100%;
  height: 100%;
  position: relative;
}

.infinite-grid__card-img {
  pointer-events: none;
  object-fit: cover;
  border-radius: inherit;
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  object-position: center;
  transition: opacity 180ms ease;
}

/* Reserve the artwork's space while an individual image/poster decodes. */
.infinite-grid__card[data-media-state="loading"],
.infinite-grid__card[data-media-state="error"] { background: #151515; }
.infinite-grid__card[data-media-state="loading"] .infinite-grid__card-img,
.infinite-grid__card[data-media-state="error"] .infinite-grid__card-img { opacity: 0; }
.infinite-grid__card[data-media-state="error"]::after {
  content: 'Artwork unavailable';
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #aaa;
  font: 12px/1.4 sans-serif;
  text-align: center;
}

/* Preserve portrait artwork without cropping its typography. */
.infinite-grid__card--portrait {
  width: var(--portrait-width, 80%);
}

/* Fill the viewport below the existing navigation. */
body.page-explore { min-width: 0; height: 100svh; overflow: hidden; background: #000; }
.page-explore #main-content { height: 100svh; padding-top: 44px; }
.page-explore .infinite-grid { height: 100%; outline-offset: -4px; }
.page-explore .dock-blur, .page-explore .dock { display: none; }
.page-explore .infinite-grid__item { box-sizing: border-box; }
.infinite-grid[data-infinite-grid-status="fallback"] { overflow: auto; touch-action: auto; cursor: auto; }
.infinite-grid[data-infinite-grid-status="fallback"] :is(.infinite-grid__collection, .infinite-grid__list) { position: relative; height: auto; }
.infinite-grid[data-infinite-grid-status="fallback"] .infinite-grid__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
  padding-bottom: 100px;
}
.infinite-grid[data-infinite-grid-status="fallback"] .infinite-grid__item {
  position: relative; width: 100%; height: auto; aspect-ratio: auto; padding: 1rem;
}
.infinite-grid[data-infinite-grid-status="fallback"] :is(.infinite-grid__card, .infinite-grid__card-img) {
  position: relative; width: 100%; height: auto;
}
@media (max-width: 980px) {
  .page-explore #main-content { padding-top: 48px; }
  .page-explore .infinite-grid__item { width: 240px; height: 240px; padding: 28px; font-size: 16px; }

  /* Let the artwork set its own height, keeping the desktop proportions
     without percentage-height resolution or cover-cropping on phones. */
  .page-explore .infinite-grid__card { height: auto; }
  .page-explore .infinite-grid__card-img {
    display: block;
    position: static;
    height: auto;
    object-fit: contain;
  }
}
@media (prefers-reduced-motion: reduce) {
  .infinite-grid__card-img { transition: none; }
}
@media (max-width: 980px) {
  .page-explore .dock { display: flex; }
  .page-explore .dock-blur { display: block; }
}
/* Retain the shared gutter while Explore locks scrolling, so the fixed nav
   does not jump sideways when arriving from a scrollable page. */
html:has(.page-explore) { overflow: hidden; scrollbar-gutter: stable; }

/* Avoid flashing the readable, unpositioned gallery before deferred scripts
   initialise. With JS unavailable, the normal readable page stays visible. */
html.explore-pending:not(.site-enhanced) body.page-explore {
  height: 100svh !important;
  overflow: hidden !important;
}
html.explore-pending:not(.site-enhanced) .page-explore #main-content {
  visibility: hidden;
  height: 100svh;
}
html.explore-pending:not(.site-enhanced) .page-explore .site-header { position: fixed; }

/* The interactive canvas can run even when shared page animation fails. */
html.explore-canvas-ready:not(.site-enhanced) .page-explore .site-header {
  position: fixed;
}
html.explore-canvas-ready:not(.site-enhanced) .page-explore #main-content {
  visibility: visible;
}
@media (max-width: 980px) {
  /* Use the existing non-animated menu when shared motion is unavailable. */
  html.explore-canvas-ready.animations-unavailable .page-explore .site-nav { display: none !important; }
  html.explore-canvas-ready.animations-unavailable .page-explore :is(.dock, .mobile-menu) { display: flex !important; }
  html.explore-canvas-ready.animations-unavailable .page-explore .dock-blur { display: block !important; }
}
