/* The photographs, as a view rather than a page.
 *
 * Shared by photos.html (entered directly) and by the home page, which shows
 * the same gallery without unloading the document — because unloading it would
 * stop the song. Both get their grid from here so there is one definition of
 * what the gallery looks like.
 */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 2.2vw;
}

.grid figure { margin: 0; line-height: 0; }

/* The duotone and grain are baked into these files rather than applied here.
   As a filter it had to run once per photograph at paint time, and WebKit does
   that as each one scrolls into view — so they arrived one at a time even when
   every file was already in cache and decoded. Baked, there is nothing left to
   run and they simply paint.

   The cost is that they no longer follow the palette: change the two colours
   and these have to be regenerated. The gallery never inverts, so that trade
   only bites if the palette itself is re-sampled. */
.grid img {
  width: 100%;
  height: auto;
  display: block;
  opacity: 0.9;
  transition: opacity 300ms ease;
}

.grid img:hover { opacity: 1; }

.empty {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.4;
}

/* --- the in-page view ------------------------------------------------------
   Only used on the home page. It scrolls over the top of the song rather than
   replacing it, so the lyric layer and the video keep their state and the song
   keeps playing underneath. It sits above both but below the icons, which stay
   on top as the tabs. */

#g-gallery {
  position: fixed;
  inset: 0;
  z-index: 12;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 8vh 2.2vw 22vh;
  background: var(--light);
  display: none;
}

body.is-gallery #g-gallery { display: block; }

/* The song is still running underneath — hidden, not torn down.
   visibility rather than display, and the difference matters: display:none
   takes the video out of the layout entirely, and iOS responds by releasing
   its decoder. Calling play() on the way back does not bring the picture
   with it — the element comes back empty, and the blend layers turn that
   empty white into flat colour. visibility keeps the element real and the
   footage running; the browser simply stops painting it, which is all that
   was wanted. The gallery above is opaque, so nothing shows through. */
/* The lyric layer is only a div, so hiding it costs nothing to restore.
   The video is deliberately NOT hidden. Safari stops hidden video to save
   power — display:none released its decoder outright, visibility:hidden still
   let it be paused a moment after each resume, and answering that with a
   retry only produced a fight the browser always wins. So it is left alone:
   #g-gallery above it is opaque and covers the viewport, so the picture is
   already invisible without the browser needing to be told. It costs some
   decoding behind an opaque layer, which is the price of it still being there
   when you come back. */
body.is-gallery #g-lyrics { visibility: hidden; }

/* Declared after the inversion rules in lyrics.css and at equal specificity,
   so this wins while the gallery is up: a section of the song flipping the
   palette must not repaint the gallery's ground mid-scroll. */
body.is-gallery {
  --ground: var(--light);
  /* White rather than the dark ink: the icons and the footer are fixed over a
     column of photographs, and the photographs are mostly dark. Dark ink on
     them disappeared. */
  --ink: #ffffff;
}

/* White reads over the photographs, which are mostly dark — but the ground
   behind them is cream, and it shows through the gaps and below the last
   image. White on cream is nothing at all. A soft shadow in the palette's own
   dark carries the chrome across both without reading as an effect: over a
   photograph it is invisible, over the cream it is the only thing holding the
   letterforms up. */
body.is-gallery #g-footer,
#g-gallery ~ #g-footer {
  text-shadow: 0 1px 3px rgba(40, 51, 29, 0.55);
}

body.is-gallery .g-icon {
  filter: drop-shadow(0 1px 3px rgba(40, 51, 29, 0.5));
}
