/* ==========================================================================
   Project Gallery Lightbox (neilkelly/project-gallery)
   Hidden modal opened by [data-nk-gallery-open]; image grid + optional video.
   Built to the NK design system (no dedicated Figma lightbox frame). Token-driven.
   Wrapper: .wp-block-neilkelly-project-gallery.nk-project-gallery
   ========================================================================== */
.wp-block-neilkelly-project-gallery.nk-project-gallery {
	position: fixed;
	inset: 0;
	z-index: 9999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--wp--preset--spacing--12);
	box-sizing: border-box;
	font-family: var(--wp--preset--font-family--inter);
	/* align:full flow child of <main>: drop the block-gap margin WordPress
	   injects on is-layout-flow children. Inert on the fixed overlay, but keeps
	   it consistent with the other full-bleed sections (see project-hero). */
	margin-block-start: 0;
}

.wp-block-neilkelly-project-gallery[hidden] { display: none; }

.wp-block-neilkelly-project-gallery .nk-project-gallery__backdrop {
	position: absolute;
	inset: 0;
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__panel {
	position: relative;
	width: 100%;
	height: 100%;
	max-width: var(--wp--custom--components--project--gallery-panel-max-width);
	max-height: var(--wp--custom--components--project--gallery-panel-max-height);
	margin-inline: auto;
	display: flex;
	flex-direction: column;
	padding: var(--wp--custom--components--project--gallery-panel-pad-top) var(--wp--preset--spacing--10) var(--wp--custom--components--project--gallery-panel-pad-bottom);
	background: var(--wp--preset--color--surface-dark);
	border: var(--wp--custom--components--project--gallery-frame-border-width) solid var(--wp--preset--color--brand-red);
	border-radius: var(--wp--custom--radius--xl);
	box-sizing: border-box;
	/* Entrance/exit: resting state sits a step below its final position and
	   transparent; view.js flips .is-open (after unhide + reflow) so the panel
	   slides up + fades in on open, and back down on close. The fixed overlay
	   has no dimming scrim, so only the panel animates. 400ms matches the
	   in-panel slider track transition below. */
	opacity: 0;
	transform: translateY( var(--wp--preset--spacing--16) );
	transition: opacity 400ms ease, transform 400ms ease;
}

.wp-block-neilkelly-project-gallery.is-open .nk-project-gallery__panel {
	opacity: 1;
	transform: translateY( 0 );
}

@media (prefers-reduced-motion: reduce) {
	.wp-block-neilkelly-project-gallery .nk-project-gallery__panel { transition: none; }
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__bar {
	position: absolute;
	left: 0;
	bottom: calc( -1 * var(--wp--custom--components--project--gallery-panel-bottom-offset) );
	width: 100%;
	flex-shrink: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--6);
	padding-top: var(--wp--preset--spacing--6);
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__close {
	position: relative;
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--2);
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--5);
	background: var(--wp--preset--color--brand-red);
	border: 0;
	border-radius: 0 0 var(--wp--custom--radius--lg) var(--wp--custom--radius--lg);
	cursor: pointer;
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--sm-md);
	line-height: var(--wp--custom--line-height--none);
	text-transform: uppercase;
	color: var(--wp--preset--color--brand-white);
}

