/**
 * Product image gallery.
 *
 * Partner of template-parts/product/gallery.php and assets/js/gallery.js. Replaces the
 * legacy slider entirely: no library, no jQuery, no inline <style>.
 *
 * The navigation mechanism is CSS, not script. The track is a scroll-snapping flex row,
 * so a touch user swipes it and a keyboard user scrolls it (the track is focusable).
 * The JavaScript only teaches the thumbnail buttons to scroll the track and keeps
 * aria-current in sync — with it disabled, every image is still reachable.
 *
 * Deliberately absent: opacity-0 prev/next arrows that appear on :hover. On a touch
 * device there is no hover, so those controls are either permanently invisible or
 * permanently stuck visible after a tap. Swipe plus thumbnails covers the same ground
 * without the trap.
 *
 * Colours are the theme's design tokens only — never a raw hex. The base stylesheet
 * redefines those tokens under prefers-color-scheme: dark, so this component follows
 * the colour scheme with no dark-mode rules of its own.
 *
 * @package Bedi\Theme
 */

/* -------------------------------------------------------------------------- *
 * Component scope and local metrics
 * -------------------------------------------------------------------------- */

.bedi-gallery {
	--bedi-gallery-thumb-size: 70px;
	--bedi-gallery-thumb-gap: 0.5rem;
	/*
	 * HOW MANY THUMBNAILS THE RAIL SHOWS BEFORE IT SCROLLS.
	 *
	 * A token rather than a number baked into the cap, because the honest
	 * answer differs by width: four rows of 70px fit beside a desktop
	 * photograph, and on a phone the same four rows would stand taller than
	 * the 263px image they belong to. The phone block below says 3.
	 */
	--bedi-gallery-rail-rows: 4;
	--bedi-gallery-radius: 4px;

	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	color: var(--bedi-ink);
}

/* -------------------------------------------------------------------------- *
 * The track
 * -------------------------------------------------------------------------- */

