/* PhotoSwipe chrome overrides. */

/* Hide the zoom button (zoom is via click/scroll/pinch instead). */
.pswp__button--zoom { display: none !important; }

/* PhotoSwipe draws a dark stroked duplicate behind its own icons (close,
   arrows, zoom) for contrast. The open-page icon (built without one — see
   lightbox_controller#openIcon) doesn't get this, so it reads as a flat
   glyph; hide the others' too so every icon shares that same flat look. */
.pswp__icn-shadow {
  display: none;
}

/* Give every icon the same drop shadow so they stay legible over light
   images. All three are fill-based SVGs (the open-page icon built the same
   way PhotoSwipe builds its own icons — see lightbox_controller#openIcon),
   so they're colorable directly via `fill`. */
.pswp__button--close .pswp__icn,
.pswp__button--photo-open .pswp__icn,
.pswp__button--arrow .pswp__icn {
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6));
  transition: fill 0.2s ease;
}

/* Highlight with the site's accent color on hover, same as every other
   link/button. */
.pswp__button--close:hover .pswp__icn,
.pswp__button--photo-open:hover .pswp__icn,
.pswp__button--arrow:hover .pswp__icn {
  fill: var(--color-accent);
}

/* The switch-view icon is a stroked line icon rather than a filled one, so it
   colors via `stroke` and has to clear the `fill` .pswp__icn sets. */
.pswp__button--photo-edit .pswp__icn {
  fill: none;
  stroke: var(--pswp-icon-color);
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6));
  transition: stroke 0.2s ease;
}

.pswp__button--photo-edit:hover .pswp__icn {
  stroke: var(--color-accent);
}

/* Sits alone in the top-left, opposite the group below. */
.pswp__button--photo-edit { order: -1; }

/* Group the counter with the buttons in the top-right. The preloader keeps
   its default margin-right:auto, pushing this whole ordered group to the
   right edge; the counter sits just left of the controls. */
.pswp__counter { order: 1; margin-inline-end: 14px; }
.pswp__button--photo-open { order: 2; }
.pswp__button--close { order: 3; }

.pswp__top-bar,
.pswp__button--arrow--prev,
.pswp__button--arrow--next,
.pswp__custom-caption {
  transition: opacity 0.3s ease;
}

.pswp--controls-hidden .pswp__top-bar,
.pswp--controls-hidden .pswp__button--arrow--prev,
.pswp--controls-hidden .pswp__button--arrow--next,
.pswp--controls-hidden .pswp__custom-caption {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* Base look for the custom caption bar; per-slide visibility (opacity) is
   still toggled inline by the controller since it changes on every slide.

   The bar is sized by its content rather than pinned to a fixed height. It
   collapses to a two-line preview of the caption, and expands to the full text
   on click (`.is-expanded`, set by the controller). Only the expanded state can
   ever scroll, and only past 70vh: on both desktop and a phone the longest
   caption written so far opens well inside that, so the scrollbar is a limit
   rather than the normal reading experience.

   The bar stays full-bleed against the bottom edge, but the text inside it is
   capped at the same 48rem measure the resume uses for prose: on a wide screen
   an uncapped centered caption runs the whole viewport as one line, which is
   where a caption stops being readable. The cap is inline padding rather than a
   `max-width` so the background still spans the window; percentage padding
   resolves against `.pswp`, which is the full viewport, so it matches the bar's
   own width. Below 48rem the `max()` falls back to the plain 15px gutter. */
.pswp__custom-caption {
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  font-size: var(--text-sm);
  line-height: 1.5;
  padding: 10px max(15px, calc((100% - 48rem) / 2));
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  text-align: center;
  display: block;
  opacity: 0;
  /* Overrides the shared opacity-only transition above so the scrim darkens
     in step with the text height rather than snapping. */
  transition: opacity 0.3s ease, background-color 0.3s ease;
}

/* Expanding darkens the bar and lets it climb the photo, since at that point
   the text is what's being looked at. 70vh is the ceiling; the overflow only
   engages past it. */
.pswp__custom-caption.is-expanded {
  background: rgba(0, 0, 0, 0.9);
  max-height: 70vh;
  overflow: auto;
}

/* Title reads as a heading over the caption text below it. */
.pswp__custom-caption-title {
  display: block;
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
}

/* Collapsed, the caption shows two lines. The clip is a height cut rather than
   `-webkit-line-clamp` because line-clamp places its ellipsis wherever the line
   happens to overflow, which is usually the middle of a word. Cutting at two
   line-heights instead lets the text wrap normally and hides the third line
   whole, so the last thing read is always a complete word. `lh` is exactly that
   height whatever the line-height is set to; the `em` before it is the
   equivalent of the current 1.5 for anything that doesn't know the unit.

   The height is transitioned rather than the bar's, because `height: auto`
   isn't animatable: expanding sets an explicit pixel height from the measured
   content (see the controller), and the bar, being bottom-anchored and sized by
   its content, slides up to follow. */
.pswp__custom-caption-text {
  display: block;
  max-height: 3em;
  max-height: 2lh;
  overflow: hidden;
  transition: max-height 0.3s ease;
  /* Honors paragraph breaks in a caption, matching how the photo page renders
     the same text. */
  white-space: pre-wrap;
}

/* Only when both are present, so a caption with no title keeps its own
   padding as the only gap above it. */
.pswp__custom-caption-title + .pswp__custom-caption-text {
  margin-top: 0.15rem;
}

@media (prefers-reduced-motion: reduce) {
  .pswp__custom-caption,
  .pswp__custom-caption-text {
    transition: none;
  }
}

/* "More"/"Less" cue, rendered only when the text is actually clamped. The
   controller sets `.is-clampable` after measuring, so a caption that already
   fits in two lines gets no affordance and no pointer cursor. */
.pswp__custom-caption.is-clampable {
  cursor: pointer;
}

.pswp__custom-caption.is-clampable::after {
  content: "More";
  display: block;
  margin-top: 0.25rem;
  font-size: var(--text-xs);
  color: rgba(255, 255, 255, 0.65);
}

.pswp__custom-caption.is-clampable.is-expanded::after {
  content: "Less";
}

/* Clicking toggles the chrome rather than zooming, so don't show a zoom
   cursor over the image. */
.pswp__img,
.pswp--zoom-allowed .pswp__img,
.pswp--zoomed-in .pswp__img { cursor: default; }

/* Host <dialog> PhotoSwipe is appended to when the lightbox is opened from
   inside another <dialog> (e.g. the admin selection modal), so it can paint
   above that dialog's own top layer. */
dialog.pswp-host-dialog {
  margin: 0;
  padding: 0;
  border: none;
  width: 100vw;
  max-width: none;
  height: 100vh;
  max-height: none;
  background: transparent;
  overflow: visible;
}

dialog.pswp-host-dialog::backdrop {
  background: transparent;
}
