/**
 * Services gallery — masonry, plus the lightbox it opens into.
 *
 * A NEW FILE ON PURPOSE. Nothing here touches inner-page.css or any block stylesheet,
 * and functions.php enqueues it only on the Services template, so no other page can be
 * affected by it.
 *
 * NO RAW COLOURS, FONTS OR RADII. Every one comes from the tokens global.css already
 * defines for the homepage, so the gallery and the lightbox are the same visual system
 * as the rest of the site — including the button tokens, which the lightbox controls
 * borrow so they match the site's buttons without repeating a single value.
 *
 * The only literals are this component's own layout parameters, declared once at the
 * top rather than repeated down the file.
 *
 * @package lawncareknox
 */

.service-gallery {
	--gal-gap: var(--sp-16);
	--gal-cols: 3;
	margin-top: var(--sp-48);
}

/* ==========================================================================
   Masonry
   ==========================================================================
   CSS multi-column, not grid. Grid cannot do true masonry without either fixed row
   spans or JavaScript measuring every image; columns give a real masonry flow for
   free AND let every image keep its own proportions, which is the whole point of a
   masonry gallery rather than a grid of identical crops.

   The trade is reading order: columns fill top-to-bottom, so images run down column
   one before column two. For a photo gallery that costs nothing — there is no
   sequence to follow — and the lightbox still slides through them in the order set in
   ACF, because that order comes from the markup, not from the layout.
   ========================================================================== */

.service-gallery__items {
	columns: var(--gal-cols);
	column-gap: var(--gal-gap);
}

.service-gallery__item {
	/* `break-inside` is what stops a column boundary cutting an image in half. */
	break-inside: avoid;
	margin-bottom: var(--gal-gap);
	overflow: hidden;
	border-radius: var(--radius);
}

.service-gallery__btn {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    border-radius: var(--radius);
    position: relative;
    overflow: hidden;
    -webkit-box-sizing: border-box;
    transform: translateZ(0);
    -webkit-mask-image: -webkit-radial-gradient(white, black);
}

/* The tile is a real button, so it has to show a focus ring for keyboard users. */
.service-gallery__btn:focus-visible {
	outline: 2px solid var(--color-secondary);
	outline-offset: 2px;
}

/*
 * No aspect-ratio and no object-fit here, deliberately: the image keeps its natural
 * proportions, which is what makes the layout masonry rather than a grid.
 */
.service-gallery__btn img {
	display: block;
	width: 100%;
	transition: var(--transition);
	display: block;
width: 100%;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
border-radius: inherit;
}

.service-gallery__btn:hover img {
	transform: scale(1.04);
}

/* ==========================================================================
   Lightbox
   ==========================================================================
   Hidden with `display: none` rather than opacity, so while closed it is out of the
   accessibility tree and cannot be tabbed into.
   ========================================================================== */

.lck-lightbox {
	--lb-chrome: 48px;      /* hit area of the close / prev / next controls */
	--lb-inset: var(--sp-24);
	display: none;
	position: fixed;
	inset: 0;
	z-index: 100000;
	/* 0.9 left the headings behind it legible enough to compete with the photo. */
	background-color: rgba(0, 0, 0, 0.95);
	align-items: center;
	justify-content: center;
	padding: var(--lb-inset);
}

.lck-lightbox.is-open {
	display: flex;
}

/*
 * Scroll lock while the lightbox is open.
 *
 * It has to land on the ROOT, not the body: once html is a scroll container the
 * body's overflow is no longer propagated to the viewport, so `body { overflow:
 * hidden }` locks nothing. Same lesson as the mobile menu in header.css.
 *
 * `scrollbar-gutter: stable` is what stops the page jumping sideways as the scrollbar
 * goes away — `hidden` is still a scroll container, so the gutter stays reserved.
 */
html:has(body.lck-lightbox-open) {
	overflow: hidden;
	scrollbar-gutter: stable;
}