/* Top-corner flares — outward-flaring tab where it meets the panel edge (Figma 969:556 / 969:557). */
.wp-block-neilkelly-project-gallery .nk-project-gallery__close::before,
.wp-block-neilkelly-project-gallery .nk-project-gallery__close::after {
	content: "";
	position: absolute;
	top: 0;
	width: var(--wp--custom--components--project--gallery-close-flare-width);
	height: var(--wp--custom--components--project--gallery-close-flare-height);
	background: var(--wp--preset--color--brand-red);
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__close::before {
	left: calc( -1 * var(--wp--custom--components--project--gallery-close-flare-width) );
	-webkit-mask: radial-gradient( var(--wp--custom--components--project--gallery-close-flare-width) var(--wp--custom--components--project--gallery-close-flare-height) at bottom left, transparent 99.5%, black 100% );
	        mask: radial-gradient( var(--wp--custom--components--project--gallery-close-flare-width) var(--wp--custom--components--project--gallery-close-flare-height) at bottom left, transparent 99.5%, black 100% );
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__close::after {
	right: calc( -1 * var(--wp--custom--components--project--gallery-close-flare-width) );
	-webkit-mask: radial-gradient( var(--wp--custom--components--project--gallery-close-flare-width) var(--wp--custom--components--project--gallery-close-flare-height) at bottom right, transparent 99.5%, black 100% );
	        mask: radial-gradient( var(--wp--custom--components--project--gallery-close-flare-width) var(--wp--custom--components--project--gallery-close-flare-height) at bottom right, transparent 99.5%, black 100% );
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__close:hover,
.wp-block-neilkelly-project-gallery .nk-project-gallery__close:hover::before,
.wp-block-neilkelly-project-gallery .nk-project-gallery__close:hover::after {
	background: var(--wp--preset--color--brand-red-hover);
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__close-icon {
	display: block;
	width: var(--wp--preset--spacing--5);
	height: var(--wp--preset--spacing--5);
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__close:focus-visible {
	outline: 2px solid var(--wp--preset--color--brand-white);
	outline-offset: 2px;
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__scroll {
	flex: 1 1 auto;
	min-height: 0;
	overflow: hidden auto;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--6);
}

/* Video slide: an embed can't be object-fit:cover-cropped like the before/after
   images, so centre it within the slide (the dark panel shows around it).
   Unlike the high-res photos, a YouTube/oembed player can't scale past the
   resolution it was served, so cap the width (content-width token, ~YouTube's
   1280px max) — stretching it to fill a full-height slide upscales and blurs it.
   Both slide classes are chained so this beats the base .__slide grid rule
   (equal specificity, defined later) and the embed actually centres. */
.wp-block-neilkelly-project-gallery .nk-project-gallery__slide.nk-project-gallery__slide--video {
	display: flex;
	align-items: center;
	justify-content: center;
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__video {
	width: 100%;
	max-width: var(--wp--custom--layout--content-width);
	max-height: 100%;
	aspect-ratio: 16 / 9;
}
.wp-block-neilkelly-project-gallery .nk-project-gallery__video :where(iframe, video) {
	width: 100%;
	height: 100%;
	border: 0;
	border-radius: var(--wp--custom--radius--lg);
}

/* Fallback slide — the video URL couldn't be embedded (unsupported provider,
   private video, or a transport failure at render time), so the slide holds a
   link out instead of vanishing. Keeps the 16/9 box from the base rule and
   centres the link inside a panel one step lighter than the dialog ground. */
.wp-block-neilkelly-project-gallery .nk-project-gallery__video--fallback {
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--wp--preset--color--surface-dark-2);
	border-radius: var(--wp--custom--radius--lg);
}

/* Primary CTA on a dark ground → white fill, per the CLAUDE.md CTA rules.
   Settles to neutral-100 on hover (white can't lighten). */
.wp-block-neilkelly-project-gallery .nk-project-gallery__video-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--2);
	box-sizing: border-box;
	min-height: var(--wp--preset--spacing--14);
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--6);
	background: var(--wp--preset--color--brand-white);
	border-radius: var(--wp--custom--radius--lg);
	font-size: var(--wp--preset--font-size--base);
	font-weight: var(--wp--custom--font-weight--semibold);
	line-height: var(--wp--custom--line-height--none);
	color: var(--wp--preset--color--ink-primary);
	text-decoration: none;
	transition: background-color 200ms ease;
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__video-link:hover,
.wp-block-neilkelly-project-gallery .nk-project-gallery__video-link:focus-visible {
	background: var(--wp--preset--color--neutral-100);
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__video-link:focus-visible {
	outline: 2px solid var(--wp--preset--color--brand-white);
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	.wp-block-neilkelly-project-gallery .nk-project-gallery__video-link { transition: none; }
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__video-link-icon {
	width: var(--wp--preset--font-size--sm-md);
	height: var(--wp--preset--font-size--sm-md);
	flex: 0 0 auto;
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__slider {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	/* Row 1 (arrows + image viewport) takes all available height, row 2 the dots.
	   flex:1 lets the slider itself fill __scroll so the images run full-height
	   under the full-height panel. Reverted for the stacked layout at <=767px. */
	grid-template-rows: minmax(0, 1fr) auto;
	flex: 1 1 auto;
	min-height: 0;
	align-items: center;
	/* Gap between arrows and the image matches the panel's horizontal padding
	   (spacing--10) so each arrow has equal space on its inner and outer side. */
	column-gap: var(--wp--preset--spacing--10);
	padding-bottom: 0;
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__viewport {
	grid-column: 2;
	grid-row: 1;
	/* The slider centres its cells (for the arrows); opt the viewport back into
	   filling row 1's height so the image can run full-height. */
	align-self: stretch;
	min-height: 0;
	overflow: hidden;
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__track {
	display: flex;
	height: 100%;
	transition: transform 400ms ease;
}

@media (prefers-reduced-motion: reduce) {
	.wp-block-neilkelly-project-gallery .nk-project-gallery__track { transition: none; }
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__slide {
	flex: 0 0 100%;
	min-width: 0;
	height: 100%;
	display: grid;
	grid-template-columns: 1fr 1fr;
	/* Bound the row to the slide (= viewport) height so images can't grow to their
	   natural height and overflow a short viewport. Without this, on a wide/short
	   screen the image renders full-height, the viewport (overflow:hidden) clips it,
	   and anything pinned to the figure's bottom (the caption) is clipped out of
	   view. minmax(0, 1fr) + item min-height:0 bounds the image box to the viewport so
	   object-fit:contain fits the whole image inside it. The <=767px stack resets this
	   (rows become auto). */
	grid-template-rows: minmax(0, 1fr);
	column-gap: var(--wp--preset--spacing--10);
	row-gap: var(--wp--preset--spacing--4);
}

/* After-only row (no before image) spans the full slide. */
.wp-block-neilkelly-project-gallery .nk-project-gallery__item:only-child { grid-column: 1 / -1; }

.wp-block-neilkelly-project-gallery .nk-project-gallery__item { position: relative; height: 100%; min-height: 0; margin: 0; }

/* Pinterest share button on each lightbox image — used by the Project Detail gallery
   (before/after images) and the Photo Gallery lightbox (both build .nk-project-gallery__item figures). */
.wp-block-neilkelly-project-gallery .nk-project-gallery__share {
	position: absolute;
	top: var(--wp--preset--spacing--3);
	right: var(--wp--preset--spacing--3);
	z-index: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--wp--preset--spacing--8);
	height: var(--wp--preset--spacing--8);
	border-radius: var(--wp--custom--radius--full);
	background: var(--wp--preset--color--brand-white);
	color: var(--wp--preset--color--brand-red);
	border: 1px solid var(--wp--preset--color--border-default);
	box-shadow: var(--wp--custom--shadow--elev-2);
	text-decoration: none;
	transition: background-color 0.15s ease;
}
.wp-block-neilkelly-project-gallery .nk-project-gallery__share:hover { background: var(--wp--preset--color--neutral-50); }
.wp-block-neilkelly-project-gallery .nk-project-gallery__share:focus-visible { outline: 2px solid var(--wp--preset--color--brand-red); outline-offset: 2px; }
.wp-block-neilkelly-project-gallery .nk-project-gallery__share-icon { display: block; width: var(--wp--preset--spacing--5); height: var(--wp--preset--spacing--5); pointer-events: none; }

.wp-block-neilkelly-project-gallery .nk-project-gallery__nav {
	grid-row: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--wp--preset--spacing--12);
	height: var(--wp--preset--spacing--12);
	background: var(--wp--preset--color--brand-white);
	/* Circular arrows matching .nk-project-hero__arrow (used by every lightbox). */
	border: 1px solid var(--wp--preset--color--border-default);
	border-radius: var(--wp--custom--radius--full);
	box-shadow: var(--wp--custom--shadow--elev-3);
	cursor: pointer;
	color: var(--wp--preset--color--ink-primary);
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__nav-icon {
	display: block;
	width: var(--wp--preset--spacing--5);
	height: var(--wp--preset--spacing--5);
	pointer-events: none;
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__nav--prev { grid-column: 1; }
.wp-block-neilkelly-project-gallery .nk-project-gallery__nav--next { grid-column: 3; }
.wp-block-neilkelly-project-gallery .nk-project-gallery__nav:hover { background: var(--wp--preset--color--neutral-100); }
.wp-block-neilkelly-project-gallery .nk-project-gallery__nav:disabled { opacity: 0.4; cursor: default; }
.wp-block-neilkelly-project-gallery .nk-project-gallery__nav:focus-visible { outline: 2px solid var(--wp--preset--color--brand-red); outline-offset: 2px; }

.wp-block-neilkelly-project-gallery .nk-project-gallery__dots {
	grid-column: 1 / -1;
	grid-row: 2;
	margin: var(--wp--custom--components--project--gallery-dots-margin-top) 0 0;
	display: flex;
	/* Wrap to a new line when there are more dots than fit, instead of squishing. */
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--3);
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__dot {
	/* Fixed size — never shrink/stretch to fit the row (a full gallery has many dots). */
	flex: 0 0 auto;
	width: var(--wp--preset--spacing--4);
	height: var(--wp--preset--spacing--4);
	padding: 0;
	border: 1px solid var(--wp--preset--color--neutral-200);
	border-radius: var(--wp--custom--radius--full);
	background: transparent;
	cursor: pointer;
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__dot.is-active {
	background: var(--wp--preset--color--neutral-200);
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__dot:focus-visible {
	outline: 2px solid var(--wp--preset--color--brand-white);
	outline-offset: 2px;
}

.wp-block-neilkelly-project-gallery .nk-project-gallery__img {
	display: block;
	width: 100%;
	height: 100%;
	/* Contain (not cover) so portrait/tall photos show whole instead of being cropped
	   top-and-bottom. The slide row is height-bounded (grid-template-rows: minmax(0,1fr)
	   + item min-height:0 above), so the image letterboxes inside the viewport rather
	   than overflowing it. Transparent letterbox shows the dark panel behind. Applies to
	   both the project before/after lightbox and the Photo Gallery lightbox. */
	object-fit: contain;
	background: transparent;
}
/* When the gallery is embedded in rich content, `.nk-cd-body__rich img { height:auto }`
   (higher specificity) would let portrait slides grow to their natural height and be
   cropped by the viewport. This slide-scoped rule outranks it, keeping the bounded
   contain behaviour everywhere the lightbox appears. */
.wp-block-neilkelly-project-gallery .nk-project-gallery__slide .nk-project-gallery__img {
	height: 100%;
	object-fit: contain;
}

/* Tag pill — default is the "After" style: red bg, white title-case text (Figma 969:595). */
.wp-block-neilkelly-project-gallery .nk-project-gallery__tag {
	position: absolute;
	top: var(--wp--preset--spacing--3);
	left: var(--wp--preset--spacing--3);
	padding: var(--wp--preset--spacing--1-5) var(--wp--preset--spacing--3);
	background: var(--wp--preset--color--brand-red);
	border-radius: var(--wp--custom--radius--full);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: var(--wp--custom--font-weight--regular);
	color: var(--wp--preset--color--brand-white);
}

/* "Before" tag pill — white background, red text (Figma 969:582). */
.wp-block-neilkelly-project-gallery .nk-project-gallery__item[data-label="before"] .nk-project-gallery__tag {
	background: var(--wp--preset--color--brand-white);
	color: var(--wp--preset--color--brand-red);
}

/* Photo Gallery lightbox caption ("title panel") — a solid semi-transparent bar
   across the bottom of the image with the photo's alt text (mirrors the live
   site's FancyBox fbx-caption). Built by view.js only when the photo carries a
   real alt. The bar itself is inert; only its X re-enables pointer events, so a
   click on the X hides this caption (see view.js) while the lightbox stays open.
   Horizontal padding leaves room for the X so the centered text never collides. */
.wp-block-neilkelly-project-gallery .nk-project-gallery__caption {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	z-index: 1;
	margin: 0;
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--10);
	background: var(--wp--custom--components--project--gallery-caption-bg);
	color: var(--wp--preset--color--brand-white);
	font-size: var(--wp--preset--font-size--sm-md);
	line-height: var(--wp--custom--line-height--base);
	text-align: center;
	pointer-events: none;
}
.wp-block-neilkelly-project-gallery .nk-project-gallery__caption[hidden] { display: none; }

/* Dimming backdrop behind the Photo Gallery lightbox. The project detail
   before/after gallery deliberately has no scrim (see the __panel note above), so
   this is scoped to the photo lightbox. Fades in/out with the panel's .is-open. */
.wp-block-neilkelly-project-gallery.nk-photo-gallery__lightbox .nk-project-gallery__backdrop {
	background: var(--wp--preset--color--surface-dark-overlay);
	opacity: 0;
	transition: opacity 400ms ease;
}
.wp-block-neilkelly-project-gallery.nk-photo-gallery__lightbox.is-open .nk-project-gallery__backdrop {
	opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
	.wp-block-neilkelly-project-gallery.nk-photo-gallery__lightbox .nk-project-gallery__backdrop { transition: none; }
}

/* Caption close (X) — hides just this caption ("title panel"), leaving the
   lightbox open. Sits at the right end of the bar; pointer-events:auto re-enables
   it over the inert caption. */
.wp-block-neilkelly-project-gallery .nk-project-gallery__caption-close {
	position: absolute;
	top: 50%;
	right: var(--wp--preset--spacing--3);
	transform: translateY( -50% );
	pointer-events: auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--wp--preset--spacing--6);
	height: var(--wp--preset--spacing--6);
	padding: 0;
	background: transparent;
	border: 0;
	border-radius: var(--wp--custom--radius--full);
	cursor: pointer;
	color: var(--wp--preset--color--brand-white);
	transition: background 200ms ease;
}
.wp-block-neilkelly-project-gallery .nk-project-gallery__caption-close:hover {
	background: var(--wp--preset--color--surface-dark-overlay);
}
.wp-block-neilkelly-project-gallery .nk-project-gallery__caption-close:focus-visible {
	outline: 2px solid var(--wp--preset--color--brand-white);
	outline-offset: 2px;
}
.wp-block-neilkelly-project-gallery .nk-project-gallery__caption-close-icon {
	display: block;
	width: var(--wp--preset--spacing--4);
	height: var(--wp--preset--spacing--4);
}

@media (max-width: 1023px) {
	.wp-block-neilkelly-project-gallery .nk-project-gallery__panel { padding: var(--wp--preset--spacing--6) var(--wp--preset--spacing--6); }
}

@media (max-width: 767px) {
	/* Extra bottom gutter so the full-height panel's overhanging "Close Gallery"
	   tab (gallery-panel-bottom-offset, ~37px below the panel) stays inside the
	   viewport instead of clipping. Top/sides keep the tight mobile inset. */
	.wp-block-neilkelly-project-gallery.nk-project-gallery { padding: var(--wp--preset--spacing--4) var(--wp--preset--spacing--4) var(--wp--preset--spacing--12); }
	/* Stack before/after in one column; drop the desktop single-row bound so both
	   images flow into their own (auto) rows at their fixed mobile height. */
	.wp-block-neilkelly-project-gallery .nk-project-gallery__slide { grid-template-columns: 1fr; grid-template-rows: auto; }
	/* Before/after stack here, so the desktop full-height fill would clip the
	   second image. Revert to content height + fixed image height and let
	   __scroll scroll. */
	.wp-block-neilkelly-project-gallery .nk-project-gallery__slider { flex: 0 0 auto; grid-template-rows: auto auto; }
	.wp-block-neilkelly-project-gallery .nk-project-gallery__track { height: auto; }
	.wp-block-neilkelly-project-gallery .nk-project-gallery__slide,
	.wp-block-neilkelly-project-gallery .nk-project-gallery__item { height: auto; }
	/* Selector carries `.__slide` so it matches the 0,3,0 base rule above
	   (.__slide .__img { height:100% }) — a bare .__img (0,2,0) would lose to it and the
	   image would stay height:100% of an auto-height parent, collapsing to nothing on
	   mobile (only arrows + dots visible). A definite 60vh breaks that percentage cycle. */
	.wp-block-neilkelly-project-gallery .nk-project-gallery__slide .nk-project-gallery__img { height: 60vh; }

	/* Give the image the full panel width. The desktop slider is a 3-column grid
	   ([arrow] [image] [arrow]) with a 40px gap each side, which on a phone squeezes the
	   image into a thin sliver. Collapse to a single full-width viewport and overlay the
	   arrows on top of it (same pattern as the project hero). */
	.wp-block-neilkelly-project-gallery .nk-project-gallery__slider {
		grid-template-columns: 1fr;
		column-gap: 0;
		position: relative;
	}
	.wp-block-neilkelly-project-gallery .nk-project-gallery__viewport { grid-column: 1; }
	.wp-block-neilkelly-project-gallery .nk-project-gallery__nav {
		position: absolute;
		top: 30vh; /* centre of the 60vh image row */
		transform: translateY(-50%);
		z-index: 3;
	}
	.wp-block-neilkelly-project-gallery .nk-project-gallery__nav--prev { left: var(--wp--preset--spacing--2); }
	.wp-block-neilkelly-project-gallery .nk-project-gallery__nav--next { right: var(--wp--preset--spacing--2); }
	.wp-block-neilkelly-project-gallery .nk-project-gallery__dots { grid-column: 1; }
}
