/**
 * PropOffice Property Gallery — Design #1.
 *
 * Measured from the reference rather than guessed:
 *   featured cell         ~65.5% of the gallery width
 *   supporting column     ~34.5%, two equal cells
 *   column gap            ~16px, row gap ~16px
 *   badge                 inset ~20px from the top and left of the image
 *   Gallery CTA           inset ~20px from the bottom and left
 *   controls              inset ~12px from the bottom and right
 *
 * ## Not one brand value appears below
 *
 * Every colour is a design token the WEBSITE supplies (Elementor globals, or
 * the design-system filter), and the type inherits the site's own face. That is
 * the contract: changing the brand in Elementor changes this gallery without
 * this file being touched. The design-system tokens below name semantic ROLES;
 * their values live in the design-system boundary, never here.
 */

.po-gallery {
	/* Structure the design owns. */
	--po-gallery-gap: 16px;
	--po-gallery-featured: 65.5%;
	--po-gallery-inset: 20px;
	--po-gallery-radius: 0;

	/* Roles the website fills. */
	--po-gallery-ink: var(--po-ds-color-text);
	--po-gallery-primary: var(--po-ds-color-primary);
	--po-gallery-on-primary: var(--po-ds-color-surface);
	--po-gallery-accent: var(--po-ds-color-accent);
	--po-gallery-on-accent: var(--po-ds-color-surface);
	--po-gallery-well: var(--po-ds-color-background);
	--po-gallery-surface: var(--po-ds-color-surface);
	--po-gallery-scrim: rgb(0 0 0 / 62%);
	--po-gallery-on-scrim: var(--po-ds-color-surface);

	box-sizing: border-box;
	display: block;
	width: 100%;
	max-width: 100%;
	font-family: var(--po-ds-font-family);
	color: var(--po-gallery-ink);
	container-type: inline-size;
}

.po-gallery *,
.po-gallery *::before,
.po-gallery *::after {
	box-sizing: border-box;
}

.po-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ------------------------------------------------------------------ stage */

.po-gallery__stage {
	display: grid;
	grid-template-columns: var(--po-gallery-featured) 1fr;
	gap: var(--po-gallery-gap);
	margin-block-start: var(--po-gallery-gap);
}

/*
 * A listing with a single photograph has no supporting column, so the featured
 * cell takes the full width and carries the controls itself.
 */
.po-gallery__stage:not(:has(.po-gallery__supporting)) {
	grid-template-columns: minmax(0, 1fr);
}

.po-gallery__featured,
.po-gallery__cell {
	position: relative;
	overflow: hidden;
	background: var(--po-gallery-well);
	border-radius: var(--po-gallery-radius);
}

/*
 * The featured cell sets the height and the right column follows it, which is
 * what keeps the two supporting cells exactly half of it. An aspect ratio
 * rather than a fixed height, so the composition holds at every width.
 */
.po-gallery__featured {
	aspect-ratio: 1100 / 636;
}

.po-gallery__supporting {
	position: relative;
	display: grid;
	grid-template-rows: 1fr 1fr;
	gap: var(--po-gallery-gap);
	min-height: 0;
}

/*
 * Taken OUT of flow, and that is the whole reason the composition holds.
 *
 * A photograph left in flow contributes its own intrinsic height to the track
 * it sits in. The two supporting cells are `1fr 1fr` in a row the grid sizes
 * automatically, so those intrinsic heights - not the featured cell's aspect
 * ratio - decided how tall the row was, and the right column ended up TALLER
 * than the photograph it was supposed to follow. With 3:2 photographs that
 * left the featured cell about a fifth of its own height short of the bottom
 * of the column beside it, at every width.
 *
 * Absolute means each cell asks its content for nothing. The row is then sized
 * by the only thing left that has a definite height - `.po-gallery__featured`
 * and its aspect ratio - and `1fr 1fr` splits exactly that, which is what makes
 * the two supporting cells half of the featured cell rather than half of
 * whatever the photographs happened to be.
 *
 * The cells carry `position: relative` already, so this anchors to the cell.
 */
