/**
 * Gallery marquee + lightbox.
 *
 * Loaded only on pages whose gallery block asked for the marquee (see includes/gallery.php);
 * the grid treatment in blocks.css is untouched and still serves the case study gallery.
 *
 * The strip is edge to edge, every frame is the same landscape crop, and the row scrolls
 * continuously.
 *
 * It was a dark band with the frames shoulder to shoulder and no notch, because the chamfer
 * read as damage with no gutter between frames. Wayne asked for white, spaced and notched on
 * 25 Sep — and the space is what makes the notch work, so the two go together.
 *
 * THE GAP IS A MARGIN, NOT `gap`. The loop is two identical halves and the animation lands on
 * `-50%`, which is only a repeat boundary if half the track is exactly half its width. A flex
 * `gap` puts N-1 gutters across 2N frames, so -50% falls a half-gutter short and the row
 * visibly jumps every cycle. A trailing margin on each frame makes it 2N x (frame + gutter),
 * and -50% is exact again.
 */

/* ── the band ─────────────────────────────────────────────────────────────────────────── */

.pwr-b-gallery--marquee {
	/* The bleed itself is WordPress's: render.php gives the section `alignfull`, and core's
	   `.has-global-padding > .alignfull` rule pulls it out past the root padding. Doing it
	   here instead with `width: 100vw` and a negative margin looked right in isolation and
	   lost on the real page — the constrained-layout rule that pins a block to the content
	   rail carries `margin-left: auto !important`, so the only way past it is to be a block
	   the rule excludes, which is what alignfull is for. */
	/* No band of its own since 1 Oct: the site ground is Deep Grey and bands are removed,
	   so the strip sits straight on the page and inherits the page's light ink. */
	background: transparent;
	color: inherit;
	/* Block padding only. Inline padding would inset the photos and lose the bleed, which is
	   the point of the strip — the frames run off both edges and keep going. */
	padding-block: var(--wp--preset--spacing--xl);
	/* Clips the track's overhang. */
	overflow: hidden;
}

/* The product template spaces its sections with main's XXL blockGap (Wayne, 2 Oct), so the
   strip's own band padding stacked on top of it and read as a hole. The case-study single
   still relies on that padding (its gallery is "a full-bleed strip carrying its own band
   padding"), so the removal is scoped to products. */
body.single-product .pwr-b-gallery--marquee {
	padding-block: 0;
}

/* The heading stays on the page's rail even though the strip below it does not, so it lines
   up with every other section heading on the product page.

   Not `--wp--style--global--wide-size`: on this theme that is 1440px, the full viewport, so
   constraining to it did nothing and the heading sat 72px left of everything else. The rail is
   the product template's post-content contentSize, which WordPress emits as a bare max-width on
   a generated `.wp-container-…` class rather than as a custom property, so there is nothing to
   read it from — hence the local token. Retune it here if that template changes.

   `min()` rather than max-width + padding so the heading sits ON the rail rather than one
   gutter inside it, and still keeps its distance from the edge on a phone. */
/* Two classes were needed when this band was ink and theme.json's elements.h2 ink colour won
   against a single class. The band is white now and the heading is ink again, but the pair is
   kept: it is the specificity that makes the colour below reliable either way. */
/* On an ink band (the product page's dark half, ticket #826) the strip stops painting its own
   white and takes the band's colours. */
.has-contrast-background-color .pwr-b-gallery--marquee { background: transparent; color: inherit; }
.has-contrast-background-color .pwr-b-gallery--marquee .pwr-b-gallery__title.pwr-b-gallery__title { color: inherit; }

.pwr-b-gallery--marquee .pwr-b-gallery__title {
	--pwr-gal-rail: 1200px;
	--pwr-gal-edge: var(--wp--style--root--padding-left, var(--wp--preset--spacing--m, 24px));

	width: min(var(--pwr-gal-rail), 100% - var(--pwr-gal-edge) * 2);
	margin-inline: auto;
	margin-block: 0 var(--wp--preset--spacing--l);
	text-align: center;
	color: inherit;
}

/* ── the track ────────────────────────────────────────────────────────────────────────── */

/* The row height is the one constant every gallery on the site shares, so it is declared on
   the SECTION class rather than on the marquee's track: the case study media carries
   .pwr-b-gallery too and sizes its frames from this, so the two cannot end up at different
   scales (Wayne, 14 Oct: the case study photos were taller than the product strip). */
