/**
 * Image carousel (template-parts/components/image-carousel.php).
 *
 * The site's scroller edges, taken from .services__track rather than restated:
 * starts at the container line, bleeds off the right viewport edge, trailing
 * space that survives scrolling to the end, no visible scrollbar, snap.
 */

.image-carousel__track {
	/* REQUIRED, not decoration. carousel-track.js steps by comparing each
	   slide's offsetLeft against the track's scrollLeft, and offsetLeft is
	   measured from the nearest POSITIONED ancestor. Without this the track is
	   skipped and the slides report their offset from the page instead, so the
	   first slide reads 64 rather than 0, the arrows scroll to a position that
	   is not a snap point, and mandatory snap pulls it straight back: the
	   arrows appear to do nothing at all. .services__track carries the same
	   declaration for the same reason. */
	position: relative;
	/* Pushes the track's start to the container line while its box still runs
	   to the viewport edge. The expression is .services__track's, unchanged. */
	margin-left: calc((100% - min(var(--container-max), 100% - 2 * var(--container-pad))) / 2);
	display: flex;
	gap: 16px; /* the site's carousel gap */
	margin-block: 0;
	padding: 0;
	list-style: none;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	padding-inline-end: 4rem; /* 64px of trailing space at scroll end */
	scrollbar-width: none; /* arrows and snap are the affordance, per design */
}

.image-carousel__track::-webkit-scrollbar {
	display: none;
}

/* --------------------------------------------------------------------
 * Slide width: ALIGNMENT chosen over a constant peek
 *
 * The standing ruling: constant peek and container alignment are mutually
 * exclusive when the box width is container-derived, and alignment wins. So the
 * width is solved for two slides filling the container exactly -
 *
 *     2 slides + one 16px gap = the container
 *
 * - and the peek is then whatever is left between the container's right edge
 * and the viewport's. That is 48px at 1440 and it grows on a wider screen,
 * which is the trade alignment buys. Nothing is cut by it: the slides are
 * images, so a partial third has no word to break mid-way.
 * -------------------------------------------------------------------- */

.image-carousel__slide {
	flex: 0 0 calc((min(var(--container-max), 100vw - 2 * var(--container-pad)) - 16px) / 2);
	scroll-snap-align: start;
	min-width: 0;
}

/* cover, unlike everywhere else on this page, and the difference is that these
   are THUMBNAILS. contain letterboxed 75px of card surface into every slide -
   a 648x486 box holding a 411px render - which reads as a bug in a row of
   pictures. A crop is acceptable here precisely because the uncropped image is
   one click away in the lightbox, which is the whole point of the slide being
   a button. Nothing is lost, only framed.

   The 4:3 floor is what gives a row of mixed ratios one height; with cover it
   is also what the crop is measured against. */
.image-carousel__image {
	display: block;
	width: 100%;
	height: 100%;
	min-height: calc(((min(var(--container-max), 100vw - 2 * var(--container-pad)) - 16px) / 2) * 0.75);
	object-fit: cover;
	border-radius: 6px;
}

.image-carousel__nav {
	margin-top: 64px; /* the services carousel's nav offset */
	display: flex;
	justify-content: flex-end;
	gap: 12px; /* the services nav gap */
}

@media (max-width: 1024px) {
	/* One slide plus a peek, the site's convention at this width, and the same
	   84vw the other scrollers use so every carousel on the site shows the same
	   sliver of the next card. */
	.image-carousel__slide {
		flex-basis: calc(100vw - 5rem);
	}

	.image-carousel__image {
		min-height: calc((100vw - 5rem) * 0.75);
	}

	.image-carousel__nav {
		margin-top: 32px;
	}
}

/* --------------------------------------------------------------------
 * The slide's trigger
 *
 * The button IS the slide's box, so it carries no look of its own: a border
 * or a background here would draw a control around a picture. Only the focus
 * ring marks it, which is base.css's shared one.
 * -------------------------------------------------------------------- */

.image-carousel__open {
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	border-radius: 6px;
	background: none;
	cursor: pointer;
	/* So the ring follows the image's corners rather than a rectangle. */
	overflow: hidden;
}

/* --------------------------------------------------------------------
 * Framed variant: contain, matted, one height for the row
 *
 * CROP SCENES, LETTERBOX DOCUMENTS. Interface screenshots are documents whose
 * edges identify the screen, so they letterbox where a render would crop.
 *
 * THE ROW'S HEIGHT IS NOT DECLARED. The track is a flex row, so its items
 * already stretch to the tallest, and the tallest is whichever image is
 * naturally deepest at the slide width - the narrowest ratio in the set. Every
 * other slide then mats to that same height. Nothing here needs to know the
 * content's aspect, which is what stops a number derived from today's uploads
 * being wrong for tomorrow's.
 *
 * The min-height floor the cover variant uses is dropped for the same reason:
 * with contain it would fight the measured height rather than support it.
 * -------------------------------------------------------------------- */

.image-carousel--framed .image-carousel__slide {
	display: flex;
}

.image-carousel--framed .image-carousel__open {
	display: flex;
	flex: 1;
	padding: 32px; /* the card padding idiom; this box is a card holding a picture */
	background-color: var(--color-surface-card);
}

.image-carousel--framed .image-carousel__image {
	min-height: 0; /* the floor is the cover variant's, and it is wrong here */
	object-fit: contain;
	border-radius: 0; /* the frame owns the corners */
}

@media (max-width: 1024px) {
	.image-carousel--framed .image-carousel__open {
		padding: 16px; /* the mobile container inset */
	}
}
