/**
 * Gallery Wall - front-end styles.
 *
 * Design concept: a gallery corridor. Each piece sits in a thin hairline
 * frame with generous matting; the piece under focus reads at full
 * strength while its neighbours recede, the way peripheral vision works
 * walking down a real gallery wall.
 *
 * Deliberately no background or text colour of its own: this sits
 * inline in a page that may be light or dark (e.g. a theme with a
 * light/dark toggle), so everything except the brass accent is
 * derived from `currentColor` - whatever colour the surrounding page
 * has already decided text should be, frame lines and the muted
 * "mat" tint follow it automatically in either mode.
 *
 * Every value below is a custom property on .gallery-wall, so a theme
 * can still override spacing/accent without touching this file.
 */

.gallery-wall {
	--gw-accent: #b08d57;
	--gw-height: 66vh;
	--gw-gap: clamp(16px, 3vw, 40px);
	/* Reserved vertical space under each frame for its caption. Was
	   hard-coded as +108px in .gallery-wall__slide; now a variable
	   so long multi-line titles have room and it's tunable in one
	   place. Sized for roughly 4-5 lines of title + 1 line of meta. */
	--gw-caption-space: 170px;
	/* Width of the soft fade applied to the left and right edges of
	   the horizontal track, so slides scroll "into" the page rather
	   than being hard-clipped at the container edge. Uses a mask
	   rather than a coloured overlay so it works identically in
	   light and dark mode without knowing the page background.
	   Set to 0 to disable. */
	--gw-edge-fade: 80px;
	/* Inherits whatever font the surrounding theme has set, so the
	   title reads as part of the site rather than importing its own
	   typeface. To use a specific theme font instead of whatever's
	   inherited here (e.g. a distinct heading font), set this to that
	   font's own CSS variable or stack in your theme's stylesheet -
	   for a block theme this is usually something like
	   --gw-font-display: var(--wp--preset--font-family--heading); but
	   the exact name depends on the theme. */
	--gw-font-display: inherit;
	--gw-font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

	/* Hairline / mat tints derived from the page's own text colour, so
	 they read correctly whether that colour is light or dark. In a
	 browser old enough to not support color-mix(), these fall back
	 to the browser's normal initial value for border/background
	 (effectively a solid currentColor border) rather than breaking. */
	--gw-line: color-mix(in srgb, currentColor 16%, transparent);
	--gw-mat: color-mix(in srgb, currentColor 4%, transparent);

	position: relative;
	background: transparent;
	color: inherit;
	padding: clamp(24px, 5vw, 56px) 0;
	overflow: hidden;
	isolation: isolate;
}

.gallery-wall * {
	box-sizing: border-box;
}

.gallery-wall__stage {
	position: relative;
	display: flex;
	align-items: center;
	/* Reserves dedicated space on each side for the nav buttons below,
	   outside the track entirely, so artwork can never render behind
	   them and they stay visible regardless of what's scrolling past. */
	padding: 0 52px;
}

/* --- the track: Smooothy positions each .gallery-wall__slide directly,
 so all decorative motion below targets *children* of the slide. --- */
.gallery-wall__track {
	display: flex;
	align-items: flex-end;
	overflow: hidden;
	width: 100%;
	padding: 0 var(--gw-gap);
	outline: none;
	cursor: grab;
	/* Soft fade at both horizontal edges, so slides scroll into and
	   out of the page rather than being hard-clipped at the
	   container's border. A mask is used instead of a coloured
	   overlay so this works in both light and dark modes without
	   needing to know the background colour. The nav arrows sit
	   outside the track (in .gallery-wall__stage padding), so they
	   aren't affected by the fade. */
	-webkit-mask-image: linear-gradient(
		to right,
		transparent 0,
		#000 var(--gw-edge-fade),
		#000 calc(100% - var(--gw-edge-fade)),
		transparent 100%
	);
	mask-image: linear-gradient(
		to right,
		transparent 0,
		#000 var(--gw-edge-fade),
		#000 calc(100% - var(--gw-edge-fade)),
		transparent 100%
	);
}

.gallery-wall__track:active {
	cursor: grabbing;
}

.gallery-wall__track:focus-visible {
	box-shadow: inset 0 0 0 2px var(--gw-accent);
}