.pwr-b-gallery {
	--pwr-gal-h: clamp(200px, 26vw, 380px);
}

.pwr-b-gallery__track {
	--pwr-gal-gap: var(--wp--preset--spacing--m);
	/* Seconds per frame. Duration is this times the number of frames in one half, so the
	   strip travels at the same speed whether a product has three photos or twelve.
	   7s, up from 4s — slower scroll, the 1 Oct meeting's call, Wayne 2 Oct. */
	--pwr-gal-pace: 7s;

	display: flex;
	/* NOT `gap` — see the header. The gutter rides on each frame instead. */
	width: max-content;
	margin: 0;
	padding: 0;
	list-style: none;
	will-change: transform;
	animation: pwr-gal-marquee calc(var(--pwr-gal-pace) * var(--pwr-gal-count, 6)) linear infinite;
}

/* The track is two identical halves, so -50% lands exactly on a repeat boundary and the
   loop has no seam. render.php pads short sets out so one half always overruns the
   viewport — two photos would otherwise leave a visible gap chasing the row. */
@keyframes pwr-gal-marquee {
	from { transform: translate3d(0, 0, 0); }
	to   { transform: translate3d(-50%, 0, 0); }
}

/* Hovering to look at a photo, or tabbing to one, should not be a moving target. Keyboard
   focus only (:focus-visible): a mouse click on an arrow leaves the button focused, and
   :focus-within would then hold the strip still until the visitor clicked somewhere else.
   And a photo open in the lightbox stops it until the lightbox closes (gallery.js). */
.pwr-b-gallery--marquee:hover .pwr-b-gallery__track,
.pwr-b-gallery--marquee:has(:focus-visible) .pwr-b-gallery__track,
.pwr-lightbox-open .pwr-b-gallery__track {
	animation-play-state: paused;
}

/* Back/next under the strip, on the page's rail like the heading above it — the carousel's
   buttons and nav (carousel.css), right-aligned. */
.pwr-b-gallery--marquee .pwr-b-gallery__nav {
	width: min(1200px, 100% - var(--wp--style--root--padding-left, var(--wp--preset--spacing--m, 24px)) * 2);
	margin-inline: auto;
	margin-block-start: var(--wp--preset--spacing--m);
}

/* ── the frames ───────────────────────────────────────────────────────────────────────── */

/* Natural ratios since 2 Oct (meeting: respect the originals; mixed portrait/landscape
   accepted). The row height is still the one constant — each frame's WIDTH now follows its
   own photo instead of forcing the 16:10 crop. The resets are EXPLICIT because the shared
   grid-gallery rules in blocks.css set the crop at one class deep — removing the
   declarations here just let those stand (measured: every frame 599px with uneven gaps). */
.pwr-b-gallery--marquee .pwr-b-gallery__item {
	flex: 0 0 auto;
	position: relative;
	height: var(--pwr-gal-h);
	aspect-ratio: auto;
	margin-inline-end: var(--pwr-gal-gap);
	/* The notch from blocks.css applies now: with a gutter between frames the cut reads as
	   the brand's corner rather than as a chipped edge. */
	overflow: hidden;
}

.pwr-b-gallery__link {
	display: block;
	width: 100%;
	height: 100%;
	cursor: zoom-in;
}

.pwr-b-gallery--marquee .pwr-b-gallery__item img {
	position: static;
	inset: auto;
	display: block;
	width: auto;
	height: 100%;
	object-fit: unset;
	transition: transform 0.4s ease, filter 0.4s ease;
}

.pwr-b-gallery__link:hover img,
.pwr-b-gallery__link:focus-visible img {
	transform: scale(1.04);
}

.pwr-b-gallery__link:focus-visible {
	outline: 3px solid var(--wp--preset--color--orange);
	outline-offset: -3px;
}

/* ── one photo ────────────────────────────────────────────────────────────────────────── */

/* Nothing to loop, so nothing moves. It keeps the band, the crop and the click to enlarge —
   what it does not keep is a single frame jumping back to itself every few seconds. */
.pwr-b-gallery--still .pwr-b-gallery__track {
	animation: none;
	width: 100%;
}

