/* Block: Photo Grid (acf/photo-grid)
   ---------------------------------------------------------------------------
   Captioned photos in a grid; each opens in GLightbox. Phone first; the comp
   is the 1512 board only (Figma 9eBn6GzkM1aHMg59Ck62cP, 363:517 in 363:462),
   the phone and tablet layouts are extrapolated. Notes:
   docs/photo-grid-block.md.

   Comp at 1512 (363:517, x 64, 1384 x 640):
     tiles    446 x 309, three columns 23px apart, rows 22px apart; the third
              column one 446 x 640 photo. One large rounded corner on two of
              them (60px: the tall photo's top right, the lower left photo's
              top left).
     caption  a 36px bar across the tile's foot, #33534C (Keane's green) at
              80%, Rig Sans Light 20/29 white, ink from 11px in, cap line 13px
              below the bar's top.
     "+"      27 x 29.5, two 3px round-capped strokes, about 20px in and 14px
              down. Linen in the comp, white here (below).
     spacing  62px from the map's foot (2191) to the grid (2253); 121px from
              the grid to the Keane's panel (3014), which lifts 73px over the
              section, so the section keeps 194 below the grid.

   Layout tiers (the roles are printed as classes by photo-grid.php, which
   also works out each photo's `sizes` from these same boxes):
     phones      one column, 15px gutters; small tiles 446:309, the tall one
                 446:640
     768-1199    two columns; the tall photo and any photo that would sit
                 alone in its row (is-wide-mod) span both, at 16:9
     1200+       the comp: six tracks, a small tile spans two (446 at 1512),
                 the tall one two rows; is-half-mod spans three, is-full-mod
                 all six

   Block stylesheets print BEFORE reset.min.css and style.css (header.md, "CSS
   order trap"), so every rule here wins on specificity, never on order. This
   one depends on lwh-glightbox, so GLightbox's own stylesheet prints first
   and the lightbox rules at the end win their ties.
--------------------------------------------------------------------------- */

.photo-grid--section {
	--pg-gutter: 15px;
	--pg-col-gap: 15px;
	--pg-row-gap: 15px;
	--pg-pad-top: 60px;
	--pg-pad-bottom: 60px;
	/* How far the next block rides up over this one (a feature panel). */
	--pg-lift: 0px;
	--pg-radius: var(--lwh-media-radius, 60px);
	/* The comp's caption bar: #33534C at 80%, i.e. Keane's green. */
	--pg-bar: rgba(52, 83, 77, 0.8);
	--pg-fg: #fff;
	--pg-ring: var(--wp--preset--color--deep-sea, #1b2632);

	position: relative;
	/* Over the pinned short hero (hero.css), like the map and the panels. */
	z-index: 1;
	padding: var(--pg-pad-top) 0 calc(var(--pg-pad-bottom) + var(--pg-lift));
	background-color: var(--wp--preset--color--linen, #d7d0c7);
}

/* After the map: the map's own tail (60/90px, its placeholder "until the
   photo grid exists") becomes the comp's gap, 62px at 1512 (40 on phones),
   and the grid drops its own top padding. Where :has() is unsupported the gap
   is just the map's 60/90. */
.neighborhood-map--section:has(+ .photo-grid--section) {
	--nmap-tail: 40px;
}

.neighborhood-map--section + .photo-grid--section {
	--pg-pad-top: 0px;
}

/* A feature panel after the grid (Keane's) lifts over its foot, 60px on
   phones and 73 from 992 (feature.css, --feature-panel-overlap); the section
   keeps that much more so the gap above the panel stays the design's. */
.photo-grid--section:has(+ .feature--section.panel-mod) {
	--pg-lift: 60px;
}

.photo-grid--container {
	position: relative;
	z-index: 1;
	padding: 0 var(--pg-gutter);
}

.photo-grid--section .photo-grid--grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--pg-row-gap) var(--pg-col-gap);
	max-width: 1384px;
	margin: 0 auto;
	padding: 0;
	list-style: none;
}

/* The tile is the box (its height from its ratio, or from the rows it spans);
   the link fills it. The caption sizes itself to the tile (cqw), so the
   tile is a size container. */