.gallery-wall__slide {
	position: relative;
	flex-shrink: 0;
	/* Use the --gw-caption-space variable instead of a magic
	   +108px. Same idea (frame is --gw-height tall; the rest is room
	   for the caption below it), just with enough budget for a long
	   title to wrap to several lines without spilling past the slide
	   box and onto its neighbours. */
	height: calc(var(--gw-height) + var(--gw-caption-space));
	margin-right: var(--gw-gap);
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	will-change: transform;
}

.gallery-wall__frame {
	position: relative;
	margin: 0;
	height: var(--gw-height);
	flex-shrink: 0;
	border: 1px solid var(--gw-line);
	background: var(--gw-mat);
	padding: clamp(8px, 1vw, 16px);
	display: flex;
	overflow: hidden;
	transform-origin: center center;
	/* A simple, safe focus cue: the centred slide (.is-active, toggled
	   once per slide change - not recalculated every frame) reads at
	   full strength; others recede slightly. Pure CSS transition, no
	   JS driving it continuously.
	   Uses opacity rather than a brightness filter deliberately: this
	   element sits inside a slide that's repositioned by a JS-driven
	   transform on every frame, and WebKit has known compositing
	   issues where a `filter` on an element in that situation can get
	   visually "stuck" in place while its real position keeps moving
	   underneath it - opacity doesn't carry that same risk. */
	opacity: 0.72;
	transform: scale(0.93);
	transition: opacity 0.4s ease, transform 0.4s ease;
}

.gallery-wall__slide.is-active .gallery-wall__frame {
	opacity: 1;
	transform: scale(1);
}

.gallery-wall__image {
	height: 100%;
	width: auto;
	max-width: none;
	object-fit: cover;
	display: block;
	pointer-events: none;
	user-select: none;
}

.gallery-wall__caption {
	position: absolute;
	top: calc(var(--gw-height) + 14px);
	/* Centred on the slide's own midpoint, not its left edge. The
	   active slide is always centred in the viewport (Smooothy centres
	   whichever slide goToNext/goToIndex targets), so anchoring here
	   guarantees the caption stays on-screen even for a piece much
	   wider than the viewport itself - anchoring to the slide's left
	   edge meant the caption could sit far outside the visible area
	   for anything wider than the screen, even while the artwork
	   itself was perfectly visible in the centre. */
	left: 50%;
	transform: translateX(-50%) translateY(4px);
	max-width: min(720px, 90vw);
	text-align: center;
	display: flex;
	flex-direction: column;
	gap: 2px;
	opacity: 0;
	transition: opacity 0.4s ease, transform 0.4s ease;
}

.gallery-wall__slide.is-active .gallery-wall__caption {
	opacity: 1;
	transform: translateX(-50%) translateY(0);
}

.gallery-wall__title {
	font-family: var(--gw-font-display);
	font-size: clamp(13px, 1.2vw, 16px);
	line-height: 1.3;
	color: inherit;
}

.gallery-wall__meta {
	font-family: var(--gw-font-ui);
	font-size: 11.5px;
	color: inherit;
	opacity: 0.62;
	letter-spacing: 0.01em;
}

/* --- nav arrows: quiet chrome, brass on hover/focus --- */
.gallery-wall__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 44px;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: 1px solid var(--gw-line);
	border-radius: 50%;
	color: inherit;
	opacity: 0.7;
	cursor: pointer;
	transition: color 0.25s ease, border-color 0.25s ease, opacity 0.25s ease;
	z-index: 2;
}

.gallery-wall__nav svg {
	width: 18px;
	height: 18px;
}

.gallery-wall__nav:hover,
.gallery-wall__nav:focus-visible {
	opacity: 1;
	border-color: var(--gw-accent);
}

.gallery-wall__nav--prev {
	left: 4px;
}

.gallery-wall__nav--next {
	right: 4px;
}

/* --- bottom bar: position count + progress rule, plain language, no dots --- */
.gallery-wall__bar {
	display: flex;
	align-items: center;
	gap: 20px;
	padding: 18px var(--gw-gap) 0;
	font-family: var(--gw-font-ui);
}