.po-gallery__image {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/*
 * The whole cell opens the viewer. A transparent button rather than a wrapping
 * anchor: this is an action, not a destination, and a button is what a screen
 * reader and a keyboard both expect.
 *
 * 🚨 SCOPED UNDER `.po-gallery` TO SURVIVE THE HOST THEME, NOT FOR TIDINESS.
 *
 * This button is `inset: 0` over the photograph and painted after it, so
 * whatever colour it carries is what the visitor sees INSTEAD of the image.
 * A single class is not enough to keep it transparent: Elementor's kit emits
 * `.elementor-kit-N button { background: var(--e-global-color-accent) }`,
 * which is one class PLUS an element - (0,1,1) - and beats a lone
 * `.po-gallery__opener` at (0,1,0). Measured on a real site: the entire
 * 1312x759 hero cell was painted the site's accent blue, with the photograph
 * loaded and intact underneath it.
 *
 * Two classes - (0,2,0) - outrank any `class + element` host rule, which is
 * the shape themes and page builders actually ship. Every button background
 * below is scoped for the same reason; the values are unchanged.
 *
 * The grid does not need this because its image is a DESCENDANT of its opener
 * rather than a sibling beneath it, so the same host rule paints a frame round
 * the photograph instead of over it.
 */
/**
 * The invisible click target over each photograph.
 *
 * 🚨 `background: none` was not enough, and the reason generalises: specificity
 * only protects properties this file DECLARES. The earlier hardening won the
 * background contest at two classes, but the same `.elementor-kit-N button` rule
 * also sets `box-shadow`, `opacity` and `border-radius` — and for a property no
 * PropOffice rule mentions there is no contest to win.
 *
 * Measured on the acceptance rig: a 14px blue glow and a 12px rounded corner
 * drawn ON TOP of the hero photograph, by an element whose whole purpose is to
 * be invisible. Same defect class as the original, one layer along.
 */
.po-gallery .po-gallery__opener {
	position: absolute;
	inset: 0;
	padding: 0;
	min-width: auto;
	max-width: none;
	cursor: pointer;
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	opacity: 1;
	font: inherit;
	outline-offset: 0;
}

/**
 * The focus ring carries THREE classes, and the third one is load-bearing.
 *
 * The control rules below declare `outline-offset: 0` — they have to, it is one
 * of the properties a host button rule sets — and they sit LATER in this file.
 * At equal specificity source order decides, so a two-class focus rule would
 * have been flattened to `0` by the very reset that protects it, and the inset
 * ring the design draws over a photograph would have moved outside the button.
 *
 * `.po-gallery .po-gallery__cta:focus-visible` is (0,3,0) and outranks both the
 * reset and any host `button:focus` rule.
 */
.po-gallery .po-gallery__opener:focus-visible,
.po-gallery .po-gallery__cta:focus-visible,
.po-gallery .po-gallery__control--button:focus-visible {
	outline: 3px solid var(--po-gallery-accent);
	outline-offset: -3px;
}

/* ----------------------------------------------------------------- states */

.po-gallery__badge {
	position: absolute;
	top: var(--po-gallery-inset);
	left: var(--po-gallery-inset);
	z-index: 2;
	padding: 14px 26px;
	font-size: 17px;
	font-weight: var(--po-ds-font-heading);
	line-height: 1;
	color: var(--po-gallery-on-primary);
	pointer-events: none;
	background: var(--po-gallery-primary);
}

.po-gallery__actions {
	position: absolute;
	bottom: var(--po-gallery-inset);
	left: var(--po-gallery-inset);
	z-index: 2;
	display: flex;
	gap: 8px;
}

/**
 * 🚨 SCOPED, AND EXHAUSTIVELY DECLARED — MEASURED, not reasoned about.
 *
 * This rule used to be a lone `.po-gallery__cta` at (0,1,0). Every structural
 * value it needs was already here — `border: 0`, the radius, the padding, the
 * type — and a host still repainted all of them, because a single class loses
 * to the shape themes actually ship. On the acceptance rig, twentytwentyfive's
 * own scope is enough:
 *
 *     .entry-content button, .wp-site-blocks button { … }
 *
 * — one class plus an element, and no `!important` anywhere. The "Gallery" call
 * to action over the hero photograph took a 6px dashed border, a 40px radius, a
 * red glow, 30px of padding and 35% opacity from it.
 *
 * Two fixes, and BOTH are needed:
 *
 * 1. Two classes — (0,2,0) — so the values this file already declares win.
 * 2. The properties it never declared. Specificity only protects a property
 *    this stylesheet MENTIONS; `box-shadow` and `opacity` had no contest to
 *    win, so the host took them uncontested however the rule was scoped. Same
 *    defect class as the viewer's chrome, `.po-gallery__opener` and the grid's
 *    tiles — fourth instance, one component along.
 *
 * The neutral values are chosen so declaring them changes nothing the design
 * decided: `min-width: auto` and `max-width: none` are the initial values, so
 * pinning them cannot squash a flex item that was sizing to its own label.
 */
.po-gallery .po-gallery__cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 52px;
	min-width: auto;
	max-width: none;
	padding: 0 30px;
	font-family: inherit;
	font-size: 17px;
	font-weight: var(--po-ds-font-button);
	line-height: 1;
	letter-spacing: normal;
	text-transform: none;
	cursor: pointer;
	border: 0;
	border-radius: var(--po-gallery-radius);
	box-shadow: none;
	opacity: 1;
	outline-offset: 0;
}

.po-gallery .po-gallery__cta--gallery {
	color: var(--po-gallery-on-accent);
	background: var(--po-gallery-accent);
}

