/*
 * Photo gallery — a preset-coloured ribbon over a dark panel of photos, paged
 * with the same arrows and dots as the testimonials block, recoloured for the
 * dark panel. Three columns on desktop, two from tablet down; three rows always.
 */

.photo-gallery,
.photo-gallery *,
.photo-gallery *::before,
.photo-gallery *::after {
	box-sizing: border-box;
}

/* Full bleed: the ribbon and panel run edge to edge of the viewport, breaking
   out of whatever content width the page sets — same as the news listing banner.
   !important: core's constrained layout caps block widths otherwise. */
.photo-gallery {
	--photo-gallery-pad: 24px;
	--photo-gallery-gap: 12px;
	--photo-gallery-columns: 3;
	--photo-gallery-ribbon-height: 64px;

	width: 100vw;
	max-width: none !important;
	margin-inline: calc( 50% - 50vw ) !important;
}

/* Section header heights: 64px desktop, 44px laptop, 56px below. */
@media ( max-width: 1440px ) {
	.photo-gallery { --photo-gallery-ribbon-height: 44px; }
}
@media ( max-width: 1024px ) {
	.photo-gallery { --photo-gallery-ribbon-height: 56px; }
}

/* Shape and type live in src/components/section-ribbon.scss; the preset sets its colours. */
.photo-gallery .section-ribbon {
	--section-ribbon-accent: var(--photo-gallery-ribbon-bg, var(--red-1));
	--section-ribbon-justify: flex-end;
	--section-ribbon-padding-left: 0px;
	--section-ribbon-padding-right: 56px;
	--section-ribbon-height: var(--photo-gallery-ribbon-height);
	/* Half the ribbon hangs over the panel's top edge, per the comp. */
	position: relative;
	z-index: 1;
	margin-bottom: calc( var(--photo-gallery-ribbon-height) / -2 );
}

.photo-gallery .section-ribbon-text {
	--section-ribbon-font-size: 20px;
	--section-ribbon-font-family: var(--font-guildhall);
	--section-ribbon-font-weight: 500;
	color: var(--photo-gallery-ribbon-text, var(--white));
}

.photo-gallery__panel {
	display: grid;
	row-gap: 1.5rem;
	padding: var(--photo-gallery-pad);
	background-color: var(--gray-8);
}

/* Clears the half of the ribbon that overlaps the panel. */
.photo-gallery .section-ribbon + .photo-gallery__panel {
	padding-top: calc( var(--photo-gallery-pad) + var(--photo-gallery-ribbon-height) / 2 );
}

.photo-gallery .photo-gallery__swiper {
	width: 100%;
}

/* Grid layout before Swiper runs (and in the editor, where it never does),
   showing only the first page; Swiper's own grid takes over once it starts. */
.photo-gallery__swiper:not( .swiper-initialized ) .swiper-wrapper {
	display: grid;
	grid-template-columns: repeat( var(--photo-gallery-columns), minmax( 0, 1fr ) );
	gap: var(--photo-gallery-gap);
}

.photo-gallery__swiper:not( .swiper-initialized ) .photo-gallery__item:nth-child( n + 10 ) {
	display: none;
}

/* The ratio sets each photo's height; Swiper's height: 100% would override it. */
.photo-gallery .photo-gallery__item {
	height: auto;
	aspect-ratio: 16 / 10;
	overflow: hidden;
}

.photo-gallery__image {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Hover, matching the cards: the zoomed copy cross-fades in (the scale never
   animates, only the blend). The item's overflow: hidden clips it. */
.photo-gallery__image--zoom {
	position: absolute;
	inset: 0;
	opacity: 0;
	transform: scale( 1.12 );
	transition: opacity .2s ease;
}

.photo-gallery__open:is( :hover, :focus-visible ) .photo-gallery__image--zoom {
	opacity: 1;
}

.photo-gallery__open {
	position: relative;
	display: block;
	width: 100%;
	height: 100%;
	padding: 0;
	border: 0;
	background: none;
	cursor: zoom-in;
}

.photo-gallery__open:focus-visible {
	outline: 2px solid var(--red-1);
	outline-offset: -2px;
}

/* Play badge over video thumbnails. */
.photo-gallery__play {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 56px;
	height: 56px;
	translate: -50% -50%;
	border-radius: 50%;
	background-color: rgba( 0, 0, 0, 0.55 );
	transition: background-color .15s ease;
}

.photo-gallery__play::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 54%;
	translate: -50% -50%;
	border-style: solid;
	border-width: 9px 0 9px 15px;
	border-color: transparent transparent transparent var(--white);
}

.photo-gallery__open:is( :hover, :focus-visible ) .photo-gallery__play {
	background-color: var(--red-1);
}

/*
 * Viewer modal. Desktop: the item fills the dialog edge to edge with the
 * controls laid over its foot. Laptop adds a dark frame above and below;
 * tablet and phone become a tall dark panel with the item centred and the
 * controls underneath.
 */
.photo-gallery__modal {
	width: min( 92vw, 1400px );
	max-width: none;
	max-height: 92vh;
	/* A fixed frame: the item is contained inside it, so the controls pinned
	   to its foot never move with an item's proportions. */
	aspect-ratio: 16 / 9;
	padding: 0;
	border: 0;
	background-color: var(--gray-8);
	color: var(--white);
	overflow: hidden;
}

.photo-gallery__modal::backdrop {
	background-color: rgba( 0, 0, 0, 0.8 );
}

html:has( .photo-gallery__modal[open] ) {
	overflow: hidden;
}

.photo-gallery__modal-inner {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
}

.photo-gallery__modal-media {
	flex: 1;
	min-height: 0;
}

