.project__hero { position: relative; min-block-size: 88svh; display: grid; align-items: end; }
.project__hero-media { position: absolute; inset: 0; }
.project__hero-media img { width: 100%; height: 100%; object-fit: cover; }
.project__hero-copy {
  position: relative; padding-block-end: var(--space-16);
  color: var(--warm-white); text-shadow: 0 1px 40px rgb(18 17 16 / 45%);
}
.project__hero-copy .display, .project__hero-copy .meta { color: inherit; }

/* The album. Every photograph is a framed print: warm-white mat, hairline
   edge, a soft professional shadow - and clear air between the frames so
   nothing touches. The column is narrower than the page wrap, so the
   album keeps comfortable margins and no print runs edge to edge. */
.project__gallery {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--space-8) var(--space-6);
  margin-block: var(--section-gap);
  max-inline-size: 66rem;
}
.project__print {
  margin: 0;
  background: var(--warm-white);
  border: 1px solid var(--hairline);
  padding: var(--space-3);
  box-shadow: 0 1px 2px rgb(18 17 16 / 4%), 0 12px 28px rgb(18 17 16 / 7%);
  transition: box-shadow 300ms var(--ease), transform 300ms var(--ease);
}
.project__print:hover {
  transform: translateY(-0.1875rem);
  box-shadow: 0 2px 4px rgb(18 17 16 / 5%), 0 18px 40px rgb(18 17 16 / 10%);
}
/* The picture clips the zoom so it stays inside its own frame. */
.project__print picture { display: block; overflow: hidden; }
.project__print img {
  inline-size: 100%; block-size: auto; aspect-ratio: 3 / 2; object-fit: cover;
  transition: transform 500ms var(--ease);
}
.project__print:hover img { transform: scale(1.03); }
/* An odd count leaves the last print alone on its row: it hangs centred
   and a little wider, like the closing page of an album. */
.project__print:last-child:nth-child(odd) {
  grid-column: 1 / -1; justify-self: center;
  inline-size: min(100%, 46rem);
}
/* Prints fade up one after the other - the delay is set per print in the
   template. The entrance is an ANIMATION, not the global reveal transition:
   a transition-delay would linger on the transform property and lag every
   later hover lift; an animation with `backwards` fill holds the print
   hidden through its delay, plays once, then releases the properties so
   the 300ms hover transitions above take over cleanly. */
.js .project__print.reveal.is-visible {
  animation: print-in 700ms var(--ease) backwards;
  animation-delay: var(--reveal-delay, 0ms);
  transition: box-shadow 300ms var(--ease), transform 300ms var(--ease);
}
@keyframes print-in {
  from { opacity: 0; transform: translateY(24px); }
  to { opacity: 1; transform: none; }
}

.project__meta {
  display: grid; grid-template-columns: auto 1fr; gap: var(--space-4) var(--space-8);
  border-block-start: 1px solid var(--hairline); padding-block-start: var(--space-8);
}
.project__meta dt {
  font-size: 0.6875rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--neutral);
}
/* Centred with the rest of the site's prose, per the client. */
.project__meta :is(dt, dd) { text-align: center; }
.project__meta dd { margin: 0; }
[dir="rtl"] .project__meta dt { letter-spacing: 0; text-transform: none; font-size: 0.875rem; }

/* A quiet text link - never another event's photograph on this page. */
.project__next a { color: inherit; text-decoration: none; }
.project__next a:hover, .project__next a:focus-visible { color: var(--rose-deep); }

@media (prefers-reduced-motion: reduce) {
  .project__print, .project__print img { transition: none; }
  .project__print:hover { transform: none; }
  .project__print:hover img { transform: none; }
  .js .project__print.reveal.is-visible { animation: none; }
}

@media (max-width: 48rem) {
  .project__gallery { grid-template-columns: 1fr; gap: var(--space-6); }
  .project__print { padding: var(--space-2); }
  .project__print:last-child:nth-child(odd) { inline-size: 100%; }
  .project__meta { grid-template-columns: 1fr; gap: var(--space-1) 0; }
  .project__meta dd { margin-block-end: var(--space-4); }
}
