/* ============================================================
   GALLERY — the studio contact sheet (theme 1.15.4, photographs only)
   sections/gallery.php · assets/js/gallery.js
   Loaded on the Gallery template only.

   Ribbon → photographs on paper, as a justified grid: rows share one
   height and fill the width; every photo keeps its natural aspect
   ratio, so nothing is cropped. gallery.js sets exact tile sizes;
   without JS the CSS flex fallback below produces nearly the same rows.
   ============================================================ */

/* Typed so getComputedStyle() returns the row height in px for gallery.js. */
@property --gx-row {
	syntax: '<length>';
	inherits: true;
	initial-value: 140px;
}

.gx {
	padding-block: 0;
	background:
		radial-gradient(55% 32% at 10% 6%, color-mix(in srgb, var(--color-clay) 7%, transparent), transparent 70%),
		radial-gradient(48% 30% at 92% 40%, color-mix(in srgb, var(--color-amber) 7%, transparent), transparent 72%);
	overflow-x: clip;
}

/* ---------- Handwritten ribbon under the page hero ---------- */
.gallery-ribbon {
	overflow: hidden;
	border-block-end: 1px dashed color-mix(in srgb, var(--color-clay) 38%, transparent);
	background: color-mix(in srgb, var(--color-vellum) 60%, transparent);
	padding-block: 0.45rem;
}
.gallery-ribbon__strip {
	display: inline-flex;
	align-items: center;
	width: max-content;
	white-space: nowrap;
	font-family: var(--font-hand);
	font-size: clamp(1.05rem, 0.9rem + 0.5vw, 1.35rem);
	color: var(--color-cinnamon);
	animation: galleryRibbon 38s linear infinite;
}
.gallery-ribbon__strip span { margin-inline-end: 0.55rem; }
.gallery-ribbon__strip i {
	font-style: normal;
	font-size: 0.72em;
	color: var(--color-clay);
	opacity: 0.55;
	margin-inline-end: 1.1rem;
}
@keyframes galleryRibbon {
	to { transform: translateX(-50%); }
}

/* ---------- Photographs ---------- */
.gx-chapter { position: relative; }
.gx-chapter--photos { padding-block: var(--space-2xl) var(--section-y); }
.gx-head { margin-block-end: var(--space-xl); }

/* Decor */
.gx__sprig {
	position: absolute;
	inline-size: clamp(3.2rem, 6vw, 5rem);
	inset-block-start: 1.5rem;
	inset-inline-end: 3.5%;
	color: var(--color-olive);
	animation: artSway 10s ease-in-out infinite alternate;
	pointer-events: none;
}
.gx__star {
	position: absolute;
	inline-size: clamp(1.6rem, 3vw, 2.5rem);
	inset-block-start: 5rem;
	inset-inline-start: 4%;
	color: var(--color-gold-light);
	animation: artTwinkle 6s ease-in-out infinite;
	pointer-events: none;
}
.gallery-note {
	font-family: var(--font-hand);
	font-size: clamp(1.15rem, 0.95rem + 0.9vw, 1.55rem);
	color: var(--color-clay);
	text-align: end;
	transform: rotate(-2deg);
	max-inline-size: none;
	margin-block-start: var(--space-md);
}

/* ---------- Justified grid ---------- */
/* Target row heights — mirrored in sections/gallery.php ($rows) for `sizes`. */
.gx-grid {
	--gx-row: 8.75rem;
	--gx-gap: 0.5rem;
	display: flex;
	flex-wrap: wrap;
	gap: var(--gx-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}
/* No-JS fallback: each tile grows in proportion to its aspect ratio, so a
   row shares one height; the filler keeps the last row at natural size. */
.gx-grid::after { content: ""; flex: 999 1 0; }
.gx-tile {
	position: relative;
	flex: calc(var(--w) / var(--h)) 1 calc(var(--w) / var(--h) * var(--gx-row));
	aspect-ratio: var(--w) / var(--h);
	min-inline-size: 0;
	border-radius: var(--radius-sm);
	overflow: hidden;
	background: var(--color-linen);
	box-shadow: var(--shadow-xs);
}
.gx-grid.is-laid::after { content: none; }
.gx-grid.is-laid .gx-tile {
	flex: 0 0 auto;
	inline-size: var(--tw);
	block-size: var(--th);
	aspect-ratio: auto;
}

.gx-tile__link {
	position: relative;
	display: block;
	inline-size: 100%;
	block-size: 100%;
	color: var(--color-parchment);
	cursor: zoom-in;
	-webkit-tap-highlight-color: transparent;
}
/* Focus ring painted above the photo (an inset shadow on the link would sit under the img). */
.gx-tile__link::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 3;
	border-radius: inherit;
	pointer-events: none;
}
.gx-tile__link:focus-visible { outline: none; }
.gx-tile__link:focus-visible::after { box-shadow: inset 0 0 0 3px var(--color-parchment), inset 0 0 0 5px var(--color-clay); }

