/* Block: Image Band (acf/image-band)
   ---------------------------------------------------------------------------
   A full-bleed photo band between the Deep Sea panels. Like the intro panel it
   is `position: relative; z-index: 1` so it paints over the sticky hero
   (`z-index: 0`) as the page scrolls up over it. It ABUTS the panel above —
   no negative margin, no overlap (style.css already zeroes the flow margin via
   `:root .wp-block-acf-image-band`).

   Height: the first slide's native aspect ratio, printed inline by the PHP as
   --band-ratio, with a 400px floor. That is a deliberate departure from the
   comp, which draws the bands at 686/730px tall on the 1512 board (a 2.2:1 and
   a 2.07:1 crop) — image 362 is 2560x1440, so at native ratio the band renders
   ~850px. Agreed with the client in Phase 3.

   Spacing is expressed as custom properties at the top of the block so the
   whole thing can be retuned in one place. The values are the comp's insets
   converted from its (padded) Figma text frames to real CSS line boxes — the
   caption's 48px glyphs sit in a 72px frame, so 12px of that frame is empty at
   each end and has to be added back.

   Comp reference — desktop 71:686 @1512, mobile 122:272 @402.
--------------------------------------------------------------------------- */

.image-band--section {
	/* Mobile (comp band 402x244; pill 21px below the top edge, caption glyphs
	   30px above the bottom) */
	--band-pad-top: 21px;
	--band-pad-bottom: 30px;
	/* .theme-container's 15px mobile gutter is half the comp's 32px, so the
	   block adds the difference back. This is NOT the desktop gutter decision
	   (see below) — it only closes a mobile-only gap. */
	--band-inset: 17px;
	/* On desktop the comp sets the pill's chevrons flush with the caption
	   (both at x=123) and lets the pill's own padding hang 14px further left.
	   On mobile the comp aligns the pill BOX with the caption instead. */
	--band-nav-offset: 0px;
	/* Everything the band paints ON the photo — the arrow pill's border and
	   chevrons, and the captions. Pure white, deliberately NOT the linen token
	   the rest of the theme uses: the client read linen as too dim over these
	   images (twice — the pill on 2026-09-01, the captions right after). One
	   knob so the two can't drift apart; don't "restore" the token. */
	--band-fg: #fff;

	position: relative;
	z-index: 1;
	/* Shows through before the photo paints. */
	background-color: var(--wp--preset--color--deep-sea, #1b2632);
}

/* --- Media --------------------------------------------------------------- */

.image-band--viewport {
	position: relative;
	overflow: hidden;
	/* NOT optional. With `width: auto` and min-height binding, Chrome runs the
	   aspect ratio BACKWARDS and derives the inline size from the height —
	   400px x 16:9 came out as a 711px-wide box inside a 402px phone, blowing
	   out the page with a horizontal scrollbar. Pinning the inline size makes
	   it definite, so the ratio can only ever drive the height. */
	width: 100%;
	/* The band's height. Safe on the hero's sticky — this is a descendant of
	   the sticky element's sibling, not an ancestor of it. */
	aspect-ratio: var(--band-ratio, 16 / 9);
	/* Floor for phones: a wide panorama would otherwise collapse to a ~226px
	   letterbox strip at 402px wide. min-height beats aspect-ratio, which is
	   exactly the behaviour wanted. Left unscoped because it never binds on
	   desktop — at 992px+ even a 2.4:1 crop clears 400px. */
	min-height: 400px;
}

.image-band--slide {
	position: relative;
	width: 100%;
	height: 100%;
}

.image-band--image,
.image-band--video {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: var(--band-media-position, center center);
}

.image-band--video {
	pointer-events: none;
}

/* --- Carousel track ------------------------------------------------------
   Only rendered for 2+ slides. Natively scrollable and swipeable, so it works
   with JS off; js/image-band.js only adds the arrow and keyboard affordances. */

.image-band--track {
	display: flex;
	height: 100%;
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	/* The arrows and swiping are the affordance; a scrollbar over the photo is
	   not part of the design. */
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.image-band--track::-webkit-scrollbar {
	display: none;
}

/* The track is a tab stop (a scrollable region has to be keyboard-reachable),
   so it needs a visible focus ring of its own — but only for keyboard focus.
   Styling `:focus-visible` alone is NOT enough to keep the ring off a click:
   Chrome still paints its own default ring over a plain `:focus`, so that has
   to be cleared first. Order matters — the two selectors are the same
   specificity, so `:focus-visible` only wins by coming second. */
.image-band--track:focus {
	outline: none;
}

.image-band--track:focus-visible {
	outline: 2px solid var(--wp--preset--color--linen, #d7d0c7);
	outline-offset: -4px;
}

.image-band--track > .image-band--slide {
	flex: 0 0 100%;
	scroll-snap-align: start;
}

/* --- Overlay -------------------------------------------------------------
   Per SLIDE, not per band — the client sets the color and opacity on each
   image, and the PHP prints them here as --slide-overlay-color /
   --slide-overlay-opacity. A slide at 0% gets neither the class nor the
   element, so `has-overlay` always means a wash that actually shows; the
   fallbacks below only bind if a slide somehow carries the class without the
   properties. 0.2 black is what the old band-wide overlay painted, the same
   value as --lwh-scrim-soft (the hero uses the 0.3 strong scrim; the bands
   are lighter).

   It sits on the slide, so the wash scrolls in with its own photo, and under
   the content layer's z-index 2, so the pill and caption stay above it. */

.image-band--slide.has-overlay::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background-color: var(--slide-overlay-color, #000);
	opacity: var(--slide-overlay-opacity, 0.2);
	pointer-events: none;
}

/* --- Content layer -------------------------------------------------------
   Arrow pill top-left, caption bottom-left, both over the photo. That is the
   phone layout; from 992px the caption moves to the top-RIGHT, opposite the
   pill — see the desktop block below.

   Gutter decision (Phase 3, binds Phases 4–5): reuse .theme-container as-is
   and accept that its 1280 + 30px puts content at x=146 on the 1512 board,
   ~23px inside the comp's 123. Consistency with intro/copy/section won over
   pixel-matching the comp.

   pointer-events are off so a swipe that starts on the caption still scrolls
   the track underneath; only the pill takes them back. */

.image-band--content {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	padding-top: var(--band-pad-top);
	padding-bottom: var(--band-pad-bottom);
	pointer-events: none;
}

.image-band--content.theme-container {
	padding-left: calc(var(--theme-content-padding) + var(--band-inset));
	padding-right: calc(var(--theme-content-padding) + var(--band-inset));
}

/* --- Arrow pill -----------------------------------------------------------
   100.4 x 48 — comp 100.6 x 48. Both chevrons share the one pill; the left one
   is images/chevron.svg rotated 180°. The clipped bottom-right corner is the
   brand's signature shape at its small radius. */

.image-band--nav {
	display: flex;
	align-items: center;
	gap: 17.6px;
	margin-left: var(--band-nav-offset);
	/* 26.4 glyph + 19.6 padding + 2 border = 48 tall; 2x26.4 + 17.6 gap + 28
	   padding + 2 border = 100.4 wide. Comp: 100.6 x 48. */
	padding: 9.8px 14px;
	border: 1px solid var(--band-fg);
	border-radius: var(--lwh-clip-corner-sm, 10px) var(--lwh-clip-corner-sm, 10px) 0 var(--lwh-clip-corner-sm, 10px);
	background-color: rgba(215, 208, 199, 0.2);
	/* The chevrons take this via `color: inherit`, and their focus ring via
	   currentColor, so the whole control whitens together. */
	color: var(--band-fg);
	pointer-events: auto;
}

.image-band--arrow {
	display: block;
	width: 26.4px;
	height: 26.4px;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	cursor: pointer;
}

.image-band--arrow[disabled] {
	opacity: 0.35;
	cursor: default;
}

/* Keyboard focus only. Clicking an arrow focuses it, and Chrome paints its own
   default ring on that plain `:focus` however carefully the author rule below
   is scoped to `:focus-visible` — so clear it here first. Same specificity as
   the rule below, which therefore has to stay second to win. */
.image-band--arrow:focus {
	outline: none;
}

.image-band--arrow:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 4px;
	border-radius: 2px;
}

.image-band--chevron {
	display: block;
	width: 100%;
	height: 100%;
}

.image-band--arrow.is-prev .image-band--chevron {
	transform: rotate(180deg);
}

/* --- Captions -------------------------------------------------------------
   One caption per slide, all printed into this single layer and cross-faded by
   js/image-band.js as the track scrolls (see the block's PHP header for why
   they are all in the markup rather than one element whose text is swapped).

   Child selectors, not the bare classes: the caption carries `.h4`, whose
   `margin: 0` lives in style.css — which the browser loads AFTER this block
   stylesheet, so at equal specificity it would win. */

.image-band--content > .image-band--captions {
	/* Pins to the bottom whether or not the pill is above it — space-between
	   would move it to the top of a caption-only band. */
	margin-top: auto;
	/* Every caption occupies the SAME cell, so the layer is as tall as the
	   longest one and the band never reflows as the captions swap. */
	display: grid;
}

.image-band--captions > .image-band--caption {
	grid-area: 1 / 1;
	/* Bottom-aligned in the shared cell, so a one-line and a two-line caption
	   put their last line at the same offset from the band's bottom edge —
	   the anchor the comp draws to. */
	align-self: end;
	margin: 0;
	color: var(--band-fg);
	text-wrap: balance;
	opacity: 0;
	/* Not opacity alone: a transparent caption would still be hit-testable and,
	   more to the point, still read out by a screen reader. `visibility` is
	   stepped at the END of the fade out and immediately on the way in. */
	visibility: hidden;
	transition: opacity 0.4s ease, visibility 0s linear 0.4s;
}

.image-band--captions > .image-band--caption.is-active {
	opacity: 1;
	visibility: visible;
	transition: opacity 0.4s ease, visibility 0s;
}

@media (prefers-reduced-motion: reduce) {
	.image-band--captions > .image-band--caption,
	.image-band--captions > .image-band--caption.is-active {
		transition: none;
	}
}

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

@media (min-width: 992px) {
	.image-band--section {
		/* comp band 1512x686: pill 49px below the top edge. The caption used
		   to sit 57px above the bottom (its 72px frame bottom is 45px up, less
		   12px of empty frame); it now shares the pill's top edge instead, so
		   --band-pad-bottom no longer positions anything on desktop and is kept
		   only so the property has a value at every width. */
		--band-pad-top: 49px;
		--band-pad-bottom: 57px;
		--band-inset: 0px;
		/* 14px of pill padding + its 1px border, so the chevrons sit flush with
		   the container's content edge the way the comp has them (x=123 there —
		   the caption they were flush WITH has since moved to the far side). */
		--band-nav-offset: -15px;
	}

	/* Caption top-right, opposite the pill (client, 2026-09-09; phones keep it
	   bottom-left, under the pill). The content layer becomes a row: the pill
	   leads, the caption layer is pushed to the far edge and its lines rag
	   left against that edge. Both share --band-pad-top, so their tops sit
	   level — and at the H4's 48px on a 1.0 line-height the caption's line box
	   is the pill's 48px too, so the two read as one header row over the
	   photo. */
	.image-band--content {
		flex-direction: row;
		justify-content: space-between;
		align-items: flex-start;
	}

	.image-band--content > .image-band--captions {
		margin-top: 0;
		/* space-between only separates two children; a caption-only band (one
		   slide, no pill) has one, and this still sends it to the right. */
		margin-left: auto;
		/* Leaves the pill its corner and keeps a long caption from running
		   the full band as a single line — it wraps well before the pill. */
		max-width: 60%;
		text-align: right;
	}

	/* The shared cell's anchor flips with the position: the FIRST line now
	   holds the top edge, so a one-line and a two-line caption start at the
	   same offset from the top of the band. */
	.image-band--captions > .image-band--caption {
		align-self: start;
	}
}

/* --- Block editor --------------------------------------------------------
   ACF renders the block in preview mode; nothing here needs disabling the way
   the hero's sticky does. The placeholder keeps the canvas from looking broken
   before any slide is chosen. */

.image-band--placeholder {
	margin: 0;
	padding: 60px 30px;
	color: var(--wp--preset--color--linen, #d7d0c7);
	background-color: var(--wp--preset--color--deep-sea, #1b2632);
	border: 1px dashed rgba(215, 208, 199, 0.4);
	text-align: center;
}