.photo-grid--section .photo-grid--tile {
	position: relative;
	margin: 0;
	padding: 0;
	aspect-ratio: 446 / 309;
	container-type: inline-size;
}

.photo-grid--section .photo-grid--tile.is-tall-mod {
	aspect-ratio: 446 / 640;
}

.photo-grid--section .photo-grid--link {
	position: absolute;
	inset: 0;
	display: block;
	overflow: hidden;
	/* What shows until a lazy photo arrives. */
	background-color: #c9c1b6;
	color: var(--pg-fg);
	text-decoration: none;
	cursor: pointer;
}

.photo-grid--section .photo-grid--link:hover {
	color: var(--pg-fg);
	text-decoration: none;
}

.photo-grid--section .corner-top-left-mod .photo-grid--link {
	border-top-left-radius: var(--pg-radius);
}

.photo-grid--section .corner-top-right-mod .photo-grid--link {
	border-top-right-radius: var(--pg-radius);
}

/* Keyboard focus only: the site's 2px ring, Deep Sea on Linen, 3px out
   (inside the gap between tiles), following the rounded corner. A mouse
   click draws none. */
.photo-grid--section .photo-grid--link:focus-visible {
	outline: 2px solid var(--pg-ring);
	outline-offset: 3px;
}

.photo-grid--section .photo-grid--image {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	max-width: none;
	object-fit: cover;
}

/* The "+": white, with the comp's own drop shadow (Group 77's filter: 0 4px,
   blur 2, 25% black) on every tile, so it reads on the ferry's white sky. */
.photo-grid--plus {
	position: absolute;
	top: 13px;
	left: 20px;
	z-index: 2;
	display: block;
	width: 30px;
	height: 30px;
	color: var(--pg-fg);
	filter: drop-shadow(0 4px 4px rgba(0, 0, 0, 0.25));
	pointer-events: none;
}

.photo-grid--plus-icon {
	display: block;
	width: 100%;
	height: 100%;
}

/* The caption bar. 20px as drawn, smaller only where the tile is too narrow
   for the comp's longest caption ("8 minute walk to the Seattle Ferry
   Terminal.", 372px of ink at 20px) to fit on one line: the size follows the
   tile's width (cqw), never under 16px. A longer caption wraps and the bar
   grows upwards. Without container units the size stays 20px. */
.photo-grid--caption {
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 2;
	display: block;
	padding: 0.3em 0.5em 0.05em;
	background-color: var(--pg-bar);
	color: var(--pg-fg);
	font-family: var(--wp--preset--font-family--sans, sans-serif);
	font-size: 20px;
	font-size: clamp(16px, calc((100cqw - 20px) * 0.0527), 20px);
	font-weight: 300;
	line-height: 1.45;
	letter-spacing: 0;
	text-align: left;
}

/* A gentle push-in on hover, as a cue that the photo opens (ours; the comp
   has no hover). Pointer devices with motion welcome only. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
	.photo-grid--section .photo-grid--image {
		transition: transform 0.6s ease;
	}

	.photo-grid--section .photo-grid--link:hover .photo-grid--image {
		transform: scale(1.04);
	}
}

.photo-grid--placeholder {
	margin: 0;
	padding: 40px 20px;
	border: 1px dashed currentColor;
	color: var(--wp--preset--color--deep-sea, #1b2632);
	font-size: 16px;
	text-align: center;
}

/* --- Tablet: two columns ------------------------------------------------------- */

@media (min-width: 768px) {
	.photo-grid--section {
		--pg-gutter: 30px;
		--pg-col-gap: 23px;
		--pg-row-gap: 22px;
	}

	.photo-grid--section .photo-grid--grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.photo-grid--section .photo-grid--tile.is-wide-mod {
		grid-column: 1 / -1;
		aspect-ratio: 16 / 9;
	}
}

/* --- Desktop --------------------------------------------------------------------- */

