/* One project: a single image at a time, an arrow to each side of it, and the
   caption on its own line underneath. The arrows stand clear of the picture on
   desktop and lie over its outer edges on a phone, where the image is worth
   more than the margin.

   The image keeps its own proportions and is boxed by both dimensions, so a
   tall portrait and a wide landscape each sit inside the same frame without
   being cropped. Both dimensions therefore vary from slide to slide, but the
   arrows do not move with them: they are pinned to the edges of the track,
   which is sized once to the project's widest slide. A narrower picture leaves
   more air beside it, and that is the point — arrows that hugged each image in
   turn would jump about as the reader stepped through.

   Two inline styles feed this file: each slideshow carries --slideshow-width,
   its widest slide, and each slide carries --slide-width, its own. The arrows
   themselves belong to components/arrow — only their placement is here. */

/* --slideshow-max-height is set inline by the component, not declared here:
   the `sizes` attribute needs the same cap as a literal and cannot read a
   custom property, so PHP owns the number and hands it to both. See
   site/plugins/gallery. */
.slideshow {
  /* What the pair of arrows and their gaps take out of the row. Nothing on a
     phone: there the arrows lie over the picture's outer edges rather than
     standing beside it, so the image keeps the full width between the body
     margins and the arrows cost it nothing. The desktop override below buys
     them their own room, which is the only width that has room to give. */
  --slideshow-chrome: 0px;
  /* The track: the widest slide, or whatever the row can spare once the arrows
     are paid for. Read on .slideshow, where the percentage is the full width
     between the body margins. */
  --slideshow-track: min(
    var(--slideshow-width, 100%),
    calc(100% - var(--slideshow-chrome))
  );

  margin-top: calc(var(--lh-base) * 2);
}

/* Wraps the track and nothing else, so its box is the picture's box: the arrows
   inside it hang off its centre line and sit level with the middle of the
   image, and the caption — which is not in here — stays free of its width.

   On mobile, spans full width so arrows sit at body margin edges. On desktop,
   centered to give arrows their own dedicated space. */
.slideshow__viewport {
  position: relative;
  width: 100%;
  margin-inline: 0;
}

/* One slide at a time; still swipeable/scrollable without JS.

   The scrollbar is hidden in both engines' dialects — it is a strip of chrome
   across the foot of the artwork, and the arrows already say the slideshow
   moves. Hiding it costs nothing in reach: the track keeps its tabindex and
   stays keyboard-scrollable, and a swipe still works. */
.slideshow__track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.slideshow__track::-webkit-scrollbar {
  display: none;
}

.slideshow__slide {
  display: flex;
  flex: 0 0 100%;
  align-items: center;
  justify-content: center;
  scroll-snap-align: center;
}

/* Bounded on both axes with auto on both, which is what keeps the aspect ratio
   while fitting inside the frame. `display: block` drops the inline baseline
   gap under the image that the caption would otherwise have to clear.

   --slide-width carries the image's real width, and the cap is not redundant
   with `100%`: an <img> chosen from a srcset reports a density-corrected
   intrinsic size, so a file narrower than `sizes` claims is read as a dense
   image rather than a small one and `width: auto` blows it up to fill the
   frame. A 282px original was being drawn 589px wide on that reasoning. This
   holds every image to the size it actually has. */
.slideshow__image {
  display: block;
  width: auto;
  height: auto;
  max-width: min(100%, var(--slide-width, 100%));
  max-height: var(--slideshow-max-height);
}

/* Under the image in normal flow, starting at the body margin like every other
   line of text on the page. It sits outside the viewport rather than in it, so
   it runs the full width of the row and lines up with the header's columns
   instead of with the track's edge.

   Not overlaid: with no backdrop to lift it off the picture there is nothing to
   read it against, and an arbitrary photograph offers no contrast to rely on. */
.slideshow__caption {
  margin: calc(var(--lh-base) / 2) 0 0;
  color: var(--page-fg, var(--foreground));
}

/* Placement only — components/arrow owns everything the button looks like.
   Hung off the centre line of .slideshow__viewport, so the pair sits level with
   the middle of the image at either width. */
.slideshow__arrow {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
}

/* Flush with the track's own edges, which on a phone are the body margins —
   the arrows lie over the ends of the picture rather than pushing it inwards.
   Measured off the track rather than off each picture, so they hold still from
   slide to slide. */
.slideshow__arrow--prev {
  left: 0;
}

.slideshow__arrow--next {
  right: 0;
}

@media (min-width: 60em) {
  /* Room to spend: the arrows take a gap of their own — they grow with
     --arrow-width, which is a token, not this component's to set — and the
     track gives up exactly the width the pair of them need. */
  .slideshow {
    --slideshow-gap: calc(var(--fs-base) * 2);
    --slideshow-chrome: calc((var(--arrow-width) + var(--slideshow-gap)) * 2);
  }

  /* On desktop, constrain viewport to image width (with arrow space) and center it. */
  .slideshow__viewport {
    width: var(--slideshow-track);
    margin-inline: auto;
  }

  /* Off the picture altogether and into the margin the track just gave up, a
     gap clear of its edge. Each arrow releases the side it was pinned to on
     mobile, or it would be held by both at once. */
  .slideshow__arrow--prev {
    left: auto;
    right: calc(100% + var(--slideshow-gap));
  }

  .slideshow__arrow--next {
    right: auto;
    left: calc(100% + var(--slideshow-gap));
  }
}
