/* ==========================================================================
   CASE PAGE - gallery
   The layout the client asked for (a full-height cover, then a masonry wall of
   stills) rebuilt on this site's own system rather than the reference's white
   Raleway/Lato one: near-black ground, Syne, the shared tokens, the site nav
   and footer. Loaded by project.html only, on top of style.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Cover - the fixed nav sits over it, as the hero does on the home page
   -------------------------------------------------------------------------- */

.gcover {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 100dvh;
  overflow: hidden;
}

.gcover__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Three grounds, because the type block sits dead centre and the photograph
   underneath it is not reliably dark there: a soft pool behind the middle where
   the title and meta row land, a foot to carry the fade into the page, and a
   head so the fixed nav has something to sit against. Measured, not guessed -
   white body copy clears WCAG AA over the pool even where the frame is
   brightest. */
.gcover::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(64% 50% at 50% 50%, rgba(7, 7, 7, .84) 0%, rgba(7, 7, 7, .6) 52%, rgba(7, 7, 7, 0) 100%),
    linear-gradient(to top, rgba(7, 7, 7, .8) 0%, rgba(7, 7, 7, 0) 38%),
    linear-gradient(to bottom, rgba(7, 7, 7, .6) 0%, rgba(7, 7, 7, .1) 22%);
  pointer-events: none;
}

.gcover__detail {
  position: relative;
  z-index: 2;
  display: grid;
  justify-items: center;
  gap: clamp(1.5rem, 3vw, 2.25rem);
  width: 100%;
  max-width: var(--shell);
  padding-inline: var(--gutter);
  padding-top: var(--nav-h);
  text-align: center;
}

.gcover__title {
  margin: 0;
  font-size: clamp(2.5rem, 9vw, 7rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -.05em;
  line-height: .84;
  color: var(--fg);
}

.gcover__meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .5rem 2.25rem;
  margin: 0;
  font-size: .6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--fg);
}

.gcover__enter { color: var(--fg); }

/* --------------------------------------------------------------------------
   Gallery
   -------------------------------------------------------------------------- */

.ggallery {
  padding-top: clamp(3rem, 7vw, 6rem);
  padding-bottom: clamp(2rem, 5vw, 4rem);
}

.ggallery__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: clamp(1.25rem, 3vw, 2rem);
  border-bottom: 1px solid var(--line);
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

.ggallery__label {
  font-size: .6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--muted);
}

.ggallery__count {
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .16em;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

/* Columns rather than absolutely positioned tiles: same wall, no layout script,
   and nothing to go wrong if it fails to load. The run of images falls down
   each column instead of across, which is the one thing this trades away. */
.gmasonry {
  column-count: 4;
  column-gap: 12px;
}

.gtile {
  display: block;
  width: 100%;
  padding: 0;
  margin: 0 0 12px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--bg-raise);
  cursor: zoom-in;
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
}

.gtile img {
  display: block;
  width: 100%;
  height: auto;
  transition: transform 1.2s var(--ease), opacity .45s var(--ease);
}

.gtile:hover img,
.gtile:focus-visible img { transform: scale(1.04); opacity: .82; }

.gtile[hidden] { display: none; }

/* a tile that holds a film. The poster is a plain img like every other tile,
   so the masonry column maths is unchanged; the play mark sits over it and
   the cursor switches from zoom to play to say what the click will do. */

.gtile--film { cursor: pointer; }

.gtile__play {
  position: absolute;
  inset: auto auto 12px 12px;
  z-index: 1;
  display: grid;
  grid-auto-flow: column;
  align-items: center;
  gap: .5rem;
  padding: .4rem .7rem .4rem .55rem;
  border-radius: 999px;
  background: rgba(7, 7, 7, .62);
  backdrop-filter: blur(8px);
  font-size: .6875rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fg);
  transition: background .3s var(--ease), color .3s var(--ease);
}

.gtile { position: relative; }

.gtile--film:hover .gtile__play,
.gtile--film:focus-visible .gtile__play {
  background: var(--fg);
  color: var(--bg);
}

/* --------------------------------------------------------------------------
   Footer controls
   -------------------------------------------------------------------------- */

.gactions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
  padding-bottom: var(--section);
}

/* --------------------------------------------------------------------------
   Lightbox
   -------------------------------------------------------------------------- */

.glb {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  background: rgba(7, 7, 7, .96);
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s var(--ease), visibility .35s var(--ease);
}

.glb.is-open { opacity: 1; visibility: visible; }

.glb__img,
.glb__video {
  max-width: min(92vw, 1500px);
  max-height: 86dvh;
  object-fit: contain;
  border-radius: var(--radius-lg);
}

/* the two viewers occupy the same cell, and only one is ever shown, so the
   frame does not jump as you page between a still and a film */
.glb__img[hidden],
.glb__video[hidden] { display: none !important; }

.glb__video { width: auto; background: #000; }

.glb__btn {
  position: absolute;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(16, 16, 16, .72);
  color: var(--fg);
  cursor: pointer;
  transition: background .3s var(--ease), border-color .3s var(--ease), color .3s var(--ease);
}

.glb__btn:hover,
.glb__btn:focus-visible { background: var(--fg); border-color: var(--fg); color: var(--bg); }

.glb__btn--close { top: 18px; right: 20px; }
.glb__btn--prev  { top: 50%; left: 20px;  transform: translateY(-50%); }
.glb__btn--next  { top: 50%; right: 20px; transform: translateY(-50%); }

.glb__count {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .16em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Breakpoints
   -------------------------------------------------------------------------- */

@media (max-width: 1100px) { .gmasonry { column-count: 3; } }

@media (max-width: 760px) {
  .gmasonry { column-count: 2; column-gap: 8px; }
  .gtile { margin-bottom: 8px; }
  .glb__btn { width: 44px; height: 44px; }
  .glb__btn--prev { left: 10px; }
  .glb__btn--next { right: 10px; }
  .glb__btn--close { right: 12px; top: 12px; }
}

@media (max-width: 460px) { .gmasonry { column-count: 1; } }
