/* ==========================================================================
   Photos section — sidebar nav + fanned polaroid stacks that expand
   in place into a gallery grid, plus a lightbox with prev/next.
   Blends onto the existing #bg dark background; no new color palette.
   ========================================================================== */

/* main.css sets html{font-size:16pt} with THREE separate media queries
   (1680px, 736px, 360px) that change it further. Since every measurement
   in this file is in rem, all of it was silently jumping to different
   actual pixel values at those thresholds — independent of our own
   40rem breakpoint — which is what caused both the resize jumpiness and
   the nav landing in unexpected places at certain widths. Locking it
   here keeps our rem math consistent at every window size. Scoped to
   this file only, so the homepage's own responsive type sizing (which
   this rule doesn't touch) is unaffected. */
html {
	font-size: 16px !important;
	/* Reserves permanent space for the vertical scrollbar so it can't
	   appear/disappear based on content height (e.g. a lower stack's
	   hover fan-out pushing total page height just past the viewport)
	   — that toggle was shifting the centered page content sideways.
	   background matches body's own base color (see main.css) so the
	   reserved gutter blends in instead of showing as a visible empty
	   strip, which is why this was removed once before. */
	scrollbar-gutter: stable;
	background: #1b1f22;
}

/* main.css fades #bg in from black over 2.5s (with a 0.75s delay) —
   nicely paced against the homepage's typewriter effect, but this page
   has no such animation to sync with, so settling faster here reads
   better. Scoped to this file only, so the homepage keeps its original
   timing untouched. */
#bg:before {
	transition-duration: 1.2s !important;
	transition-delay: 0.3s !important;
}

/* Dimension is built as a single-screen hero page and isn't expecting
   content taller than the viewport, so without an explicit allowance
   here, tall content (many albums, or a short window) can end up
   visually clipped at the bottom with no way to scroll to it. */
html,
body {
	overflow-y: auto !important;
	height: auto !important;
	scrollbar-gutter: stable;
	/* Browsers auto-adjust scroll position ("scroll anchoring") when
	   layout above the current view shrinks — like a grid collapsing
	   back down to its smaller stack. That's what was causing sections
	   further down the page to visibly "fall into place" after
	   collapsing, since their collapse is more likely to trigger the
	   browser's anchoring than a section already near the top. */
	overflow-anchor: none;
	/* Hide the scrollbar's visible track/thumb — scrolling still works
	   via wheel, trackpad, or keyboard. scrollbar-gutter above still
	   reserves the space either way, so this doesn't reintroduce any
	   layout shift; it just makes that reserved space blend into the
	   background instead of showing a visible bar. */
	scrollbar-width: none; /* Firefox */
	-ms-overflow-style: none; /* old Edge/IE */
}

html::-webkit-scrollbar,
body::-webkit-scrollbar {
	display: none; /* Chrome, Safari, new Edge */
}

/* Confirmed via main.css: #wrapper is `display:flex; flex-direction:column;
   justify-content:space-between; min-height:100vh;`, and #wrapper:before
   is an empty flex item. With only that empty item and our real content
   as the two flex children, space-between pushes our content toward the
   bottom — and that gap grows as the viewport gets taller, which is
   exactly the drift we saw. This file only loads on the photos pages, so
   it's safe to switch #wrapper back to plain top-aligned block layout
   here without touching the homepage. Padding is zeroed too, since with
   display:block that padding would otherwise stack on top of
   .photos-wrapper's own padding instead of being absorbed into the
   flex centering like it was before. */
body,
#wrapper {
	display: block !important;
	align-items: normal !important;
	justify-content: normal !important;
	min-height: 0 !important;
	height: auto !important;
	padding: 0 !important;
}

#wrapper:before {
	display: none !important;
}

.photos-wrapper {
	max-width: 44rem;
	margin: 0 auto;
	padding: 3rem 2rem 5rem;
}

.photos-back {
	display: inline-flex;
	align-items: center;
	gap: 0.15rem;
	margin-bottom: 2rem;
	opacity: 0.7;
	text-decoration: none;
	border: none !important;
	outline: none !important;
	box-shadow: none !important;
	background: none !important;
	padding: 0 !important;
	-webkit-appearance: none;
	appearance: none;
	transition: opacity 0.2s ease;
}

