/*
 * gallery.css — heading/intro and the coverflow photo carousel.
 *
 * Figma: "Gallery" frame, node 124:2. The artboard's carousel spans its full
 * 1628px section; ours sits inside the 1280px container, so all four visible
 * side positions (two per side) are kept but sized down from the artboard's
 * 246x272 so the full five-slide coverflow comfortably fits the narrower
 * column — total width across all five slides is ~1124px.
 */

.gallery {
	background: var(--surface-frame);
	color: var(--ink);
}

.galleryInner {
	width: min(100% - (var(--gutter) * 2), var(--container));
	margin-inline: auto;
	padding-block: clamp(56px, 6.2vw, 110px);
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}

.galleryEyebrow {
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 12px;
	line-height: 28px;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: var(--ink);
}

.galleryEyebrow .eyebrowRule {
	color: var(--accent);
}

.galleryTitle {
	margin-top: clamp(12px, 1.3vw, 20px);
	max-width: 21em;
	font-size: 42px;
	line-height: 1.364;
	font-weight: 400;
	text-transform: capitalize;
	text-wrap: balance;
}

.galleryTitle span {
	color: inherit;
}

.galleryIntro {
	margin-top: clamp(16px, 1.8vw, 28px);
	max-width: 980px;
	font-family: var(--font-body);
	font-size: clamp(0.9375rem, 0.9rem + 0.16vw, 1rem);
	line-height: 1.625;
	color: var(--ink-muted);
}

/* ---------------------------------------------------------- Carousel */

.galleryCarousel {
	width: 100%;
	margin-top: clamp(40px, 4.5vw, 80px);
}

.galleryViewport {
	position: relative;
	/* Tall enough for the active slide (300px) plus room for its shadow. */
	height: 320px;
	overflow: hidden;
}

.galleryTrack {
	position: relative;
	height: 100%;
}

.galleryItem {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 300px;
	height: 268px;
	margin: -134px 0 0 -150px;
	border-radius: 24px;
	overflow: hidden;
	cursor: pointer;
	transition: transform 0.5s var(--ease), width 0.5s var(--ease), height 0.5s var(--ease),
		opacity 0.5s var(--ease), border-radius 0.5s var(--ease), margin 0.5s var(--ease);
	/*
	 * --offset is set per item by gallery.js: 0 for the active slide, -1/+1
	 * for its immediate neighbours, -2/+2 for the pair beyond those, and so
	 * on for a bigger gallery. It is updated continuously for every item,
	 * including ones further out than the visible ±2, so a navigation that
	 * jumps more than one slide animates as a slide-through rather than a
	 * teleport. The multiplier here is NOT uniform per step — see the
	 * .isAdjacent / .isFar rules below, which override it with the actual
	 * measured distance for that tier — because the active slide is wider
	 * than its neighbours, so the first step is naturally longer than every
	 * step after it.
	 *
	 * Size, opacity and z-index are NOT driven from --offset either — JS also
	 * toggles .isActive / .isAdjacent / .isFar, and those classes carry the
	 * actual visual states below, because matching on the serialized text of
	 * an inline style ([style*="--offset: 0"]) is brittle and not how CSS is
	 * meant to be queried.
	 */
	transform: translateX(calc(var(--offset, 0) * 258px));
	z-index: 1;
	opacity: 0;
	pointer-events: none;
}

.galleryItem.isActive {
	width: 300px;
	height: 268px;
	margin: -134px 0 0 -150px;
	border-radius: 24px;
	transform: translateX(0);
	opacity: 1;
	z-index: 3;
	cursor: default;
	pointer-events: auto;
	box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
}

/*
 * The four visible neighbours — two on each side, all one size, matching
 * the artboard's five-up layout exactly (node 45:1498: two faded thumbnails
 * either side of the sharp centre). Distance from centre: half the active
 * slide's width (150) + the gap (16) + half this width (95) = 261px for the
 * inner pair; the outer pair sits a further 95+16+95 = 206px beyond that
 * (467px total), so --offset's own magnitude (1 or 2) needs a different
 * multiplier per tier rather than one constant step.
 */
.galleryItem.isAdjacent,
.galleryItem.isFar {
	width: 190px;
	height: 210px;
	margin: -105px 0 0 -95px;
	border-radius: 17px;
	opacity: 1;
	pointer-events: auto;
}

