/* ============================================================
   DJC_ProdImageGallery
   product image gallery: one slide on stage, arrows either side,
   dots underneath, a short fade between slides. the component owns
   the stage, the slide frames, the custom-slide card, the video
   cover and the fullscreen zoom. the page reskins through the
   --pgal-* knobs below and never restyles the parts. nothing here
   needs campaign-base, but the knobs read its tokens first when
   they are present.
   ============================================================ */
.djc-prod-image-gallery {
  /* knobs -- set these on the page to reskin */
  --pgal-stage-height: clamp(240px, 34vw, 430px);   /* reserved before the art decodes */
  --pgal-gap: clamp(8px, 1.4vw, 18px);              /* arrow to slide */
  --pgal-fade: 0.45s;
  --pgal-radius: 8px;
  --pgal-shadow: 0 18px 50px rgb(27 27 74 / 0.26);
  --pgal-cutout-shadow: drop-shadow(0 12px 26px rgb(27 27 74 / 0.22));
  --pgal-card-max: 560px;
  --pgal-card-bkg: #ffffff;
  --pgal-card-radius: var(--radius-md, 16px);
  --pgal-card-shadow: var(--boxshadow-card, 0 10px 30px rgb(27 27 74 / 0.18));
  --pgal-card-pad: clamp(18px, 2.6vw, 26px);
  --pgal-arrow-size: 46px;
  --pgal-arrow-bkg: #ffffff;
  --pgal-arrow-ink: var(--brand-dark, #1b1b4a);
  --pgal-arrow-ink-hover: var(--brand-1, #2a5298);
  --pgal-arrow-shadow: 0 6px 20px rgb(27 27 74 / 0.18);
  --pgal-dot-size: 11px;
  --pgal-dot: rgb(27 27 74 / 0.18);
  --pgal-dot-active: var(--brand-1, #2a5298);
  --pgal-video-max: 860px;
  --pgal-video-bkg: var(--brand-dark, #1b1b4a);
  --pgal-video-btn-bkg: #ffffff;
  --pgal-video-btn-ink: var(--brand-dark, #1b1b4a);
  --pgal-font-ui: var(--font-ui, var(--font-2, inherit));

  width: 100%;
}

/* ============================================================
   STAGE
   the arrows are flex siblings of the slide, so the row is only as
   wide as the art and there is nothing to recompute per slide. no
   scroll position is animated anywhere.
   ============================================================ */
.djc-prod-image-gallery__stage {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--pgal-gap);
  min-height: var(--pgal-stage-height);
  /* hands horizontal finger drags to the swipe handler, keeps vertical
     scrolling with the browser */
  touch-action: pan-y;
}

.djc-prod-image-gallery__slide {
  display: none;
  min-width: 0;
}

.djc-prod-image-gallery__slide.is-active {
  display: block;
  animation: djcProdImageGalleryFade var(--pgal-fade) ease;
}

@keyframes djcProdImageGalleryFade {
  from {
    opacity: 0;
    transform: scale(0.985);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.djc-prod-image-gallery__media {
  display: block;
}

.djc-prod-image-gallery__media--zoom {
  cursor: zoom-in;
}

.djc-prod-image-gallery__media--click {
  cursor: pointer;
}

.djc-prod-image-gallery__media--zoom:focus-visible,
.djc-prod-image-gallery__media--click:focus-visible {
  outline: 3px solid var(--pgal-dot-active);
  outline-offset: 4px;
  border-radius: var(--pgal-radius);
}

/* ============================================================
   IMAGE SLIDES
   ============================================================ */
.djc-prod-image-gallery__img {
  display: block;
  margin: 0 auto;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: var(--pgal-stage-height);
  border-radius: var(--pgal-radius);
  box-shadow: var(--pgal-shadow);
}

/* a transparent product render carries its shadow in the pixels -- a
   radius and a box shadow would frame the empty corners */
.djc-prod-image-gallery__img--cutout {
  border-radius: 0;
  box-shadow: none;
  filter: var(--pgal-cutout-shadow);
}

/* ============================================================
   CUSTOM SLIDES
   the gallery draws the card; the slide's own html fills it.
   __custom--bare drops the card for html that brings its own frame.
   ============================================================ */
.djc-prod-image-gallery__slide--custom {
  width: 100%;
  max-width: var(--pgal-card-max);
}

.djc-prod-image-gallery__custom {
  box-sizing: border-box;
  width: 100%;
  padding: var(--pgal-card-pad);
  border-radius: var(--pgal-card-radius);
  background: var(--pgal-card-bkg);
  box-shadow: var(--pgal-card-shadow);
}

.djc-prod-image-gallery__custom--bare {
  padding: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

/* ============================================================
   VIDEO SLIDES
   a muted poster frame under a Watch Now cover. the cover goes once
   the video starts, and the native controls take over.
   ============================================================ */
.djc-prod-image-gallery__slide--video {
  width: 100%;
  max-width: var(--pgal-video-max);
}

.djc-prod-image-gallery__video {
  position: relative;
  width: 100%;
  border-radius: var(--pgal-radius);
  overflow: hidden;
  background: var(--pgal-video-bkg);
  box-shadow: var(--pgal-shadow);
}

.djc-prod-image-gallery__video-el {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* a slide ratio wins over the 16:9 default */
.djc-prod-image-gallery__media[style*="aspect-ratio"] .djc-prod-image-gallery__video,
.djc-prod-image-gallery__media[style*="aspect-ratio"] .djc-prod-image-gallery__video-el {
  height: 100%;
  aspect-ratio: auto;
}

.djc-prod-image-gallery__video-cover {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: rgb(27 27 74 / 0.25);
  cursor: pointer;
}

.djc-prod-image-gallery__video-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 52px;
  padding: 0 28px;
  border-radius: 999px;
  background: var(--pgal-video-btn-bkg);
  color: var(--pgal-video-btn-ink);
  font-family: var(--pgal-font-ui);
  font-size: 17px;
  font-weight: 700;
  box-shadow: 0 6px 20px rgb(27 27 74 / 0.18);
  transition: transform 0.2s ease-in-out;
}

.djc-prod-image-gallery__video-cover:hover .djc-prod-image-gallery__video-btn {
  transform: scale(1.04);
}

.djc-prod-image-gallery__video.is-playing .djc-prod-image-gallery__video-cover {
  display: none;
}

/* ============================================================
   CONTROLS
   ============================================================ */
.djc-prod-image-gallery__arrow {
  width: var(--pgal-arrow-size);
  height: var(--pgal-arrow-size);
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--pgal-arrow-bkg);
  color: var(--pgal-arrow-ink);
  font-size: 17px;
  cursor: pointer;
  box-shadow: var(--pgal-arrow-shadow);
  transition: transform 0.25s ease, color 0.25s ease;
}

.djc-prod-image-gallery__arrow:hover {
  transform: scale(1.08);
  color: var(--pgal-arrow-ink-hover);
}

.djc-prod-image-gallery__dots {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin-top: 22px;
}

.djc-prod-image-gallery__dot {
  width: var(--pgal-dot-size);
  height: var(--pgal-dot-size);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--pgal-dot);
  cursor: pointer;
  transition: transform 0.25s ease, background 0.25s ease;
}

.djc-prod-image-gallery__dot.is-active {
  background: var(--pgal-dot-active);
  transform: scale(1.25);
}

/* ============================================================
   ZOOM
   one fullscreen lightbox on body, shared by every gallery. it sits
   outside any gallery root, so its knobs live on its own class.
   z-index clears the media-player modal (10001).
   ============================================================ */
.djc-prod-image-gallery-zoom {
  --pgal-zoom-bkg: rgb(13 16 36 / 0.94);
  --pgal-zoom-close-bkg: rgb(255 255 255 / 0.16);
  --pgal-zoom-close-bkg-hover: rgb(255 255 255 / 0.3);

  display: none;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 10002;
  background: var(--pgal-zoom-bkg);
  touch-action: none;
  overscroll-behavior: contain;
  opacity: 0;
  transition: opacity 0.28s ease;
}

.djc-prod-image-gallery-zoom.is-open {
  display: block;
}

.djc-prod-image-gallery-zoom.is-shown {
  opacity: 1;
}

.djc-prod-image-gallery-zoom__img {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: auto;
  /* very little padding -- the art owns the screen */
  max-width: calc(100% - 12px);
  max-height: calc(100% - 12px);
  transform-origin: center center;
  will-change: transform;
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.djc-prod-image-gallery-zoom__img.is-loaded {
  opacity: 1;
}

.djc-prod-image-gallery-zoom__img.is-zoomed {
  cursor: grab;
}

.djc-prod-image-gallery-zoom__img.is-anim {
  transition: opacity 0.2s ease, transform 0.25s ease;
}

.djc-prod-image-gallery-zoom__close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--pgal-zoom-close-bkg);
  color: #ffffff;
  font-size: 20px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.djc-prod-image-gallery-zoom__close:hover {
  background: var(--pgal-zoom-close-bkg-hover);
}

/* stepping through the gallery from the zoom. the arrows and the count wear
   the close button's knobs, and stay hidden unless the zoom holds a set and
   the screen is a desktop's -- a phone keeps the one-image pinch zoom */
.djc-prod-image-gallery-zoom__arrow {
  display: none;
  position: absolute;
  top: 50%;
  z-index: 2;
  width: 52px;
  height: 52px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--pgal-zoom-close-bkg);
  color: #ffffff;
  font-size: 22px;
  cursor: pointer;
  transform: translateY(-50%);
  transition: background 0.2s ease;
}

.djc-prod-image-gallery-zoom__arrow:hover {
  background: var(--pgal-zoom-close-bkg-hover);
}

.djc-prod-image-gallery-zoom__arrow--prev {
  left: 24px;
}

.djc-prod-image-gallery-zoom__arrow--next {
  right: 24px;
}

.djc-prod-image-gallery-zoom__count {
  display: none;
  position: absolute;
  top: 24px;
  left: 0;
  right: 0;
  z-index: 1;
  margin: 0;
  text-align: center;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  color: rgb(255 255 255 / 0.8);
  pointer-events: none;
}

.djc-prod-image-gallery-zoom__arrow:focus-visible,
.djc-prod-image-gallery-zoom__close:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 3px;
}

@media (min-width: 761px) and (hover: hover) and (pointer: fine) {
  .djc-prod-image-gallery-zoom.is-set .djc-prod-image-gallery-zoom__arrow {
    display: flex;
  }

  .djc-prod-image-gallery-zoom.is-set .djc-prod-image-gallery-zoom__count {
    display: block;
  }

  /* room either side for the arrows, so they never sit on the art */
  .djc-prod-image-gallery-zoom.is-set .djc-prod-image-gallery-zoom__img {
    max-width: calc(100% - 200px);
    max-height: calc(100% - 96px);
  }
}

/* body scroll lock while the zoom is open. !important because page and
   sitewide sheets set body overflow too, and a lock that loses is no lock */
body.djc-prod-image-gallery-lock {
  overflow: hidden !important;
}

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .djc-prod-image-gallery__slide.is-active {
    animation: none;
  }

  .djc-prod-image-gallery__arrow,
  .djc-prod-image-gallery__dot,
  .djc-prod-image-gallery__video-btn,
  .djc-prod-image-gallery-zoom,
  .djc-prod-image-gallery-zoom__arrow,
  .djc-prod-image-gallery-zoom__img,
  .djc-prod-image-gallery-zoom__img.is-anim {
    transition: none;
  }
}