.photos-back:hover {
	opacity: 1;
}

.photos-back-arrow {
	display: block;
	width: 1rem;
	height: 1rem;
	flex-shrink: 0;
}

.photos-back img {
	display: block;
	width: 3rem;
	height: 3rem;
	border-radius: 4px;
	flex-shrink: 0;
	margin-left: -0.6rem;
	filter: brightness(0) invert(1);
}

/* ---------- Row: sidebar nav list + main stack content, side by side.
   Home lives above this row (as a separate block, see .photos-back)
   rather than inside it — that way both columns here start completely
   fresh with nothing above them, so align-items:flex-start lines up the
   nav's first item with the stack's first title exactly, with no
   measurement or hardcoded offset needed at all. Normal document flow
   throughout — no position:fixed, no viewport-relative calc(). The page
   never scrolls at this size, so there's no real need for fixed
   positioning, and every fixed/calc()-based approach we tried turned out
   to be fragile in ways that were hard to fully pin down and patch. ---------- */

.photos-row {
	display: flex;
	align-items: flex-start;
	gap: 3rem;
}

/* Hamburger toggle — hidden on wide screens, shown (and functional) only
   within the mobile breakpoint below. Reuses .icon-btn's circular styling.
   !important guards against .icon-btn's own display:flex (equal
   specificity, defined later in this file) silently winning. */
.nav-toggle {
	display: none !important;
	position: fixed;
	bottom: 2rem;
	left: 50%;
	transform: translateX(-50%);
	z-index: 21;
}

#sidebar-nav {
	flex: 0 0 auto;
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
}

#sidebar-nav a {
	text-decoration: none;
	color: inherit;
	opacity: 0.45;
	transition: opacity 0.2s ease;
	background: none;
	border: none;
	text-align: left;
	padding: 0;
	font: inherit;
	cursor: pointer;
	white-space: nowrap;
}

#sidebar-nav a:hover,
#sidebar-nav a.is-current {
	opacity: 1;
}

.photos-main {
	flex: 1;
	min-width: 0;
}

.album-section {
	text-align: center;
	margin-bottom: 3.5rem;
	scroll-margin-top: 2rem;
}

.album-section:last-child {
	margin-bottom: 0;
}

.album-section-title {
	text-decoration: none;
	color: inherit;
	display: inline-block;
	margin-bottom: 1.25rem;
	opacity: 0.85;
	transition: opacity 0.2s ease;
	background: none !important;
	border: none !important;
	outline: none !important;
	box-shadow: none !important;
	padding: 0 !important;
	font: inherit;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
}

.album-section-title:hover {
	opacity: 1;
}

.album-section-title h2 {
	margin: 0;
	font-size: 1em;
	font-weight: 400;
	letter-spacing: normal;
	text-transform: none;
	white-space: nowrap;
}

.photos-subtitle {
	text-align: center;
	opacity: 0.5;
	margin: -1rem 0 3.5rem;
}

/* ---------- Fanned 4-photo stack ---------- */

.polaroid-stack {
	position: relative;
	width: 8.5rem;
	height: 10.625rem;
	margin: 0 auto;
	cursor: pointer;
	opacity: 1;
	transform: scale(1);
	/* No persistent transition here — JS grants one temporarily via
	   inline style right before toggling is-fading (expand/collapse),
	   then clears it. A permanent transition here was letting any
	   resize-triggered layout recalculation animate visibly even when
	   the final value hadn't actually changed, which was the real
	   cause of the resize jumpiness. */
}

.polaroid-stack.is-fading {
	opacity: 0 !important;
	transform: scale(0.96);
	pointer-events: none !important;
	visibility: hidden;
}

.polaroid-stack.is-hidden {
	display: none;
}

/* Whenever any panel is open, disable pointer-events on every stack —
   not just the one that's fading. A stack lower on the page can end up
   spatially underneath where the centered panel renders, and something
   about the stacking order was letting it win the hit-test over the
   panel despite the panel's higher z-index. This is the robust
   catch-all: no stack can ever intercept a click meant for the panel
   while one is open, regardless of the exact mechanism. */
