/**
 * PropOffice Property UIs - Version 1: three-image split showcase.
 *
 * Composition
 * -----------
 *   Desktop   large primary image on the left, two stacked secondary images on
 *             the right, property details overlaying the lower portion of the
 *             primary image.
 *   Tablet    the same split, with the secondary column narrowed and the
 *             showcase shortened so the overlay keeps breathing room.
 *   Mobile    a deliberately different composition: primary image, then the
 *             details as a solid card beneath it, then the secondary images
 *             side by side. Overlaying text on a small image is unreadable, so
 *             the mobile layout stops overlaying.
 *
 * Everything tunable reads a --ppui-* custom property. Elementor controls write
 * those properties onto the widget wrapper, so no rule here needs to know that
 * a control exists.
 *
 * Every selector is namespaced under .propoffice-pui-featured-listings; nothing
 * here can reach the agency theme or Elementor's own markup.
 */

.propoffice-pui-featured-listings--v1 {
	--ppui-v1-height: 520px;
	--ppui-v1-secondary-width: 30%;
	/*
	 * The shared width, with this composition's own starting point behind it.
	 *
	 * The appearance section writes --ppui-panel-width once for every version;
	 * the fallback is what this one opens at before anybody has. 40% here,
	 * because Version 1 lays a wide overlay across the photograph rather than a
	 * panel beside it - the fallback is the whole of how that number reaches the
	 * page, so it is not decoration.
	 */
	--ppui-v1-overlay-width: var(--ppui-panel-width, 40%);

	/*
	 * Cover and centred, because a property photograph cropped from its middle
	 * is almost always the shot the agency intended. "contain" would letterbox
	 * every image that does not match the cell, and a top or bottom anchor
	 * reliably decapitates buildings.
	 */
	--ppui-image-fit: cover;
	--ppui-image-position: center center;

	--ppui-cta-align: right;
	--ppui-cta-width: auto;
	--ppui-cta-display: inline-flex;
	--ppui-cta-bg-hover: var(--ppui-cta-bg);
	--ppui-cta-text-hover: var(--ppui-cta-text);
	--ppui-stat-icon-size: 28px;
	--ppui-mobile-card-bg: var(--ppui-overlay);

	display: grid;
	gap: calc(var(--ppui-gap) * 2);
}

/*
 * Theme defence.
 *
 * The component renders inside a theme we do not control, and page builders
 * routinely style headings, paragraphs, images and list items through selectors
 * like `.elementor-widget-container h3` or `img { margin-bottom }`. Those
 * outrank a single-class rule: they repaint our overlay text in the theme's
 * dark heading colour, and a stray image margin is exactly what puts a pale
 * band under the primary photograph.
 *
 * Both blocks below use :where(), which contributes no specificity at all. That
 * matters more than it looks. These rules therefore sit at two classes -
 * enough to beat the theme - while every component rule further down, at the
 * same two classes but declared later, still wins. An earlier version used
 * :is(), which added the element's specificity and quietly beat the very rules
 * the Elementor colour controls write to, so setting Price Colour did nothing.
 */
.propoffice-pui-featured-listings--v1 :where(img, figure, picture, ul, ol, li, p, h1, h2, h3, h4, h5, h6) {
	margin: 0;
	padding: 0;
}

.propoffice-pui-featured-listings--v1 :where(img) {
	border-radius: 0;
	box-shadow: none;
	vertical-align: middle;
}

/*
 * Square by default, but at zero added specificity. Themes round links and
 * buttons routinely, and the composition is architectural, so the default has
 * to be stated - yet stating it in a component rule would tie for specificity
 * with the per-element Border Radius control and win or lose on stylesheet
 * order. :where() puts this below every one of those controls by construction.
 */