.gx-tile__img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover; /* box shares the photo's own ratio — this only absorbs sub-pixel rounding */
	transition: transform var(--dur-slow) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}
.js .gx-tile__img.is-pending { opacity: 0; }

/* Caption: slides up on hover / keyboard focus (fine pointers); touch sees it in the viewer. */
.gx-tile__cap {
	position: absolute;
	inset-inline: 0;
	inset-block-end: 0;
	z-index: 2;
	padding: 2rem 0.85rem 0.6rem;
	background: linear-gradient(180deg, transparent, rgba(30, 20, 15, 0.78));
	font-family: var(--font-hand);
	font-size: clamp(1.05rem, 0.95rem + 0.35vw, 1.3rem);
	line-height: 1.15;
	color: var(--color-parchment);
	opacity: 0;
	transform: translateY(0.5rem);
	transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
	pointer-events: none;
}
@media (hover: hover) {
	.gx-tile__link:hover .gx-tile__img { transform: scale(1.04); }
	.gx-tile__link:hover .gx-tile__cap,
	.gx-tile__link:focus-visible .gx-tile__cap { opacity: 1; transform: none; }
}

/* ============================================================
   VIEWER — full-screen photos (native <dialog>)
   ============================================================ */
html.gx-lock { overflow: hidden; }

.gx-viewer {
	position: fixed;
	inset: 0;
	inline-size: 100%;
	block-size: 100%;
	max-inline-size: none;
	max-block-size: none;
	margin: 0;
	padding: 0;
	border: 0;
	background: rgba(24, 16, 12, 0.97);
	color: var(--color-parchment);
	overflow: hidden;
}
.gx-viewer[open] {
	display: grid;
	grid-template-rows: auto auto minmax(0, 1fr) auto auto;
}
.gx-viewer::backdrop { background: rgba(24, 16, 12, 0.7); }

.gx-viewer__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-sm);
	padding: max(0.6rem, env(safe-area-inset-top)) clamp(0.6rem, 3vw, 1.5rem) 0.6rem;
}
.gx-viewer__count {
	font-family: var(--font-mono);
	font-size: var(--text-sm);
	letter-spacing: 0.06em;
	color: var(--text-on-dark-mute);
}
.gx-viewer__count b { color: var(--color-parchment); font-weight: 500; }
.gx-viewer__tools { display: flex; gap: 0.4rem; }

.gx-viewer__btn {
	display: grid;
	place-items: center;
	inline-size: 2.75rem;
	block-size: 2.75rem;
	border: 1.5px solid rgba(247, 241, 231, 0.32);
	border-radius: var(--radius-full);
	background: rgba(43, 29, 22, 0.6);
	color: var(--color-parchment);
	transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-spring);
}
.gx-viewer__btn:hover { background: var(--color-clay); border-color: transparent; }
.gx-viewer__btn:focus-visible { outline: none; box-shadow: var(--focus-ring-dark); }
.gx-viewer__btn svg {
	inline-size: 1.25rem;
	block-size: 1.25rem;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}
.gx-viewer__btn[aria-pressed="true"] { background: var(--color-clay); border-color: transparent; }
.gx-viewer__btn .is-pause,
.gx-viewer__btn[aria-pressed="true"] .is-play { display: none; }
.gx-viewer__btn[aria-pressed="true"] .is-pause { display: block; }

/* Slideshow timer */
.gx-viewer__progress {
	block-size: 2px;
	margin-inline: clamp(0.6rem, 3vw, 1.5rem);
	border-radius: var(--radius-full);
	background: rgba(247, 241, 231, 0.12);
	overflow: hidden;
	visibility: hidden;
}
.gx-viewer.is-playing .gx-viewer__progress { visibility: visible; }
.gx-viewer__progress span {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	background: linear-gradient(90deg, var(--color-clay), var(--color-amber));
	transform: scaleX(0);
	transform-origin: left center;
}
.gx-viewer__progress span.is-running { animation: gxProgress var(--gx-dur, 5s) linear forwards; }
@keyframes gxProgress { to { transform: scaleX(1); } }