body.grid-expanded .polaroid-stack {
	pointer-events: none !important;
}

.polaroid-stack .stack-item {
	position: absolute;
	inset: 0;
	/* Same reasoning — no persistent transition. JS adds one temporarily
	   on mouseenter/mouseleave for the hover fan-out effect. */
}

.polaroid-stack .stack-item .polaroid {
	transition: box-shadow 0.2s ease;
}

.polaroid-stack .stack-item:nth-child(1) { z-index: 1; }
.polaroid-stack .stack-item:nth-child(2) { z-index: 2; }
.polaroid-stack .stack-item:nth-child(3) { z-index: 3; }
.polaroid-stack .stack-item:nth-child(4) { z-index: 4; }

/* Fixed rem values, not percentages — the stack is always exactly 8.5rem,
   so these are just percentages pre-multiplied against that. Percentage
   translate() values recompute relative to the element's own box on any
   resize-triggered layout pass, and since transform has a transition,
   that recomputation was firing the transition visibly even when the
   resulting pixel value hadn't actually changed — that was the real
   cause of the resize jumpiness. */
.polaroid-stack .stack-item:nth-child(1) { transform: rotate(-11deg) translate(-1.19rem, 0.85rem); }
.polaroid-stack .stack-item:nth-child(2) { transform: rotate(-4deg) translate(-0.51rem, 0.425rem); }
.polaroid-stack .stack-item:nth-child(3) { transform: rotate(4deg) translate(0.425rem, 0.106rem); }
.polaroid-stack .stack-item:nth-child(4) { transform: rotate(10deg) translate(0.935rem, -0.106rem); }

.polaroid-stack:hover .stack-item:nth-child(1) { transform: rotate(-15deg) translate(-1.7rem, 1.169rem); }
.polaroid-stack:hover .stack-item:nth-child(2) { transform: rotate(-6deg) translate(-0.765rem, 0.531rem); }
.polaroid-stack:hover .stack-item:nth-child(3) { transform: rotate(6deg) translate(0.68rem, 0); }
.polaroid-stack:hover .stack-item:nth-child(4) { transform: rotate(14deg) translate(1.36rem, -0.425rem); }

/* Individual-photo hover — highlight only the frame itself. No movement,
   no scale, no un-rotating, no z-index change: just the visible polaroid
   edge lighting up so it's clear which one you're about to click. Now that
   the rotation lives on .stack-item itself, hover hit-testing follows the
   actual rotated shape instead of each card's full (overlapping) box. */
.polaroid-stack .stack-item:hover .polaroid {
	box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.55), 0 0.75rem 1.75rem rgba(0, 0, 0, 0.45);
}

/* ---------- Polaroid frame (shared) — generous mat, true polaroid ratio ---------- */

.polaroid {
	background: #fff;
	padding: 7% 7% 10%;
	box-shadow: 0 0.75rem 1.75rem rgba(0, 0, 0, 0.45);
	border-radius: 2px;
	aspect-ratio: 4 / 5;
}

.polaroid img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* ---------- Expanded gallery grid — a centered overlay panel, not
   part of document flow. Other stacks stay exactly where they are,
   dimmed behind the backdrop, since nothing about their layout changes
   when a panel opens. ---------- */

.grid-overlay-backdrop {
	position: fixed;
	inset: 0;
	background: rgba(10, 11, 13, 0.75);
	z-index: 29;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.3s ease;
}

.grid-overlay-backdrop.is-open {
	opacity: 1;
	pointer-events: auto;
}

.grid-overlay-panel {
	position: fixed;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%) scale(0.9);
	z-index: 30;
	max-width: min(90vw, 44rem);
	max-height: 85vh;
	overflow-y: auto;
	background: rgba(20, 22, 28, 0.97);
	border-radius: 0.75rem;
	padding: 2rem 2rem 1.5rem;
	box-shadow: 0 2rem 4rem rgba(0, 0, 0, 0.6);
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.3s ease, transform 0.3s ease;
}

.grid-overlay-panel.is-open {
	opacity: 1;
	pointer-events: auto;
	transform: translate(-50%, -50%) scale(1);
}