@media (min-width: 992px) {
	.photo-grid--section {
		/* 64px at 1512 (the comp's x), never under 30. */
		--pg-gutter: max(30px, 4.2328vw);
		--pg-pad-top: 90px;
		--pg-pad-bottom: 121px;
	}

	.neighborhood-map--section:has(+ .photo-grid--section) {
		--nmap-tail: 62px;
	}

	.photo-grid--section:has(+ .feature--section.panel-mod) {
		--pg-lift: 73px;
	}

	/* The comp's band behind the map (363:483, the Linen pinstripe from x 924)
	   runs on 80px past the grid's top edge, so the stripes carry on behind
	   the grid's top right. Same box and phase as the map's
	   .neighborhood-map--body::before. */
	.neighborhood-map--section + .photo-grid--section::before {
		content: "";
		position: absolute;
		top: 0;
		left: 61.1%;
		right: 0;
		z-index: 0;
		height: 80px;
		background-image: url(../../images/pattern-linen-pinstripe.webp);
		background-repeat: repeat;
		background-size: 14.54px 4px;
		background-position: left top;
		pointer-events: none;
	}
}

/* --- The comp: three columns ----------------------------------------------------- */

@media (min-width: 1200px) {
	.photo-grid--section .photo-grid--grid {
		grid-template-columns: repeat(6, minmax(0, 1fr));
	}

	.photo-grid--section .photo-grid--tile,
	.photo-grid--section .photo-grid--tile.is-wide-mod {
		grid-column: span 2;
		aspect-ratio: 446 / 309;
	}

	/* Two rows and the gap between them: its height comes from the rows. */
	.photo-grid--section .photo-grid--tile.is-tall-mod {
		grid-row: span 2;
		aspect-ratio: auto;
	}

	/* A small tile's height on half the row (2.2 = 680.5 / 309 at 1512). */
	.photo-grid--section .photo-grid--tile.is-half-mod {
		grid-column: span 3;
		aspect-ratio: 2.2;
	}

	.photo-grid--section .photo-grid--tile.is-full-mod {
		grid-column: 1 / -1;
		aspect-ratio: 1384 / 640;
	}
}

/* --- The lightbox ----------------------------------------------------------------
   GLightbox 3.3.1 (js/glightbox.min.js), opened by js/photo-grid.js, which
   adds .photo-grid--lightbox to its container. Restyled to the site's own
   lightbox (css/lightbox.css): Deep Sea at 78% with a blur, round 48px
   Linen-outlined buttons, and the caption in the tile's green bar under the
   photo, as wide as the photo. Every layout rule is set here at all widths,
   so GLightbox's own 769px switch (its "mobile" layout) changes nothing; the
   arrows move from under the photo to its sides at 768. Specificity (0,3,0)
   and up, and this file prints after GLightbox's, which wins any tie.

   GLightbox sizes the photo itself above 768px wide, with an inline
   max-height (100vh less the caption) and the caption's max-width to match;
   the photo's room is ours at every width, hence the two !important max
   sizes below: they override a third-party inline style. */