.pwr-b-gallery--still .pwr-b-gallery__item {
	flex: 1 1 100%;
	aspect-ratio: auto;
	height: var(--pwr-gal-h);
	/* Nothing follows it, so the trailing gutter would just push it off the right edge. */
	margin-inline-end: 0;
}

/* ── a short set (2–3 photos): a still row ───────────────────────────────────────────── */

/* The scroll is earned at four (Wayne, 7 Oct): under that, a padded-out loop is a gimmick.
   Same frames, same band height, nothing moving. The row centres when it fits the band and
   becomes an ordinary swipeable row when it does not — exactly what the reduced-motion
   fallback below already does to the marquee. */
.pwr-b-gallery--row {
	overflow-x: auto;
	scroll-snap-type: x proximity;
}

.pwr-b-gallery--row .pwr-b-gallery__track {
	animation: none;
	width: max-content;
	margin-inline: auto;
}

.pwr-b-gallery--row .pwr-b-gallery__item {
	scroll-snap-align: start;
}

/* ── captions ─────────────────────────────────────────────────────────────────────────── */

.pwr-b-gallery__figure {
	margin: 0;
	width: 100%;
	height: 100%;
}

/* An orange BADGE, not a scrim (Wayne + the 1 Oct meeting: caption as a badge overlay, the
   gradient goes). It sits off the photo's bottom-left corner, square like every badge —
   the chamfer means clickable, and a caption is a label. Ink on orange, the badge system's
   own pairing (Wayne, 2 Oct — white fell short of contrast).

   ONE LINE, at most two thirds of the photo, cut with an ellipsis, and a plus at its end that
   says "there is more — open it" (web catch-up, 23 Oct; it was up to three lines that morning
   and the badge ate the photo). The whole photo is the lightbox link, badge included, and the
   lightbox shows the caption whole. The words are their own span so the ellipsis cuts them
   and never the plus. */