.grid-overlay-panel.is-hidden {
	display: none;
}

.gallery-grid {
	display: grid;
	grid-template-columns: repeat(4, 8.5rem);
	justify-content: center;
	gap: 1.5rem;
}

.polaroid-stack.is-hidden {
	display: none;
}

.gallery-grid .polaroid {
	cursor: pointer;
	transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.gallery-grid .polaroid:hover {
	transform: translateY(-4px);
	box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.5);
}

.grid-close-wrap {
	display: flex;
	justify-content: center;
	margin-top: 1.5rem;
}

/* While viewing a photo in the lightbox, hide the "collapse grid back to
   stack" button — otherwise it faintly shows through the lightbox's
   semi-transparent backdrop, reading as a stray close button in the
   photo view when it's actually meant only for returning to the stack. */
body.lightbox-open .grid-close-wrap {
	visibility: hidden;
}

.icon-btn {
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 50%;
	border: 1px solid rgba(255, 255, 255, 0.2);
	background: rgba(255, 255, 255, 0.06);
	color: #eee;
	cursor: pointer;
	transition: background 0.2s ease, transform 0.2s ease;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	line-height: 1;
}

.icon-btn:hover {
	background: rgba(255, 255, 255, 0.14);
}

.icon-btn svg {
	width: 1rem;
	height: 1rem;
	display: block;
}

.grid-close-btn:hover {
	transform: scale(1.05);
}

/* ---------- Lightbox, with prev/next ---------- */

.lightbox {
	position: fixed;
	inset: 0;
	background: rgba(20, 22, 28, 0.72);
	display: flex;
	align-items: center;
	justify-content: center;
	flex-direction: column;
	z-index: 1000;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.35s ease;
	padding: 2rem;
}

.lightbox.is-open {
	opacity: 1;
	pointer-events: auto;
}

.lightbox .lightbox-frame {
	background: #fff;
	padding: 3% 3% 5%;
	box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.6);
	max-width: min(90vw, 42rem);
	max-height: 78vh;
	transform: scale(0.82);
	transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
	will-change: transform;
}

.lightbox.is-open .lightbox-frame {
	transform: scale(1);
}

.lightbox img {
	display: block;
	max-width: 100%;
	max-height: calc(78vh - 4rem);
	object-fit: contain;
}

.lightbox .lightbox-caption {
	color: #eee;
	margin-top: 1.25rem;
	font-size: 0.95em;
	opacity: 0.8;
	text-align: center;
}

.lightbox .lightbox-close {
	position: absolute;
	top: 1.5rem;
	right: 2rem;
}

.lightbox .lightbox-close svg {
	width: 1.1rem;
	height: 1.1rem;
}

.lightbox .lightbox-nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
}

.lightbox .lightbox-nav svg {
	width: 1.15rem;
	height: 1.15rem;
}

.lightbox .lightbox-prev {
	left: 1.5rem;
}

.lightbox .lightbox-next {
	right: 1.5rem;
}

@media (max-width: 40rem) {
	.photos-wrapper {
		padding: 3rem 1.25rem 3rem;
	}

	.photos-row {
		flex-direction: column;
		align-items: stretch;
		gap: 1.25rem;
	}

	.gallery-grid {
		grid-template-columns: repeat(2, 8.5rem);
	}

	.nav-toggle {
		display: flex !important;
	}

	body.grid-expanded .nav-toggle {
		display: none !important;
	}

	#sidebar-nav {
		display: none;
		position: fixed;
		bottom: 5.5rem;
		left: 50%;
		transform: translateX(-50%);
		background: rgba(20, 22, 28, 0.95);
		border: 1px solid rgba(255, 255, 255, 0.15);
		border-radius: 0.75rem;
		padding: 1rem 1.75rem;
		gap: 0.75rem;
		z-index: 20;
		box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.5);
		white-space: nowrap;
		text-align: center;
	}

	#sidebar-nav.is-open {
		display: flex;
	}

	.lightbox .lightbox-nav {
		width: 2.25rem;
		height: 2.25rem;
	}

	.lightbox .lightbox-prev { left: 0.5rem; }
	.lightbox .lightbox-next { right: 0.5rem; }
}