/* Stage */
.gx-viewer__stage {
	position: relative;
	min-block-size: 0;
	touch-action: pan-y pinch-zoom;
	user-select: none;
	-webkit-user-select: none;
}
.gx-viewer__figure {
	position: absolute;
	inset: clamp(0.5rem, 2vh, 1.25rem) clamp(0.5rem, 6.5vw, 6rem);
	display: grid;
	place-items: center;
	margin: 0;
}
.gx-viewer__figure.is-entering { animation: gxEnter var(--dur-base) var(--ease-out) both; }
@keyframes gxEnter {
	from { opacity: 0; transform: translateX(calc(var(--gx-dir, 0) * 2.5rem)); }
}
.gx-viewer__media {
	display: block;
	inline-size: auto;
	block-size: auto;
	max-inline-size: 100%;
	max-block-size: 100%;
	border-radius: 0.375rem;
	background: #1C120D;
	box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
	-webkit-user-drag: none;
}

.gx-viewer__nav {
	position: absolute;
	inset-block-start: 50%;
	z-index: 2;
	translate: 0 -50%;
}
.gx-viewer__nav--prev { inset-inline-start: clamp(0.4rem, 1.6vw, 1.5rem); }
.gx-viewer__nav--next { inset-inline-end: clamp(0.4rem, 1.6vw, 1.5rem); }
.gx-viewer__nav:hover { transform: scale(1.06); }

/* Caption + strip */
.gx-viewer p { max-inline-size: none; } /* base.css caps paragraphs at 68ch */
.gx-viewer__caption {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: center;
	gap: 0.2rem 0.75rem;
	min-block-size: 2.4rem;
	padding: 0.3rem clamp(1rem, 4vw, 2rem) 0.2rem;
	text-align: center;
}
.gx-viewer__title {
	font-family: var(--font-hand);
	font-size: clamp(1.25rem, 1.05rem + 0.6vw, 1.6rem);
	line-height: 1.2;
	color: var(--color-parchment);
}
.gx-viewer__strip {
	display: flex;
	gap: 0.4rem;
	overflow-x: auto;
	padding: 0.55rem clamp(0.6rem, 3vw, 1.5rem) max(0.75rem, env(safe-area-inset-bottom));
	scrollbar-width: none;
	overscroll-behavior-x: contain;
}
.gx-viewer__strip::-webkit-scrollbar { display: none; }
.gx-viewer__thumb {
	position: relative;
	flex: 0 0 auto;
	block-size: 3.25rem;
	padding: 0;
	border-radius: 0.3rem;
	overflow: hidden;
	opacity: 0.5;
	outline: 2px solid transparent;
	outline-offset: 1px;
	transition: opacity var(--dur-fast) var(--ease-out), outline-color var(--dur-fast) var(--ease-out);
}
.gx-viewer__thumb:first-child { margin-inline-start: auto; }
.gx-viewer__thumb:last-child { margin-inline-end: auto; }
.gx-viewer__thumb img { block-size: 100%; inline-size: auto; object-fit: cover; }
.gx-viewer__thumb:hover { opacity: 0.85; }
.gx-viewer__thumb[aria-current="true"] { opacity: 1; outline-color: var(--color-parchment); }
.gx-viewer__thumb:focus-visible { opacity: 1; outline-color: var(--color-clay); }

.gx-viewer__toast {
	position: absolute;
	inset-block-end: 6.5rem;
	inset-inline-start: 50%;
	z-index: 3;
	translate: -50% 0;
	padding: 0.45rem 1rem;
	border-radius: var(--radius-full);
	background: var(--color-parchment);
	color: var(--text);
	font-size: var(--text-sm);
	font-weight: 600;
	box-shadow: var(--shadow-lg);
	opacity: 0;
	transition: opacity var(--dur-base) var(--ease-out);
	pointer-events: none;
}
.gx-viewer__toast.is-on { opacity: 1; }

/* ---------- Responsive ---------- */
@media (max-width: 599px) {
	.gx-chapter--photos { padding-block-start: var(--space-xl); }
	.gx-head { margin-block-end: var(--space-lg); }
	.gx__star { display: none; }
	.gx-tile { border-radius: var(--radius-xs); }
	.gx-viewer__figure { inset-inline: 0; }
	.gx-viewer__media { border-radius: 0; }
	.gx-viewer__nav { inline-size: 2.4rem; block-size: 2.4rem; background: rgba(43, 29, 22, 0.45); }
	.gx-viewer__thumb { block-size: 2.75rem; }
	.gx-viewer__toast { inset-block-end: 5.5rem; }
}
@media (min-width: 600px) {
	.gx-grid { --gx-row: 12rem; --gx-gap: 0.75rem; }
}
@media (min-width: 1024px) {
	.gx-grid { --gx-row: 21rem; --gx-gap: 1rem; }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
	.gallery-ribbon__strip { animation: none; }
	.gx__sprig, .gx__star { animation: none; }
	.gx-tile__img, .gx-tile__cap, .gx-viewer__btn { transition: none; }
	.gx-tile__link:hover .gx-tile__img { transform: none; }
	.gx-viewer__figure.is-entering { animation: none; }
}