.propoffice-pui-featured-listings--v1 :where(a, button) {
	border-radius: 0;
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__details-inner :where(h1, h2, h3, h4, h5, h6, p, span) {
	color: inherit;
	font-family: inherit;
}

/*
 * height, not min-height.
 *
 * min-height only ever grew the showcase, so asking for 390px when the previous
 * value was larger changed nothing. An explicit height makes the control
 * authoritative in both directions; the mobile composition sets it back to auto
 * where the panel leaves the image and the content decides.
 */
.propoffice-pui-featured-listings__showcase {
	display: grid;
	gap: var(--ppui-gap);
	grid-template-columns: 1fr var(--ppui-v1-secondary-width);
	height: var(--ppui-v1-height);
	position: relative;
}

/* ---------------------------------------------------------------- Images */

/*
 * The panels own the geometry and are told to fill their grid cell explicitly.
 * Left to stretch by default they would, but a theme rule that sets a height or
 * a display on a generic div is enough to collapse one, and a collapsed primary
 * panel is what leaves a band of background under the photograph.
 */
/*
 * No border-radius here, and none on the panels below.
 *
 * A single global Corner Radius token used to round every image at once, which
 * meant a radius wanted on the button also landed on the photography. Radius
 * and border are now per-element controls that write straight to the element
 * they name, so this file states the composition and the panel keeps whatever
 * the designer asked for - including nothing.
 */
/*
 * Every cell is placed explicitly, and that is not tidiness.
 *
 * The information panel shares row 1, column 1 with the photograph. Auto
 * placement fills the first free cell, so the moment the panel claims 1/1 an
 * unplaced photograph is pushed into column 2 and the secondary column drops to
 * a second row - the composition inverts, with a 360px "primary" beside an
 * 824px pair of thumbnails. Naming all three costs three declarations and
 * removes the ambiguity entirely.
 */
.propoffice-pui-featured-listings__primary {
	grid-column: 1;
	grid-row: 1;
	height: 100%;
	min-height: 0;
	overflow: hidden;
	position: relative;
}

.propoffice-pui-featured-listings__secondary {
	display: grid;
	gap: var(--ppui-gap);
	grid-column: 2;
	grid-row: 1;
	grid-template-rows: 1fr 1fr;
	height: 100%;
	min-height: 0;
}

.propoffice-pui-featured-listings__secondary-panel {
	height: 100%;
	min-height: 0;
	overflow: hidden;
	position: relative;
}

/*
 * The images fill their panel rather than dictating its size, which is what
 * keeps the two secondary panels exactly equal regardless of the aspect ratios
 * an agency uploads. object-fit does the cropping; the panel owns the geometry.
 *
 * The component root on the front of every selector is load-bearing. Elementor
 * ships `.elementor img { height: auto }` and the theme ships `img { height:
 * auto }` - one class plus an element, which outranks a lone class. This rule
 * said `height: 100%` and lost, so every image fell back to its intrinsic
 * aspect ratio: a 209x267 cell held a 209x140 image, and two secondary images
 * were equal only for as long as their source files happened to share a shape.
 * Two classes wins, and with it the panel decides the geometry again.
 */
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__primary-image,
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__secondary-image,
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__primary .propoffice-property__placeholder,
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__secondary-panel .propoffice-property__placeholder {
	display: block;
	height: 100%;
	inset: 0;
	max-width: none;
	object-fit: var(--ppui-image-fit);
	object-position: var(--ppui-image-position);
	position: absolute;
	width: 100%;
}

.propoffice-pui-featured-listings__primary::after {
	background: linear-gradient(to top, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 55%);
	content: "";
	inset: 0;
	pointer-events: none;
	position: absolute;
}

/* ----------------------------------------------------------------- Badge */

/*
 * Styled here rather than relying on the shared base rule alone. The badge sits
 * over photography in a theme we do not control, so its size, padding and
 * colour are stated explicitly and cannot collapse to a bare dot if a theme
 * resets paragraph styling.
 */
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__badge {
	background: var(--ppui-badge-bg);
	border-radius: 0;
	color: var(--ppui-badge-text);
	display: inline-block;
	font-size: 0.8125rem;
	font-weight: 600;
	left: 0;
	letter-spacing: 0.08em;
	line-height: 1.2;
	margin: 0;
	padding: 0.85em 1.6em;
	position: absolute;
	text-transform: uppercase;
	top: 0;
	white-space: nowrap;
	z-index: 3;
}

/* --------------------------------------------------------------- Details */

/*
 * Anchored flush to the bottom-left corner rather than floated as a card. The
 * photograph is the subject of this presentation; the panel is a caption on it,
 * not a box over it. No blur: the reference keeps the image legible through the
 * overlay, which is what makes it read as architectural rather than as a modal.
 *
 * It is a grid item sharing the photograph's cell, not a child of it. Placing
 * both in row 1, column 1 overlays the panel without nesting it, and that is
 * what makes the mobile composition possible at all: a nested panel put into
 * normal flow is still inside the image's box, and clipped by its overflow.
 * The order property did nothing there either, its parent being a plain block.
 * As a sibling it only has to be handed a row of its own.
 *
 * width, not max-width. An absolutely positioned box with only a max-width is
 * shrink-to-fit: the value is a ceiling the content may never reach, so raising
 * the control from 34% to 50% once changed nothing visible. The width still
 * measures against the primary column, because that is the column it occupies,
 * so Overlay Width keeps meaning "this much of the photograph".
 */
.propoffice-pui-featured-listings__details {
	align-self: end;
	grid-column: 1;
	grid-row: 1;
	justify-self: start;
	padding: 0;
	width: var(--ppui-v1-overlay-width);
	z-index: 2;
}

/*
 * The shared appearance, with this composition's own starting points behind it.
 *
 * Padding, radius, the border and the colour of the words are decisions about
 * Featured Properties rather than about the split showcase, so the appearance
 * section owns them and this reads what it wrote. The fallbacks are what this
 * layout opens at before anybody has set anything.
 */
.propoffice-pui-featured-listings__details-inner {
	background: color-mix(in srgb, var(--ppui-overlay) calc(var(--ppui-overlay-opacity) * 100%), transparent);
	border: var(--ppui-panel-border-width) var(--ppui-panel-border-style) var(--ppui-panel-border-color);
	border-radius: var(--ppui-panel-radius, 0);
	color: var(--ppui-panel-text);
	display: grid;
	gap: 0.5rem;
	padding: var(--ppui-panel-pad, 2.25rem 1.5rem 0);
}

/*
 * color-mix is well supported but not universal. Browsers without it ignore the
 * declaration above and fall back to this opaque overlay, which keeps the text
 * readable rather than leaving it on bare photography.
 */
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
	.propoffice-pui-featured-listings__details-inner {
		background: var(--ppui-overlay);
	}
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__title {
	color: var(--ppui-title-color);
	font-size: var(--ppui-title-size);
	font-weight: 600;
	letter-spacing: 0.08em;
	margin: 0;
	text-transform: uppercase;
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__price {
	color: var(--ppui-price-color);
	font-size: var(--ppui-price-size);
	font-weight: 800;
	letter-spacing: -0.01em;
	line-height: 1.05;
	margin: 0;
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__location {
	color: var(--ppui-location-color);
	font-size: var(--ppui-location-size);
	font-weight: 700;
	letter-spacing: 0.06em;
	line-height: 1.35;
	margin: 0;
	text-transform: uppercase;
}

/* ------------------------------------------------------------ Statistics */

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__stats {
	align-items: flex-end;
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem 1.5rem;
	list-style: none;
	margin: 0.5rem 0 0;
	padding: 0;
}

/*
 * Icon above value, as in the reference. The written label stays in the markup
 * and is hidden visually rather than dropped: "4" beside a pictogram means
 * nothing to a screen reader, so the word bedrooms has to survive somewhere.
 */
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__stat {
	align-items: center;
	color: var(--ppui-stat-value);
	display: flex;
	flex-direction: column;
	font-size: var(--ppui-stat-size);
	gap: 0.3rem;
	line-height: 1.1;
	margin: 0;
	padding: 0;
}

/*
 * Sized in its own unit rather than in ems, so the Icon Size control and the
 * statistics typography stay independent. Tying the glyph to the font size made
 * the two controls fight: enlarging the number enlarged the pictogram with it.
 */
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__stat-icon {
	color: var(--ppui-stat-icon);
	flex: none;
	height: var(--ppui-stat-icon-size);
	width: var(--ppui-stat-icon-size);
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__stat i {
	color: var(--ppui-stat-icon);
	font-size: var(--ppui-stat-icon-size);
	line-height: 1;
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__stat-value {
	font-weight: 600;
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__stat-label {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	overflow: hidden;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

/* ------------------------------------------------------------------- CTA */

/*
 * Alignment and width are two independent decisions, and the design used to
 * make both for you: the button was pinned bottom-right at its natural size, so
 * "centred" and "full width" were simply unreachable.
 *
 * justify-self does the aligning, which is what works inside the grid the
 * overlay already is - text-align would only move the words within the button.
 * The width token defaults to auto, so a button nobody has configured still
 * hugs its text exactly as before.
 */
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta {
	align-items: center;
	align-self: end;
	background: var(--ppui-cta-bg);
	color: var(--ppui-cta-text);
	display: var(--ppui-cta-display);
	font-size: 0.8125rem;
	font-weight: 600;
	justify-content: center;
	justify-self: var(--ppui-cta-align);
	letter-spacing: 0.08em;
	line-height: 1;
	margin: 1.5rem 0 0;
	min-height: 44px;
	padding: 1.05rem 1.75rem;
	text-align: center;
	text-decoration: none;
	text-transform: uppercase;
	transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out;
	width: var(--ppui-cta-width);
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta:hover,
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta:focus-visible {
	background: var(--ppui-cta-bg-hover);
	color: var(--ppui-cta-text-hover);
}

/*
 * The button as a button, when the whole card is the link. It carries no href,
 * so it must not offer a pointer or a focus ring that leads nowhere - the card
 * link underneath is the real target.
 */
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta--static {
	cursor: inherit;
	pointer-events: none;
}

/*
 * Every link state carries the colour explicitly. A theme styling a:hover or
 * a:visited would otherwise repaint the button text on interaction, so the
 * control would appear to work until the pointer touched it.
 */
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta:link,
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta:visited,
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta:hover,
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta:focus,
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta:active {
	color: var(--ppui-cta-text);
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta:hover,
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta:focus-visible {
	filter: brightness(1.12);
	text-decoration: none;
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__cta:focus-visible {
	outline: 3px solid var(--ppui-cta-text);
	outline-offset: -6px;
}

/*
 * The call to action is the only link in the showcase. Stretching it across the
 * details overlay - its nearest positioned ancestor - makes that whole panel
 * clickable without adding a second link, so the card keeps one tab stop and
 * never nests a link inside a link.
 */
.propoffice-pui-featured-listings__cta::after {
	content: "";
	inset: 0;
	position: absolute;
	z-index: 3;
}

.propoffice-pui-featured-listings__sr-only {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	overflow: hidden;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

/* ------------------------------------------------------------- Card link */

/*
 * One link covering the whole showcase, sitting above the photographs and below
 * the information panel so the text stays selectable.
 *
 * It is a real anchor rather than a click handler on the article: that is what
 * gives it a tab stop, a context menu, middle-click to open in a new tab, and an
 * accessible name - none of which a JavaScript click can reproduce.
 */
.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__card-link {
	inset: 0;
	position: absolute;
	z-index: 4;
}

.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__card-link:focus-visible {
	outline: 3px solid var(--ppui-cta-bg);
	outline-offset: -3px;
}

/*
 * The link sits above the information panel, so a click anywhere on the card -
 * including on the price or the address - follows it. That costs text
 * selection inside the card, which is the accepted trade for this pattern and
 * the reason it is a switch rather than the default.
 */
.propoffice-pui-featured-listings--card-link .propoffice-pui-featured-listings__showcase {
	cursor: pointer;
}

/* ------------------------------------------------------------ Responsive */

@media (max-width: 1024px) {
	.propoffice-pui-featured-listings--v1 {
		--ppui-v1-height: 440px;
		--ppui-v1-secondary-width: 28%;
		--ppui-v1-overlay-width: 52%;
		--ppui-pad: 18px;
	}
}

/*
 * Mobile is a different composition rather than a squeezed desktop one. The
 * details leave the image and become a solid card, because overlaid text on a
 * phone-width photograph is where this design would otherwise fail hardest.
 */
@media (max-width: 767px) {
	/*
	 * The mobile composition takes the panel off the image, so the content
	 * decides the height and the showcase control stops applying. Overriding
	 * the token here rather than the property keeps a responsive height value
	 * usable if a site sets one for mobile.
	 */
	.propoffice-pui-featured-listings--v1 {
		--ppui-v1-height: auto;
		--ppui-v1-overlay-width: 100%;
		--ppui-pad: 16px;
	}

	/*
	 * height, set on the element rather than through the token.
	 *
	 * Overriding --ppui-v1-height here does not work and cannot be made to:
	 * Elementor writes that token from the Showcase Height control at wrapper
	 * specificity, with no media query, so its desktop value applies at every
	 * width and outranks anything this stylesheet declares. The showcase stayed
	 * locked at its desktop height on a phone, which left the information card
	 * crushed into the photograph instead of sitting below it.
	 *
	 * Setting the property directly sidesteps the token entirely. A site that
	 * wants a fixed height on mobile has the overlay composition below, which
	 * puts it back.
	 */
	.propoffice-pui-featured-listings--v1 .propoffice-pui-featured-listings__showcase {
		grid-template-columns: 1fr;
		grid-template-rows: auto;
		height: auto;
		min-height: 0;
	}

	/*
	 * Placement released, so all three stack in source order: photograph,
	 * information, thumbnails.
	 */
	.propoffice-pui-featured-listings__primary {
		aspect-ratio: 4 / 3;
		grid-column: auto;
		grid-row: auto;
	}

	.propoffice-pui-featured-listings__primary::after {
		display: none;
	}

	/*
	 * Its own row, which is all the below-image composition needs now that the
	 * panel is a sibling rather than a child. auto placement puts it after the
	 * photograph and before the secondary images.
	 */
	.propoffice-pui-featured-listings__details {
		grid-column: auto;
		grid-row: auto;
		justify-self: stretch;
		padding: 0;
		width: auto;
	}

	.propoffice-pui-featured-listings__details-inner {
		background: var(--ppui-mobile-card-bg);
		padding: 1.25rem;
	}

	.propoffice-pui-featured-listings__secondary {
		grid-column: auto;
		grid-row: auto;
		grid-template-columns: 1fr 1fr;
		grid-template-rows: none;
	}

	.propoffice-pui-featured-listings__secondary-panel {
		aspect-ratio: 4 / 3;
	}

	/*
	 * The stretched pseudo-element is only for the non-clickable card, and on
	 * mobile the details sit outside the primary panel, so there is nothing
	 * sensible for it to cover. The real card link, when enabled, is an actual
	 * anchor over the showcase and is unaffected by this.
	 */
	.propoffice-pui-featured-listings__cta::after {
		display: none;
	}

	/*
	 * The other mobile composition: the panel stays on the photograph exactly as
	 * it does on a desktop. Everything above is undone rather than duplicated,
	 * so the two options cannot drift apart.
	 */
	.propoffice-pui-featured-listings--mobile-overlay .propoffice-pui-featured-listings__showcase {
		grid-template-columns: 1fr var(--ppui-v1-secondary-width);
		grid-template-rows: 1fr;
		height: var(--ppui-v1-height);
	}

	.propoffice-pui-featured-listings--mobile-overlay {
		--ppui-v1-overlay-width: 78%;
	}

	.propoffice-pui-featured-listings--mobile-overlay .propoffice-pui-featured-listings__primary {
		aspect-ratio: auto;
	}

	.propoffice-pui-featured-listings--mobile-overlay .propoffice-pui-featured-listings__primary::after {
		display: block;
	}

	.propoffice-pui-featured-listings--mobile-overlay .propoffice-pui-featured-listings__details {
		grid-column: 1;
		grid-row: 1;
		justify-self: start;
		width: var(--ppui-v1-overlay-width);
	}

	.propoffice-pui-featured-listings--mobile-overlay .propoffice-pui-featured-listings__details-inner {
		background: color-mix(in srgb, var(--ppui-overlay) calc(var(--ppui-overlay-opacity) * 100%), transparent);
	}

	.propoffice-pui-featured-listings--mobile-overlay .propoffice-pui-featured-listings__secondary {
		grid-template-columns: none;
		grid-template-rows: 1fr 1fr;
		order: 0;
	}

	.propoffice-pui-featured-listings--mobile-overlay .propoffice-pui-featured-listings__secondary-panel {
		aspect-ratio: auto;
	}
}

@media (prefers-reduced-motion: reduce) {
	.propoffice-pui-featured-listings__cta {
		transition: none;
	}

	.propoffice-pui-featured-listings__cta:hover,
	.propoffice-pui-featured-listings__cta:focus-visible {
		transform: none;
	}
}