.pwr-b-gallery__caption {
	position: absolute;
	left: var(--wp--preset--spacing--s);
	bottom: var(--wp--preset--spacing--s);
	box-sizing: border-box; /* the cap is the badge's whole width, padding and plus included */
	max-width: min(66.666%, calc(100% - 2 * var(--wp--preset--spacing--s)));
	z-index: 1;
	margin: 0;
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--xs);
	padding: var(--wp--preset--spacing--xs) var(--wp--preset--spacing--s);
	background: var(--wp--preset--color--orange, #f58228);
	color: var(--wp--preset--color--contrast, #0f212c);
	font-size: var(--wp--preset--font-size--xs, 0.6875rem);
	font-weight: 700;
	letter-spacing: var(--wp--custom--tracking--normal, 0.04em);
	text-transform: uppercase;
	line-height: 1.35;
	text-align: left;
}
.pwr-b-gallery__caption-text {
	min-width: 0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
/* No caption: the box is just the plus, square. */
.pwr-b-gallery__caption--bare { padding: var(--wp--preset--spacing--xs); }
/* The plus: two bars in the ink colour, drawn rather than typed so it sits dead centre at any
   size and cannot pick up the caption's letter-spacing. */
.pwr-b-gallery__caption::after {
	content: "";
	flex: none;
	width: 0.9em;
	height: 0.9em;
	background:
		linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat,
		linear-gradient(currentColor, currentColor) center / 2px 100% no-repeat;
}

/* ── motion off ───────────────────────────────────────────────────────────────────────── */

/* A strip the visitor cannot stop is the worst case for this pattern, so when motion is
   declined the row stops being an animation and becomes an ordinary swipeable one — every
   photo still reachable, nothing moving on its own. The duplicate half is hidden so the
   same photo does not appear twice in a row the visitor is scrolling by hand. */
@media (prefers-reduced-motion: reduce) {
	.pwr-b-gallery--marquee { overflow-x: auto; scroll-snap-type: x mandatory; }
	/* The nav scrolls the strip by hand here, so it must not ride away with it. */
	.pwr-b-gallery--marquee .pwr-b-gallery__nav { position: sticky; left: 0; }
	.pwr-b-gallery__track { animation: none; }
	.pwr-b-gallery__track > [aria-hidden="true"] { display: none; } /* the slides only — not what is inside them */
	.pwr-b-gallery--marquee .pwr-b-gallery__item { scroll-snap-align: start; }
}

/* ── lightbox ─────────────────────────────────────────────────────────────────────────── */

/* A <dialog>: the browser gives the modal backdrop, the focus trap, Esc to close and the
   inert background for free, all of which are fiddly and easy to get subtly wrong by hand.
   gallery.js falls back to doing nothing if showModal() is missing, and the frames are
   real links to the full-size file, so that degrades to opening the image. */
.pwr-lightbox {
	width: min(94vw, 1600px);
	max-width: none;
	max-height: 94vh;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--wp--preset--color--base, #fff);
	overflow: visible;
}

.pwr-lightbox::backdrop {
	background: rgb(15 33 44 / 0.92);
}

.pwr-lightbox__figure {
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--s, 0.75rem);
	align-items: center;
}

.pwr-lightbox__img {
	display: block;
	max-width: 100%;
	max-height: 82vh;
	width: auto;
	height: auto;
	object-fit: contain;
}

/* The same badge the strip's captions wear (Wayne, 2 Oct): orange plate, ink, small caps.
   Centred under the photo as its own chip rather than a text line. */
.pwr-lightbox__caption {
	margin: var(--wp--preset--spacing--s, 0.75rem) auto 0;
	width: fit-content;
	max-width: 100%;
	padding: var(--wp--preset--spacing--xs, 0.5rem) var(--wp--preset--spacing--s, 0.75rem);
	background: var(--wp--preset--color--orange, #f58228);
	color: var(--wp--preset--color--contrast, #0f212c);
	font-size: var(--wp--preset--font-size--xs, 0.6875rem);
	font-weight: 700;
	letter-spacing: var(--wp--custom--tracking--normal, 0.04em);
	text-transform: uppercase;
	line-height: 1.35;
	text-align: center;
	overflow-wrap: anywhere;
}

.pwr-lightbox__count {
	font-variant-numeric: tabular-nums;
	opacity: 0.7;
}

.pwr-lightbox__btn {
	position: absolute;
	z-index: 1;
	display: grid;
	place-items: center;
	width: 3rem;
	height: 3rem;
	padding: 0;
	border: 0;
	cursor: pointer;
	color: inherit;
	background: rgb(15 33 44 / 0.6);
	transition: background 0.2s ease;
}

.pwr-lightbox__btn:hover,
.pwr-lightbox__btn:focus-visible {
	/* background-color, never the shorthand: prev/next carry the brand arrow as a
	   background-image, and the shorthand erased it on hover. */
	background-color: var(--wp--preset--color--orange, #f58228);
}
/* The arrow is brand orange with its colour baked in, so the hover plate deepens to ink
   instead of going orange-on-orange. */
.pwr-lightbox__prev:hover,
.pwr-lightbox__prev:focus-visible,
.pwr-lightbox__next:hover,
.pwr-lightbox__next:focus-visible {
	background-color: rgb(15 33 44 / 0.92);
}

.pwr-lightbox__btn svg { width: 1.25rem; height: 1.25rem; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }

/* Prev/next wear the brand double-chevron (arrow-right.svg beside this file — a theme-side
   copy of the media library's arrows-orange-right, so launch cannot lose it). The mark has
   its orange baked in; prev is the same file mirrored. */
.pwr-lightbox__prev,
.pwr-lightbox__next {
	background-image: url(arrow-right.svg);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 1.4rem 1.4rem;
}

.pwr-lightbox__close { top: calc(var(--wp--preset--spacing--s, 0.75rem) * -1); right: 0; }
/* prev mirrors the arrow in the same transform that centres it. */
.pwr-lightbox__prev  { left: 0;  top: 50%; transform: translateY(-50%) scaleX(-1); }
.pwr-lightbox__next  { right: 0; top: 50%; transform: translateY(-50%); }

/* One photo: the arrows would be a dead control, so they are not rendered at all. */
.pwr-lightbox.is-single .pwr-lightbox__prev,
.pwr-lightbox.is-single .pwr-lightbox__next { display: none; }

@media (prefers-reduced-motion: reduce) {
	.pwr-lightbox__btn,
	.pwr-b-gallery--marquee .pwr-b-gallery__item img { transition: none; }
	.pwr-b-gallery__link:hover img,
	.pwr-b-gallery__link:focus-visible img { transform: none; }
}