.galleryItem.isAdjacent {
	transform: translateX(calc(var(--offset) * 261px));
	z-index: 2;
}

.galleryItem.isFar {
	transform: translateX(calc(var(--offset) * 233.5px));
	z-index: 1;
}

.galleryItem.isAdjacent::after,
.galleryItem.isFar::after {
	content: "";
	position: absolute;
	inset: 0;
	background: rgba(248, 248, 247, 0.35);
	pointer-events: none;
}

.galleryImg {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* The bottom gradient the counter sits on (node 45:1509) — only meaningful
   on the active slide, where the counter is actually legible. */
.galleryItem.isActive::before {
	content: "";
	position: absolute;
	inset: auto 0 0 0;
	height: 33%;
	background: linear-gradient(to top, rgba(0, 0, 0, 0.38), rgba(0, 0, 0, 0));
	pointer-events: none;
}

.galleryCounter {
	position: absolute;
	right: 20px;
	bottom: 20px;
	z-index: 1;
	font-family: var(--font-body);
	font-weight: 500;
	font-size: 12px;
	letter-spacing: 0.1em;
	color: #fff;
	/* Only the active slide's counter is ever meant to be read — the
	   neighbours' copies are covered by the white-wash overlay already. */
	opacity: 0;
	transition: opacity 0.3s var(--ease);
}

.galleryItem.isActive .galleryCounter {
	opacity: 1;
}

/* ----------------------------------------------------------- Controls */

.galleryControls {
	margin-top: clamp(28px, 3vw, 48px);
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 24px;
}

.galleryNav {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background: var(--accent);
	color: var(--warm-sand);
	transition: background-color 0.2s var(--ease);
}

.galleryNav:hover,
.galleryNav:focus-visible {
	background: var(--accent-deep);
}

.galleryDots {
	display: flex;
	align-items: center;
	gap: 8px;
}

.galleryDot {
	width: 8px;
	height: 8px;
	border-radius: 50%;
	/*
	 * #6b6f6b, not the artboard's #c8c8c6 — that measures 1.6:1 against this
	 * section's background, well under the 3:1 a non-text UI indicator needs
	 * (WCAG 1.4.11) since these dots are how a sighted user perceives which
	 * slide is active. This darker grey reaches 4.03:1 and still reads as a
	 * clearly secondary dot beside the active pill.
	 */
	background: #6b6f6b;
	transition: background-color 0.2s var(--ease), width 0.2s var(--ease);
}

.galleryDot.isActive {
	width: 24px;
	border-radius: 4px;
	background: var(--accent);
}

.galleryDot:hover,
.galleryDot:focus-visible {
	background: var(--accent-deep);
}

/* --------------------------------------------------------------- Small */

@media (max-width: 767px) {
	.galleryTitle {
		font-size: 36px;
		line-height: 1.164;
	}

	/*
	 * .galleryControls is a flex row and, on a phone, the 15-dot track alone
	 * is wider than the space left beside two 44px arrows — flex-shrink's
	 * default of 1 was squeezing these arrows down to a sliver, which turned
	 * their border-radius: 50% into a pill instead of a circle.
	 */
	.galleryNav {
		flex-shrink: 0;
	}

	/*
	 * Smaller dots free up the width the fixed-size arrows above no longer
	 * give back — 15 of them at the desktop size don't fit next to two full
	 * 44px circles on a narrow phone, and shrinking the dots instead of the
	 * arrows is what keeps every slide's indicator visible with no scrolling.
	 */
	.galleryDots {
		gap: 6px;
	}

	.galleryDot {
		width: 6px;
		height: 6px;
	}

	.galleryDot.isActive {
		width: 18px;
	}
}

@media (max-width: 640px) {
	/* No room for two faded neighbours on a phone — the coverflow effect
	   collapses to a plain single-slide view, still fully navigable. */
	.galleryViewport {
		height: 280px;
	}

	.galleryItem.isAdjacent,
	.galleryItem.isFar {
		opacity: 0;
		pointer-events: none;
	}

	.galleryItem.isActive {
		width: min(300px, 88vw);
		height: 260px;
		margin-top: -130px;
		margin-left: calc(min(300px, 88vw) / -2);
	}
}
