/* templates/archive-case-study.html — styling shared by the pieces only used on the Our Work
   archive (case-study photo frame + decorative play-badge overlay, ROI stat bar). Gated to load only
   on the "Case Study" category archive (functions.php, is_category('case-study')) since it's
   template-specific, same lazy-loading reasoning already used for archive-insights.css. The filter-bar
   dropdown/pagination-pill styling is NOT duplicated here — this template is also a category archive,
   so archive-insights.css's .bpd-filter-select/.bpd-pagination rules already apply (loaded sitewide on
   any is_category()||is_tag() request per the existing gate). */

/* Case-study card photo frame — relative positioning host for the decorative play-badge overlay,
   plus the design's xlg corner radius.

   The radius lives here, not on the block, for the same round-trip reason as the aspect ratios
   below — and one that is sharper still. A hand-authored style.border.radius of
   "var(--wp--custom--radius--xlg)" does NOT survive WordPress's own re-serialization: PHP's
   serialize_block_attributes() escapes every "--" in an attribute value, and the parser does not
   reverse it, so one editor save rewrites the attribute to "var(u002du002dwpu002du002d…)". The
   block then reports "unexpected or invalid content" on reopen, and "Attempt recovery" writes that
   mangled value into the inline style — silently dropping the corner radius. Harmless in a template
   (never round-tripped), fatal in a pattern that gets flattened into client post content, which is
   exactly what the case-study patterns do. Verified 2026-08-10 on post 72. Rule: no CSS custom
   property inside a block attribute value. */
.bpd-case-study-photo {
	position: relative;
	overflow: hidden;
	border-radius: var(--wp--custom--radius--xlg);
}

/* Card hover (issue #37): subtle image scale on hover, matching the old live site's card
   interaction — same mechanism as .bpd-photo-frame in photo-frame.css. Scoped to an <a> ancestor
   so it only fires for actual card links (wp:post-featured-image isLink:true, or a linked
   wp:image like our-work-feature-band.php's feature cards); the single-case-study content-cell
   images (case-study-content-cell-image.php, case-study-challenge-band.php) are all
   linkDestination:"none" and stay unaffected. This wrapper's own overflow:hidden above keeps the
   scaled image clipped to the rounded frame. */
.bpd-case-study-photo a:hover img {
	transform: scale(1.03);
}

@media (prefers-reduced-motion: no-preference) {
	.bpd-case-study-photo img {
		transition: transform var(--wp--custom--motion--duration-sm) var(--wp--custom--motion--ease);
	}
}

/* core/group does not declare "dimensions" support (only image/cover/video blocks do), so a
   hand-authored style.dimensions.aspectRatio never round-trips (WP's own re-serialization omits an
   unsupported style key, producing a saved-vs-computed markup mismatch → invalid block). Aspect
   ratios live here as plain CSS instead — layout-derived masonry proportions (819/500, 405/500),
   not design tokens, same treatment as this template's existing hardcoded flex-basis/min-width
   masonry column math. bpd-case-study-photo--32 uses the theme.json 3/2 aspect-ratio preset since
   that one does have a matching token. */
.bpd-case-study-photo--32 {
	aspect-ratio: var(--wp--preset--aspect-ratio--3-2);
}

.bpd-case-study-photo--wide {
	aspect-ratio: 819 / 500;
}

.bpd-case-study-photo--tall {
	aspect-ratio: 405 / 500;
}

/* Creative Showcase airport photo (single-case-study.html, node 5799:2160): Figma crops this one
   anchored to the bottom, unlike every other cell's default centered cover-crop. object-position
   has to live here rather than as an inline style on the image — core/image doesn't serialize
   arbitrary style attributes into its block JSON, so a hand-added inline style never round-trips
   (CLAUDE.md rule 5: it fails editor validation on reopen). */
.bpd-case-study-photo--bottom img {
	object-position: center bottom;
}

/* Selector includes .wp-block-image (not just "img") so this beats, on equal source order, core's
   own wp-includes/blocks/image/style.min.css ".wp-block-image img { height: auto; }" — both are
   two-class-equivalent specificity (0,2,1) vs (0,1,1), but real wp:image-block markup (as opposed
   to the raw <img> used by the non-block card renderers in inc/pattern-helpers.php) loads that core
   stylesheet too, and its rule was winning on source order alone, leaving the image at its natural
   aspect ratio instead of filling/cropping the box. Verified 2026-08-21 on
   patterns/our-work-feature-band.php's two feature cards (real wp:image blocks). */
.bpd-case-study-photo .wp-block-image img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* The img's height:100% above resolves against the figure, and the figure must in turn resolve
   against the group's aspect-ratio-derived height — otherwise (auto-height figure) the image falls
   back to its natural ratio and leaves a gap below it inside the box. This chain is what actually
   crops the 16:9 sources into the design's 1244/810, 612/628, 596/460 and 3/2 boxes. */
.bpd-case-study-photo > .wp-block-image {
	height: 100%;
	margin: 0;
}

/* linkDestination:"custom"/"attachment" wp:image blocks (our-work-feature-band.php's two feature
   cards) wrap the img in an <a>, and an anchor's UA-default display:inline-block shrink-wraps to
   its content instead of passing the figure's height down — breaking the percentage-height chain
   above, so the img fell back to its natural ratio (gap below the photo, corners reading as
   unrounded since the box's real height never got cropped into). display:block + height:100% here
   keeps the anchor transparent to that chain, same as the figure rule above it. Verified 2026-08-21
   on the two feature cards — this selector only matches wp:image blocks with a link (plain,
   non-linked case-study photos have no <a> here at all). */
.bpd-case-study-photo .wp-block-image a {
	display: block;
	height: 100%;
}

/* Decorative play-badge (real Figma vector: translucent circle + pause bars, flattened into one
   asset, assets/images/play-badge.svg) — bottom-right corner overlay, per OQ5's "static decorative
   image, not video/interactive" resolution. */
.bpd-play-badge {
	position: absolute;
	right: var(--wp--preset--spacing--400);
	bottom: var(--wp--preset--spacing--400);
	margin: 0;
	pointer-events: none;
}

.bpd-play-badge img {
	width: 100%;
	height: 100%;
	object-fit: contain;
}

/* Large play-badge variant (masonry grid's bigger cards, Figma's 44px "Large" VideoPlayer size). */
.bpd-play-badge-lg {
	width: 44px;
	height: 44px;
}

/* ROI stat bar — light strip under each case-study card's title/description. */
.bpd-roi-bar p {
	margin: 0;
}

/* Case-study card grid (Query Loop) — no per-card border, matches Figma's white/shadowless cards. */
.bpd-case-study-card {
	position: relative;
}

/* Masonry-style featured grid — 3 rows of alternating 66/33 columns (Figma's flex-wrap 819px/405px
   card widths reproduced as wp:columns width ratios, a real core-block layout, not CSS masonry —
   see PROGRESS.md for the measurement that confirmed this is a two-size flex-wrap, not true masonry). */
.bpd-case-study-masonry-row {
	align-items: flex-start;
}

/* core/group has no attribute-backed flex-basis/min-width style (that's a flex-CHILD sizing
   concern the block's own style supports don't cover), so hand-authoring them into a literal
   style="" attribute hit the same saved-vs-computed mismatch documented above for aspect-ratio.
   Modifier classes carry the two masonry item widths instead — layout-derived proportions, not
   design tokens, same as the aspect-ratio and column-width figures already hardcoded in this file. */
.bpd-masonry-item--wide {
	flex-basis: 66%;
	min-width: 405px;
}

.bpd-masonry-item--narrow {
	flex-basis: 32%;
	min-width: 280px;
}