.glightbox-container.photo-grid--lightbox {
	--pgl-fg: var(--wp--preset--color--linen, #d7d0c7);
	--pgl-bg: var(--wp--preset--color--deep-sea, #1b2632);
	/* Room kept clear beside and above/below the photo: the close button
	   above, the arrows below (phones) or beside (768+), the caption bar. */
	--pgl-side: 16px;
	--pgl-chrome: 260px;

	font-family: var(--wp--preset--font-family--sans, sans-serif);
}

.glightbox-container.photo-grid--lightbox .goverlay,
.glightbox-mobile .glightbox-container.photo-grid--lightbox .goverlay {
	background: rgba(27, 38, 50, 0.78);
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
}

/* As wide as the photo: the caption below takes no width of its own
   (width 0, min-width 100%), so it wraps to the photo's width. */
.glightbox-container.photo-grid--lightbox .ginner-container {
	flex-direction: column;
	width: -moz-fit-content;
	width: fit-content;
	max-width: 100%;
	height: auto;
	margin: auto;
}

.glightbox-container.photo-grid--lightbox .gslide-media {
	box-shadow: 0 4px 24px rgba(0, 0, 0, 0.35);
}

.glightbox-container.photo-grid--lightbox .gslide-image img {
	width: auto;
	height: auto;
	min-width: 0;
	max-width: calc(100vw - 2 * var(--pgl-side)) !important;
	max-height: calc(100vh - var(--pgl-chrome)) !important;
	max-height: calc(100svh - var(--pgl-chrome)) !important;
}

/* The caption: the tile's bar, solid, under the photo and as wide as it. */
.glightbox-container.photo-grid--lightbox .gslide-description,
.glightbox-mobile .glightbox-container.photo-grid--lightbox .gslide-description {
	position: static;
	flex: 0 0 auto;
	order: 1 !important; /* beats GLightbox's mobile order: 2 !important (same thing, after the photo) */
	width: 0;
	min-width: 100%;
	max-height: none;
	padding: 0;
	overflow: visible !important; /* GLightbox's mobile rule: overflow: auto !important */
	background: var(--wp--preset--color--keanes-green, #34534d);
}

.glightbox-container.photo-grid--lightbox .gdesc-inner {
	padding: 6px 10px 1px;
}

.glightbox-container.photo-grid--lightbox .gslide-title {
	display: none;
}

.glightbox-container.photo-grid--lightbox .gslide-desc,
.glightbox-mobile .glightbox-container.photo-grid--lightbox .gslide-desc {
	margin: 0;
	color: #fff;
	font-family: var(--wp--preset--font-family--sans, sans-serif);
	font-size: 20px;
	font-weight: 300;
	line-height: 29px;
	letter-spacing: 0;
	text-align: left;
}

/* The buttons: the site lightbox's round close button, for all three. */
.glightbox-container.photo-grid--lightbox .gbtn {
	position: absolute;
	box-sizing: border-box;
	width: 48px;
	height: 48px;
	padding: 0;
	border: 1px solid var(--pgl-fg);
	border-radius: 50%;
	background-color: rgba(27, 38, 50, 0.6);
	color: var(--pgl-fg);
	opacity: 1;
	transition: background-color 0.2s ease, color 0.2s ease;
}

/* Hover only where there is a real hover: on a touch screen the tapped
   button stayed filled (Phase 7 audit NB-5, 2026-10-15). */
@media (hover: hover) {
	.glightbox-container.photo-grid--lightbox .gbtn:hover {
		background-color: var(--pgl-fg);
		color: var(--pgl-bg);
	}
}

/* GLightbox marks the button its Tab handler moved to as .focused and rings
   it; the ring is ours, on :focus-visible, so a mouse open shows none. */
.glightbox-container.photo-grid--lightbox .gbtn.focused {
	outline: none;
}

.glightbox-container.photo-grid--lightbox .gbtn:focus-visible {
	outline: 2px solid var(--pgl-fg);
	outline-offset: 3px;
}

.glightbox-container.photo-grid--lightbox .gbtn svg {
	width: 20px;
	height: 20px;
}

/* GLightbox's skin fills the icons' paths; ours are strokes. */
.glightbox-container.photo-grid--lightbox .gbtn path {
	fill: none;
	stroke: currentColor;
}

.glightbox-container.photo-grid--lightbox .gclose {
	top: 12px;
	right: 12px;
}

.glightbox-container.photo-grid--lightbox .gprev,
.glightbox-container.photo-grid--lightbox .gnext {
	top: auto;
	bottom: 16px;
	bottom: max(16px, env(safe-area-inset-bottom));
}

.glightbox-container.photo-grid--lightbox .gprev {
	left: calc(50% - 60px);
}

.glightbox-container.photo-grid--lightbox .gnext {
	right: calc(50% - 60px);
}

/* GLightbox 3.3 quirk (as amenities.css): on a one-photo gallery its own
   display: flex beats its display: none, and the arrows linger at 10%. */
.glightbox-container.photo-grid--lightbox .gbtn.glightbox-button-hidden {
	display: none;
}

@media (min-width: 768px) {
	.glightbox-container.photo-grid--lightbox {
		--pgl-side: 96px;
		/* The close button (24 + 48) above, the caption and 24px below. */
		--pgl-chrome: 160px;
	}

	.glightbox-container.photo-grid--lightbox .gclose {
		top: 24px;
		right: 24px;
	}

	.glightbox-container.photo-grid--lightbox .gprev,
	.glightbox-container.photo-grid--lightbox .gnext {
		top: calc(50% - 24px);
		bottom: auto;
	}

	.glightbox-container.photo-grid--lightbox .gprev {
		left: 24px;
	}

	.glightbox-container.photo-grid--lightbox .gnext {
		right: 24px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.glightbox-container.photo-grid--lightbox .gbtn {
		transition: none;
	}
}