.photo-gallery__modal-item {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
	background-color: var(--black);
}

.photo-gallery__modal-close {
	position: absolute;
	top: 12px;
	right: 12px;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border: 1px solid var(--gray-3);
	background-color: var(--white);
	color: var(--gray-8);
	cursor: pointer;
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.photo-gallery__modal-close:is( :hover, :focus-visible ) {
	background-color: var(--red-1);
	border-color: var(--red-1);
	color: var(--white);
}

/* Sits above a video's own control bar. */
.photo-gallery__modal-controls {
	position: absolute;
	bottom: 12px;
	left: 50%;
	z-index: 2;
	display: flex;
	translate: -50% 0;
}

.photo-gallery__modal:has( video ) .photo-gallery__modal-controls {
	bottom: 64px;
}

.photo-gallery__modal.is-single .photo-gallery__modal-controls {
	display: none;
}

.photo-gallery__modal-arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border: 0;
	background-color: var(--white);
	color: var(--gray-8);
	cursor: pointer;
	transition: background-color .15s ease, color .15s ease;
}

.photo-gallery__modal-arrow:not( :disabled ):is( :hover, :focus-visible ) {
	background-color: var(--red-1);
	color: var(--white);
}

.photo-gallery__modal-arrow:disabled {
	background-color: var(--gray-6);
	color: var(--gray-5);
	cursor: default;
}

/* Large desktop — no 1400px cap: the 16:9 frame takes 92% of whichever
   viewport side runs out first. */
@media ( min-width: 1441px ) {
	.photo-gallery__modal {
		width: min( 92vw, calc( 92vh * 16 / 9 ) );
	}
}

/* Laptop — a dark frame above and below the item. */
@media ( max-width: 1299px ) {
	.photo-gallery__modal-inner {
		padding-block: 28px;
	}

	.photo-gallery__modal-close {
		top: 8px;
		right: 8px;
	}
}

/* Tablet and phone — a tall panel, item centred, controls beneath it. */
@media ( max-width: 1024px ) {
	.photo-gallery__modal {
		height: 80vh;
		aspect-ratio: auto;
	}

	.photo-gallery__modal-inner {
		padding-block: 56px 24px;
	}

	.photo-gallery__modal-controls,
	.photo-gallery__modal:has( video ) .photo-gallery__modal-controls {
		position: static;
		align-self: center;
		margin-top: 24px;
		translate: none;
	}
}

/* Controls — testimonials' arrows and dots, in light-on-dark. */
.photo-gallery__controls {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 2rem;
}

/* Swiper locks pagination when every photo already fits on one page. */
.photo-gallery__controls:has( .swiper-pagination-lock ) {
	display: none;
}

.photo-gallery__arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 62px;
	height: 62px;
	padding: 0;
	border: 0;
	border-bottom: 1px solid var(--gray-5);
	background: none;
	color: var(--white);
	cursor: pointer;
	transition: background-color .15s ease, border-color .15s ease;
}

.photo-gallery__arrow:not( .swiper-button-disabled ):is( :hover, :focus-visible ) {
	background-color: var(--gray-7);
	border-bottom-color: var(--red-1);
}

.photo-gallery__arrow.swiper-button-disabled {
	color: var(--gray-6);
	cursor: default;
}

/* Extra ancestor outranks Swiper's full-width pagination rule. */
.photo-gallery .photo-gallery__controls .photo-gallery__dots {
	display: flex;
	gap: 1.25rem;
	width: auto;
}

.photo-gallery__dot {
	width: 10px;
	height: 10px;
	border: 1px solid var(--gray-4);
	border-radius: 50%;
	cursor: pointer;
	transition: border-color .15s ease, box-shadow .15s ease;
}

/* A red ring, thickened inward so the dot doesn't grow and nudge its row. */
.photo-gallery__dot:not( .is-active ):hover {
	border-color: var(--red-1);
	box-shadow: inset 0 0 0 1px var(--red-1);
}

.photo-gallery__dot.is-active {
	border-color: var(--red-1);
	background-color: var(--red-1);
}

/* Laptop */
@media ( max-width: 1299px ) {
	.photo-gallery .section-ribbon-text {
		--section-ribbon-font-size: 18px;
	}
}

/* Tablet — two columns, six to a page. Keep in step with view.js. */
@media ( max-width: 1024px ) {
	.photo-gallery {
		--photo-gallery-pad: 20px;
		--photo-gallery-gap: 8px;
		--photo-gallery-columns: 2;
	}

	.photo-gallery__swiper:not( .swiper-initialized ) .photo-gallery__item:nth-child( n + 7 ) {
		display: none;
	}

	.photo-gallery .section-ribbon {
		--section-ribbon-padding-left: 24px;
	}
}

/* Mobile */
@media ( max-width: 768px ) {
	.photo-gallery {
		--photo-gallery-pad: 16px;
	}

	/* The label can't wrap, so it has to fit the bar's 92vw cap. */
	.photo-gallery .section-ribbon-text {
		--section-ribbon-font-size: clamp( 13px, 4.4vw, 16px );
	}
}

/* Related links' phone breakpoint, where its ribbon's label inset tightens. */
@media ( max-width: 640px ) {
	.photo-gallery .section-ribbon {
		--section-ribbon-padding-right: 40px;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.photo-gallery__arrow,
	.photo-gallery__dot,
	.photo-gallery__play,
	.photo-gallery__image--zoom,
	.photo-gallery__modal-close,
	.photo-gallery__modal-arrow { transition: none; }
}

/* Desktop/laptop: the full-bleed panel insets its content by the page gutter. */
@media ( min-width: 1025px ) {
	.photo-gallery__panel {
		padding-inline: var(--page-gutter);
	}
}