.bedi-gallery__track {
	display: flex;
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	/* Stops a swipe past the last image from scrolling the page or triggering back-nav. */
	overscroll-behavior-inline: contain;
/*
 * WHITE, NOT --bedi-muted.
 *
 * The track, the slide and the thumbnails all sat on #F9F9F9. On a product
 * photographed against white — which is every catalogue shot this shop has —
 * that draws a faint grey panel around the subject and a grey square behind
 * each thumbnail, so the picture reads as a tile on a card rather than as the
 * product itself. The radius and the border still define the shape; the fill
 * does not need to.
 */
	border-radius: var(--bedi-gallery-radius);
	background-color: var(--bedi-surface);
	/* The thumbnails are the visible affordance; the scrollbar would only add noise. */
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.bedi-gallery__track::-webkit-scrollbar {
	display: none;
}

/* The track is a focusable scroll container, so it needs a visible focus ring. */
.bedi-gallery__track:focus-visible {
	outline: 2px solid var(--bedi-accent);
	outline-offset: 2px;
}

.bedi-gallery__slide {
	flex: 0 0 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	margin: 0;
	aspect-ratio: 1 / 1;
	scroll-snap-align: center;
	scroll-snap-stop: always;
}

/*
 * Product photography here is mixed portrait and landscape, so contain rather than
 * cover: cropping a spec sheet or a boxed item loses the part the customer came for.
 * The explicit 100%/100% overrides the intrinsic width/height attributes on the <img>,
 * which are there for layout reservation, not for final sizing.
 */
.bedi-gallery__image {
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
}

/* -------------------------------------------------------------------------- *
 * Single image
 *
 * Same stage, no track, no thumbnails. The PHP does not even emit them.
 * -------------------------------------------------------------------------- */

.bedi-gallery__solo {
	display: flex;
	align-items: center;
	justify-content: center;
	margin: 0;
	aspect-ratio: 1 / 1;
	border-radius: var(--bedi-gallery-radius);
	background-color: var(--bedi-surface);
}

/* -------------------------------------------------------------------------- *
 * Thumbnails
 * -------------------------------------------------------------------------- */

.bedi-gallery__thumbs {
	display: flex;
	gap: var(--bedi-gallery-thumb-gap);
	overflow-x: auto;
	padding-block-end: 2px;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.bedi-gallery__thumbs::-webkit-scrollbar {
	display: none;
}

.bedi-gallery__thumb {
	flex: 0 0 auto;
	display: block;
	inline-size: var(--bedi-gallery-thumb-size);
	block-size: var(--bedi-gallery-thumb-size);
	padding: 0;
	border: 2px solid transparent;
	border-radius: var(--bedi-gallery-radius);
	background-color: var(--bedi-surface);
	cursor: pointer;
	transition: border-color 160ms ease;
	/* Suppresses the tap-highlight flash on iOS without removing any real feedback. */
	-webkit-tap-highlight-color: transparent;
}

.bedi-gallery__thumb:hover {
	border-color: var(--bedi-accent);
}

.bedi-gallery__thumb[aria-current="true"] {
	border-color: var(--bedi-ink);
}

.bedi-gallery__thumb:focus-visible {
	outline: 2px solid var(--bedi-accent);
	outline-offset: 2px;
}

.bedi-gallery__thumb-image {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	border-radius: 2px;
}

/* -------------------------------------------------------------------------- *
 * The vertical thumbnail rail
 *
 * From 48em up the thumbnails move to a column on the LEFT of the main image,
 * which is the shape every large catalogue uses and the one the client asked
 * for. Below that they stay a horizontal strip underneath: a 70px column on a
 * 375px screen is a fifth of the width spent on navigation, and the main image
 * is the thing a phone has least room for.
 *
 * ORDER RATHER THAN A DOM CHANGE. The track comes first in the markup and the
 * thumbs second, and that stays true at both widths — one DOM, two layouts. It
 * does mean the visual order (thumbs, then image) differs from the tab order
 * (image, then thumbs) on wide screens. That is the deliberate trade: the main
 * image is the primary content and reaching it first by keyboard is right even
 * when it sits second from the left, and reordering the markup would put a
 * navigation list before the figure it navigates on phones too, where it is
 * genuinely below.
 * -------------------------------------------------------------------------- */

/*
 * THE RAIL IS NOW VERTICAL AT EVERY WIDTH, INCLUDING PHONES.
 *
 * This block used to start at 48em, on the argument that a 70px column is a
 * fifth of a 375px screen and the main image has least room there. The client
 * asked for the rail on the phone too, and the argument answers itself once the
 * thumbnails shrink: at 44px the rail costs 52px of 375 — fourteen per cent —
 * and it buys back the vertical space the horizontal strip was spending under
 * the image, which on a phone is the scarcer of the two.
 */
@media (min-width: 48em) {

	.bedi-gallery:not(.bedi-gallery--single) {
		align-items: flex-start;
		flex-direction: row;
	}


	.bedi-gallery__track {
		flex: 1 1 auto;
		min-inline-size: 0;
	}

	/*
	 * The stretch that makes the rail match the image. align-items: flex-start
	 * on the parent keeps the rail from stretching when there are only two
	 * thumbnails, and this overrides it for the track alone.
	 */
	.bedi-gallery:not(.bedi-gallery--single) .bedi-gallery__track {
		align-self: stretch;
	}
}

/* -------------------------------------------------------------------------- *
 * Narrower viewports
 * -------------------------------------------------------------------------- */

@media (max-width: 1024px) {

	.bedi-gallery {
		--bedi-gallery-thumb-size: 60px;
	}
}

@media (max-width: 600px) {

	.bedi-gallery {
		--bedi-gallery-thumb-size: 52px;
	}
}

/* -------------------------------------------------------------------------- *
 * Reduced motion
 *
 * The CSS half of the contract; gallery.js passes behavior: 'auto' to scrollIntoView
 * under the same query, because scroll-behavior on the container does not govern a
 * scroll that explicitly asks for smooth.
 * -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
 * THE THUMBNAIL RAIL
 *
 * Unmediated on purpose. The rail is a vertical column at every width — the
 * desktop block above and the phone block below both say so — and the first
 * draft of this put the cap and the arrows inside `min-width: 48em`, which
 * meant the phone got a scroller with no affordance and no controls. The only
 * genuinely width-dependent things are the thumbnail size and the row count,
 * and both are tokens.
 * -------------------------------------------------------------------------- */

/*
 * THE RAIL IS THE COLUMN NOW; the nav inside it is only the scroller.
 * `order: -1` puts it left of the track without touching the markup.
 */
.bedi-gallery__rail {
	order: -1;
	flex: 0 0 var(--bedi-gallery-thumb-size);
	position: relative;
}

.bedi-gallery__thumbs {
	flex-direction: column;
	/*
	 * FOUR THUMBNAILS AND A HAIR OF THE FIFTH.
	 *
	 * The phone rule used to say `max-block-size: 100%` and mean "no taller
	 * than the photograph". It never did anything: a percentage height
	 * resolves against the containing block, the gallery row has no definite
	 * height of its own, so the percentage resolves to none and ten
	 * thumbnails simply drew ten thumbnails. The only clue that it scrolled
	 * was that it stopped.
	 *
	 * An explicit cap is what makes the overflow legible before you touch
	 * it — the cut-off next row is the affordance, the arrow is the control.
	 *
	 * rows x size + (rows - 1) gaps + a 24px peek of the row after.
	 */
	max-block-size: calc(
		var(--bedi-gallery-thumb-size) * var(--bedi-gallery-rail-rows)
		+ var(--bedi-gallery-thumb-gap) * (var(--bedi-gallery-rail-rows) - 1)
		+ 24px
	);
	overflow-x: visible;
	overflow-y: auto;
	padding-block-end: 0;
	padding-inline-end: 2px;
	scroll-behavior: smooth;
	/* Snap so a nudge lands on a thumbnail, not between two. */
	scroll-snap-type: y proximity;
}

.bedi-gallery__thumb { scroll-snap-align: start; }

/*
 * The arrows sit ON the rail, not in the scroller — see the note in
 * gallery.php. Down is pinned to the bottom edge with a fade behind it so
 * the thumbnail it covers still reads as a thumbnail continuing under it,
 * rather than as the end of the list.
 */
.bedi-gallery__railbtn {
	align-items: center;
	-webkit-appearance: none;
	appearance: none;
	background-color: var(--bedi-surface);
	border: var(--bedi-border-width) solid var(--bedi-rule);
	border-radius: var(--bedi-radius-round);
	block-size: 28px;
	color: var(--bedi-ink);
	cursor: pointer;
	display: flex;
	inline-size: 28px;
	inset-inline-start: 50%;
	justify-content: center;
	padding: 0;
	position: absolute;
	transform: translateX(-50%);
	transition:
		background-color var(--bedi-dur-micro) var(--bedi-ease-out),
		color var(--bedi-dur-micro) var(--bedi-ease-out);
	z-index: 2;
}

.bedi-gallery__railbtn:hover {
	background-color: var(--bedi-accent);
	border-color: var(--bedi-accent);
	color: #FFFFFF;
}

.bedi-gallery__railbtn[hidden] { display: none; }

.bedi-gallery__railbtn--up   { inset-block-start: -6px; }
.bedi-gallery__railbtn--down { inset-block-end: -6px; }

/*
 * The fade under the bottom arrow. A pseudo-element on the RAIL rather
 * than on the scroller, for the same reason the buttons are: anything
 * inside the nav scrolls with it.
 *
 * Gated on the attribute the script sets from a real measurement, not on
 * the buttons being in the markup. The markup cannot know whether a given
 * rail overflows — that depends on the rendered thumbnail size, which
 * depends on the viewport — so anything printed server-side would be a
 * guess, and a fade over a rail that does not scroll reads as a bug.
 */
.bedi-gallery__rail[data-bedi-rail-overflow]::after {
	background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--bedi-surface));
	block-size: 44px;
	content: "";
	inset-block-end: 0;
	inset-inline: 0;
	pointer-events: none;
	position: absolute;
	z-index: 1;
}