.lck-lightbox__figure {
	margin: 0;
	max-width: 100%;
	max-height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-16);
}

/*
 * Capped in BOTH axes so a portrait shot cannot run off the top and bottom of the
 * viewport — the usual failure of a naive lightbox. The chrome is subtracted from the
 * height budget so the controls never overlap the image.
 */
.lck-lightbox__img {
	display: block;
	max-width: 100%;
	max-height: calc(100vh - var(--lb-inset) * 2 - var(--lb-chrome) * 2);
	width: auto;
	height: auto;
	object-fit: contain;
	border-radius: var(--radius);
}

.lck-lightbox__caption,
.lck-lightbox__count {
	font-family: var(--font-primary);
	font-size: var(--btn-text-size);
	line-height: var(--btn-text-lh);
	letter-spacing: var(--btn-text-tracking);
	color: var(--color-white);
	text-align: center;
}

.lck-lightbox__count {
	opacity: 0.7;
}

/* --- Controls. Square, flat, filling with the brand green on hover — the same
       language as the site's buttons, via the same tokens. --- */

.lck-lightbox__close,
.lck-lightbox__prev,
.lck-lightbox__next {
	position: absolute;
	width: var(--lb-chrome);
	height: var(--lb-chrome);
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-radius: 0;
	background-color: rgba(255, 255, 255, 0.12);
	color: var(--color-white);
	font-family: var(--font-primary);
	font-size: var(--btn-text-size);
	font-weight: var(--btn-text-weight);
	line-height: 1;
	cursor: pointer;
	transition: var(--transition);
}

.lck-lightbox__close:hover,
.lck-lightbox__prev:hover,
.lck-lightbox__next:hover,
.lck-lightbox__close:focus-visible,
.lck-lightbox__prev:focus-visible,
.lck-lightbox__next:focus-visible {
	background-color: var(--color-primary);
}

.lck-lightbox__close {
	top: var(--lb-inset);
	right: var(--lb-inset);
}

.lck-lightbox__prev {
	left: var(--lb-inset);
	top: 50%;
	transform: translateY(-50%);
}

.lck-lightbox__next {
	right: var(--lb-inset);
	top: 50%;
	transform: translateY(-50%);
}

/* A one-image gallery has nowhere to slide to, so the arrows come off. */
.lck-lightbox.is-single .lck-lightbox__prev,
.lck-lightbox.is-single .lck-lightbox__next {
	display: none;
}

/* ==========================================================================
   Responsive
   ==========================================================================
   A column count is a fixed number, so unlike an auto-filling grid this genuinely
   needs breakpoints. They match the theme's own set.
   ========================================================================== */

@media (max-width: 999px) {
	.service-gallery {
		margin-top: var(--sp-40);
	}
}

@media (max-width: 767px) {
	.service-gallery {
		--gal-cols: 2;
		margin-top: var(--sp-32);
	}

	/*
	 * On a phone the arrows move to the bottom corners, out from under the thumb's
	 * path across the image, and the image gets the full width.
	 */
	.lck-lightbox__prev {
		left: var(--lb-inset);
		top: auto;
		bottom: var(--lb-inset);
		transform: none;
	}

	.lck-lightbox__next {
		right: var(--lb-inset);
		top: auto;
		bottom: var(--lb-inset);
		transform: none;
	}

	.lck-lightbox__img {
		max-height: calc(100vh - var(--lb-inset) * 2 - var(--lb-chrome) * 3);
	}
}

@media (max-width: 479px) {
	.service-gallery {
		--gal-cols: 1;
	}
}

/* Anyone who has asked for less motion gets no zoom and no transitions. */
@media (prefers-reduced-motion: reduce) {

	.service-gallery__btn img,
	.lck-lightbox__close,
	.lck-lightbox__prev,
	.lck-lightbox__next {
		transition: none;
	}

	.service-gallery__btn:hover img {
		transform: none;
	}
}