/* The reference's secondary treatment: a light chip beside the accent one. */
.po-gallery .po-gallery__cta--video {
	color: var(--po-gallery-accent);
	background: var(--po-gallery-surface);
}

/*
 * 🚨 A HOST'S `button:hover` OUTRANKS EVERY DEFENCE ABOVE.
 *
 * The hardening above wins the RESTING contest at two classes — (0,2,0) beats
 * `.elementor-kit-N button` at (0,1,1). It says nothing about the hovered
 * state, and `.elementor-kit-N button:hover` is (0,2,1): a class, a
 * pseudo-class and an element. That outranks (0,2,0), so on hover the host
 * paints the button again and the earlier fix simply does not apply.
 *
 * MEASURED on the live Kava install, on the PUBLIC frontend, signed in as
 * nobody:
 *
 *     .elementor-kit-10 button:hover { background-color: var(--e-global-color-primary) }
 *     --e-global-color-primary: #1A1816
 *
 * `.po-gallery__opener` is `position: absolute; inset: 0` — measured 568x320
 * over a 568x320 photograph — so hovering a picture painted a near-black
 * rectangle over the whole of it. Sixty-six buttons in one gallery match that
 * rule. It reached BOTH layouts, because the opener is shared, and in Type 2 it
 * followed the pointer across the coverflow, which is why it read as the
 * neighbouring photographs darkening too.
 *
 * 🚨 THIS IS NOT THE COVERFLOW SHADING. `.po-gallery__shade` is a separate,
 * intentional, position-driven mechanism that is present at rest, specified in
 * docs/designs/PROPERTY-GALLERY-TYPE-2.md and measured off the reference. It is
 * untouched here.
 *
 * The fix is the same architectural move as the resting hardening, one state
 * along: scope under the component root WITH the state, which is (0,3,0) and
 * outranks the host. Each button restates the treatment it already has, so
 * nothing about the design changes — a hover that PropOffice never designed
 * simply stops happening. No `!important`, no host selector, no z-index.
 *
 * `:focus` and `:active` are covered in the same breath because a kit that
 * styles one interaction state almost always styles all three, and finding this
 * again through a keyboard user's focus ring would be the same day repeated.
 */
.po-gallery .po-gallery__opener:hover,
.po-gallery .po-gallery__opener:focus,
.po-gallery .po-gallery__opener:active {
	background: none;
	box-shadow: none;
	opacity: 1;
	border-radius: 0;
}

.po-gallery .po-gallery__cta--gallery:hover,
.po-gallery .po-gallery__cta--gallery:focus,
.po-gallery .po-gallery__cta--gallery:active {
	color: var(--po-gallery-on-accent);
	background: var(--po-gallery-accent);
	box-shadow: none;
	opacity: 1;
}

.po-gallery .po-gallery__cta--video:hover,
.po-gallery .po-gallery__cta--video:focus,
.po-gallery .po-gallery__cta--video:active {
	color: var(--po-gallery-accent);
	background: var(--po-gallery-surface);
	box-shadow: none;
	opacity: 1;
}

.po-gallery .po-gallery__control:hover,
.po-gallery .po-gallery__control:focus,
.po-gallery .po-gallery__control:active {
	color: var(--po-gallery-on-scrim);
	background: var(--po-gallery-scrim);
	box-shadow: none;
	opacity: 1;
}

/* --------------------------------------------------------------- controls */

.po-gallery__controls {
	position: absolute;
	right: 12px;
	bottom: 12px;
	z-index: 2;
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	justify-content: flex-end;
}

/**
 * The count / Fullscreen / Grid strip, hardened for the same reason.
 *
 * This rule was already scoped to two classes, so the values below held — but
 * `box-shadow` and `opacity` were not among them, and on the rig the whole
 * strip picked up the host's red glow and faded to 35% over the photograph.
 * Scoping is half the remedy; DECLARING is the other half.
 *
 * `.po-gallery__count` is a span rather than a button and no host `button` rule
 * reaches it, but it shares the strip's treatment and costs nothing to cover.
 */
.po-gallery .po-gallery__control {
	display: inline-flex;
	gap: 6px;
	align-items: center;
	min-height: 30px;
	min-width: auto;
	max-width: none;
	padding: 0 11px;
	font-family: inherit;
	font-size: 14px;
	font-weight: var(--po-ds-font-label);
	line-height: 1;
	color: var(--po-gallery-on-scrim);
	background: var(--po-gallery-scrim);
	border: 0;
	border-radius: 3px;
	box-shadow: none;
	opacity: 1;
	outline-offset: 0;
}