@media (prefers-reduced-motion: reduce) {

	.bedi-gallery__track {
		scroll-behavior: auto;
	}

	.bedi-gallery__thumb {
		transition: none;
	}
}

/* -------------------------------------------------------------------------- *
 * The rail on a phone
 *
 * Same shape as the desktop rail, smaller: 44px thumbnails in a column to the
 * left of the image rather than a strip beneath it. Scoped to below 48em so it
 * cannot touch the desktop rules above, which are already correct.
 * -------------------------------------------------------------------------- */

@media (max-width: 47.9375em) {

	.bedi-gallery {
		/* 44px was cautious. 64px reads as a picture rather than a swatch, and
		   still leaves the main image 271px of a 375px screen. */
		--bedi-gallery-thumb-size: 64px;
		--bedi-gallery-thumb-gap: 10px;
	}

	.bedi-gallery:not(.bedi-gallery--single) {
		align-items: flex-start;
		flex-direction: row;
		/* The rail and the image are two separate objects; 8px read as one
		   object with a seam down it. */
		gap: 14px;
	}

	.bedi-gallery {
		/*
		 * Three rows, not four. 4 x 64 + 3 x 10 + 24 = 310px, and the image
		 * next to it is 263px square on a 375px screen — the rail would
		 * overhang the photograph it belongs to. Three rows come to 236px.
		 */
		--bedi-gallery-rail-rows: 3;
	}

	/*
	 * ORDER AND FLEX BELONG TO THE RAIL, NOT TO THE NAV.
	 *
	 * These two declarations used to sit on `.bedi-gallery__thumbs` and were
	 * correct while the nav was itself the flex item. Wrapping it in the rail
	 * made them inert — the nav became a lone child of a new block — and the
	 * rail dropped to the right of the image with no visible cause.
	 */
	.bedi-gallery:not(.bedi-gallery--single) .bedi-gallery__rail {
		/* -1 puts the rail before the image without touching the markup, which
		   keeps the main image first in the DOM and first in the tab order. */
		order: -1;
		flex: 0 0 var(--bedi-gallery-thumb-size);
	}

	.bedi-gallery:not(.bedi-gallery--single) .bedi-gallery__track {
		align-self: stretch;
		flex: 1 1 auto;
		min-inline-size: 0;
	}
}