.gallery-wall__count {
	margin: 0;
	font-size: 12.5px;
	color: inherit;
	opacity: 0.62;
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

.gallery-wall__progress {
	position: relative;
	flex: 1;
	height: 1px;
	background: var(--gw-line);
}

.gallery-wall__progress span {
	position: absolute;
	inset: 0;
	width: 0%;
	background: var(--gw-accent);
	transform-origin: left center;
}

.gallery-wall-empty {
	padding: 40px;
	text-align: center;
	color: inherit;
	opacity: 0.62;
	font-family: var(--gw-font-ui);
}

/* --- static fallback: used when there are too few/narrow images to
 actually need dragging (see gallery-wall.js), or on portrait phones
 (where a horizontal carousel is the wrong interaction for a tall
 narrow screen). Same frame styling, just laid out in normal flow
 instead of handed to the scroll engine. --- */
.gallery-wall--static .gallery-wall__track {
	overflow: visible;
	cursor: default;
flex-direction: column;
flex-wrap: nowrap;
	justify-content: center;
	row-gap: var(--gw-gap);
	/* No edge fade in static mode - the fade is a horizontal-carousel
	   affordance, and in a wrapped/stacked layout there are no
	   off-screen slides scrolling in and out at the edges. */
	-webkit-mask-image: none;
	mask-image: none;
	
}

.gallery-wall--static .gallery-wall__nav,
.gallery-wall--static .gallery-wall__bar {
	display: none;
}

/* --- portrait phones: a single-column, vertically-scrolled list.
 This bypasses the scroll engine entirely (see the portrait check
 in gallery-wall.js) because a horizontal carousel is the wrong
 interaction on a tall narrow screen - images were being cropped
 top and bottom, and captions clipped at the edges. The trade is
 the interactive drag/snap feel for a layout that just shows the
 work properly, one piece at a time, scroll-down-to-continue, the
 way most portfolio sites handle mobile. --- */
@media (max-width: 780px) and (orientation: portrait) {
	/* Kill the horizontal-edge mask here too - with nothing scrolling
	   horizontally, a fade at the sides just looks like a bug. */
	.gallery-wall--static .gallery-wall__track {
		-webkit-mask-image: none;
		mask-image: none;
	}

	.gallery-wall--static .gallery-wall__slide {
		/* One per row, full width of the track, and let the slide
		   size to its own content (rather than the fixed
		   --gw-height + caption-space box the carousel uses) so
		   nothing gets clipped. */
		height: auto;
		width: 100%;
		max-width: 100%;
		margin-right: 0;
	}

	.gallery-wall--static .gallery-wall__frame {
		/* Let the frame size to the image, capped so a very tall
		   portrait piece still leaves the caption visible below
		   the fold. */
		height: auto;
		width: 100%;
		max-height: 70vh;
		justify-content: center;
	}

	.gallery-wall--static .gallery-wall__image {
		/* contain (not cover): the whole artwork visible, nothing
		   cropped. This is the actual fix for the "image gets cut
		   off" symptom - cover was cropping to fill the fixed-height
		   frame, which is a landscape-carousel compromise that
		   doesn't make sense in a full-width single-column layout. */
		height: auto;
		width: 100%;
		max-width: 100%;
		max-height: 70vh;
		object-fit: contain;
	}

	.gallery-wall--static .gallery-wall__caption {
		/* Back into normal flow (no longer absolutely positioned
		   below a fixed-height frame), full width, always visible.
		   This is the actual fix for the "text gets cut off"
		   symptom - the previous absolute positioning was relative
		   to a slide box wider than the viewport, so the caption
		   extended past both edges. */
		position: static;
		top: auto;
		left: auto;
		transform: none;
		opacity: 1;
		max-width: 100%;
		width: 100%;
		margin-top: 12px;
	}

	.gallery-wall--static .gallery-wall__slide.is-active .gallery-wall__caption {
		/* Override the .is-active transform once the caption is back
		   in static flow - the translateX(-50%) that centres it in
		   carousel mode would shift it off-screen here. */
		transform: none;
	}
}

/* --- lightbox in light mode: Darkify adds .darkify_dark_mode_enabled
 to <html> when the site is in dark mode. In its absence, the site is
 in light mode (confirmed: body background is #fff, caption text is
 #111), and the lightbox follows suit - white scrim, #111 text,
 matching the gallery captions underneath each image, rather than the
 conventional always-dark overlay. The scrim is white at 97% so the
 page behind is still faintly visible (it's an overlay, not a page
 replacement). Meta/desc use opacity the same way the gallery caption
 does, so they stay in sync if that opacity is ever tuned. --- */
html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox {
	background: rgba(255, 255, 255, 0.97);
}

html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__caption {
	color: #111111;
}

html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__title {
	color: inherit;
}

html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__meta {
	color: #111111;
	opacity: 0.62;
}

html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__desc {
	color: #111111;
	opacity: 0.78;
}

html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__image {
	border-color: rgba(0, 0, 0, 0.12);
}

html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__close,
html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__prev,
html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__next {
	color: #111111;
	border-color: rgba(0, 0, 0, 0.16);
}

html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__close:hover,
html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__prev:hover,
html:not(.darkify_dark_mode_enabled) .gallery-wall-lightbox__next:hover {
	border-color: #b08d57;
}


/* --- lightbox, built by JS and appended once to <body>. This stays a
 fixed dark scrim regardless of the page's own light/dark mode - 
 that's the conventional, expected treatment for a lightbox overlay. --- */
.gallery-wall-lightbox {
	position: fixed;
	inset: 0;
	z-index: 10000;
	background: rgba(10, 9, 8, 0.96);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: clamp(16px, 4vw, 48px);
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.3s ease;
	/* Inherit the site's body font rather than a hard-coded
	   Georgia/system stack. */
	font-family: inherit;
}

.gallery-wall-lightbox.is-open {
	opacity: 1;
	visibility: visible;
}

.gallery-wall-lightbox__figure {
	position: relative;
	max-width: 100%;
	max-height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 18px;
	transform: scale(0.97);
	transition: transform 0.35s ease;
}

.gallery-wall-lightbox.is-open .gallery-wall-lightbox__figure {
	transform: scale(1);
}

.gallery-wall-lightbox__image {
	max-width: 100%;
	max-height: 72vh;
	object-fit: contain;
	border: 1px solid rgba(237, 233, 227, 0.14);
}

.gallery-wall-lightbox__caption {
	text-align: center;
	color: #ede9e3;
	max-width: 60ch;
}

.gallery-wall-lightbox__title {
	font-family: inherit;
	font-style: normal;
	font-size: 17px;
	display: block;
	margin-bottom: 4px;
}

.gallery-wall-lightbox__meta {
	font-size: 12px;
	color: #8c867c;
	display: block;
}

.gallery-wall-lightbox__desc {
	font-size: 13px;
	line-height: 1.6;
	margin-top: 10px;
	color: #c8c3ba;
}

.gallery-wall-lightbox__link {
	display: inline-block;
	margin-top: 12px;
	font-size: 13px;
	color: #b08d57;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.gallery-wall-lightbox__close,
.gallery-wall-lightbox__prev,
.gallery-wall-lightbox__next {
	position: absolute;
	background: transparent;
	border: 1px solid rgba(237, 233, 227, 0.18);
	border-radius: 50%;
	color: #ede9e3;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: border-color 0.2s ease, color 0.2s ease;
}

.gallery-wall-lightbox__close:hover,
.gallery-wall-lightbox__prev:hover,
.gallery-wall-lightbox__next:hover {
	border-color: #b08d57;
}

.gallery-wall-lightbox__close {
	top: clamp(12px, 3vw, 28px);
	right: clamp(12px, 3vw, 28px);
	width: 40px;
	height: 40px;
}

.gallery-wall-lightbox__prev,
.gallery-wall-lightbox__next {
	top: 50%;
	transform: translateY(-50%);
	width: 48px;
	height: 48px;
}

.gallery-wall-lightbox__prev {
	left: clamp(8px, 2vw, 24px);
}

.gallery-wall-lightbox__next {
	right: clamp(8px, 2vw, 24px);
}

.gallery-wall-lightbox svg {
	width: 18px;
	height: 18px;
}

/* --- responsive: shrink slide height and gaps on small screens --- */
@media (max-width: 780px) {
	.gallery-wall {
		--gw-height: min(var(--gw-height), 46vh);
		--gw-gap: 14px;
		--gw-caption-space: 190px;
	}

	.gallery-wall__stage {
		padding: 0 40px;
	}

	.gallery-wall__nav {
		width: 36px;
		height: 36px;
	}

	.gallery-wall-lightbox__prev,
	.gallery-wall-lightbox__next {
		width: 38px;
		height: 38px;
	}
}

/* --- respect reduced motion: keep the carousel usable, drop the flourish --- */
@media (prefers-reduced-motion: reduce) {
	.gallery-wall__frame,
	.gallery-wall__image,
	.gallery-wall__caption,
	.gallery-wall-lightbox,
	.gallery-wall-lightbox__figure {
		transition-duration: 0.01ms !important;
	}
}

.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(1px, 1px, 1px, 1px);
	white-space: nowrap;
}