/*
 * Tracking and casing are pinned on the BUTTONS only, never on the shared
 * strip rule above.
 *
 * `.po-gallery__count` is a `<span>`; no host `button` rule can reach it, and
 * it inherits the site's own tracking — twentytwentyfive gives it -0.1px.
 * Declaring `letter-spacing: normal` on the shared rule was measured on the rig
 * to CHANGE that span from -0.1px to normal: hardening that quietly restyles an
 * element which was never at risk is a regression wearing a fix's clothes.
 *
 * The two buttons compute `normal` already, so this costs nothing today and
 * stops an Elementor kit's `text-transform: uppercase` from shouting FULLSCREEN
 * tomorrow.
 */
.po-gallery .po-gallery__control--button {
	cursor: pointer;
	letter-spacing: normal;
	text-transform: none;
}

.po-gallery__count-value {
	font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------- responsive */

/*
 * Breakpoints, and why they are where they are.
 *
 * 900px — the supporting column can no longer hold a legible photograph beside
 * a 65% featured cell, so the composition becomes one column: the featured
 * image, then the two supporting cells side by side beneath it. The reference's
 * relationship is preserved rather than squeezed.
 *
 * 620px — the badge and the calls to action pull in to a 12px inset, because
 * a 20px one takes a visible share of a photograph this narrow.
 *
 * 420px — the CTAs and the badge take their compact sizing so a 320px screen
 * still shows the whole of both buttons.
 */
@container (max-width: 900px) {
	.po-gallery__stage {
		grid-template-columns: minmax(0, 1fr);
	}

	.po-gallery__supporting {
		grid-template-rows: none;
		grid-template-columns: 1fr 1fr;
	}

	.po-gallery__featured {
		aspect-ratio: 16 / 10;
	}

	.po-gallery__cell {
		aspect-ratio: 4 / 3;
	}
}

/*
 * These rules set properties on DESCENDANTS, never on `.po-gallery` itself.
 *
 * A container query styles what is inside the container; an element cannot
 * respond to its own. Declaring `--po-gallery-inset` on `.po-gallery` in here
 * would silently do nothing — so the values are applied where they are read.
 */
@container (max-width: 620px) {
	.po-gallery__badge {
		top: 12px;
		left: 12px;
	}

	.po-gallery__actions {
		bottom: 12px;
		left: 12px;
	}
}

/*
 * 🚨 RAISING A BASE RULE'S SPECIFICITY SILENTLY KILLS EVERY OVERRIDE OF IT.
 *
 * A container query buys no specificity whatsoever, and source order only
 * decides a TIE. So each rule in here has to be scoped to match the rule it
 * overrides — no more and, decisively, NO LESS.
 *
 * `.po-gallery__cta` is scoped because THIS change scoped its base rule to
 * `.po-gallery .po-gallery__cta` (0,2,0). Left at one class it would have lost
 * to its own base, and the compact sizing the breakpoint note above promises —
 * "the CTAs and the badge take their compact sizing" — would have died as a
 * side effect of hardening. Scoping both halves keeps 15px reaching the screen.
 *
 * `.po-gallery__badge` needs nothing: its base rule is still one class.
 *
 * `.po-gallery__control` is deliberately NOT scoped, and it is INERT because of
 * that. Its base rule has been `.po-gallery .po-gallery__control` at (0,2,0)
 * since `dd2921d` — a commit whose message states "No colour, geometry, DOM or
 * JavaScript changed; the values are exactly what they were" — so this 13px has
 * reached nothing since, and the strip renders 14px at every width. Scoping it
 * here WOULD revive it: measured on the rig by swapping only this stylesheet at
 * a 298px gallery, 14px before and 13px after.
 *
 * That revival is a RENDERING CHANGE, and nothing authorises it. No reference,
 * no design contract, no test and no documented behaviour asks for 13px — the
 * breakpoint note above names the CTAs and the badge, not the control strip.
 * Host protection does not need it either: the base rule declares `font-size`
 * at (0,2,0) and already outranks any `class + element` host rule at every
 * width. So the rule stays exactly as it shipped, and reviving it stays a
 * design decision for someone to take on purpose rather than a side effect of
 * hardening — which is precisely how it came to be inert in the first place.
 *
 * `PropertyGalleryControlHardeningTest` pins all three reaches, in both
 * directions.
 */
@container (max-width: 420px) {
	.po-gallery .po-gallery__cta {
		min-height: 42px;
		padding: 0 18px;
		font-size: 15px;
	}

	.po-gallery__badge {
		padding: 9px 16px;
		font-size: 14px;
	}

	.po-gallery__control {
		font-size: 13px;
	}
}

/* Containers only answer when one is established; a viewport fallback covers
   the gallery being placed somewhere that suppresses containment. */
@media (max-width: 900px) {
	.po-gallery__stage {
		grid-template-columns: minmax(0, 1fr);
	}

	.po-gallery__supporting {
		grid-template-rows: none;
		grid-template-columns: 1fr 1fr;
	}
}
