/* ==========================================================================
   Palm Estate - properties
   --------------------------------------------------------------------------
   Enqueued on the listings archive and single property pages only (see
   functions.php). The page band, form fields, buttons and dividers these
   pages are built from live in components.css.

   01 Listings band and finder
   02 Results
   03 Property card
   04 Pagination
   05 Single property
   ========================================================================== */


/* 01 Listings band and finder ============================================= */

/* The page band (components.css) with more room: title bottom-left, a lead
   and a line of facts bottom-right, and the finder beneath them. */
/*
 * The band's ground is the footer's: the paper texture under a Cream shade
 * multiplied over it, here on Forest rather than Deep, so the two dark ends
 * of the site share one surface. Title bottom-left, a lead and a line of
 * facts bottom-right, and the finder beneath them on the same ground.
 */
.listings-band {
	position: relative;
	z-index: 2; /* over the results, which tuck up under its arc */
	display: grid;
	align-content: end;
	gap: var(--space-xl);
	min-height: clamp(24rem, 52svh, 36rem);
	padding-bottom: calc(var(--space-2xl) + var(--band-arc-h));
}

.listings-band__inner {
	position: relative;
	z-index: 1;
	display: grid;
	gap: var(--space-lg);
}

@media (min-width: 1024px) {
	.listings-band__inner {
		grid-template-columns: 1.2fr 1fr;
		align-items: end;
		gap: var(--space-2xl);
	}

	.listings-band__aside {
		justify-self: end;
		text-align: right;
	}

	.listings-band .page-band__lead {
		margin-left: auto;
	}
}

.listings-band .page-band__title {
	font-size: var(--fs-display, var(--fs-3xl));
}

.listings-band__facts {
	margin-top: var(--space-md);
	color: var(--pe-accent);
}

.listings-band__dot {
	margin-inline: var(--space-2xs);
}

/*
 * The finder: one bar with a hairline Bronze frame on the band's ground.
 * Sale / rent is a segmented control at the left; the fields follow, divided by hairlines;
 * Clear at the right end. Its parts keep the shared field and choice
 * classes for listings.js and for their focus and checked states; this only
 * reshapes them.
 */
.finder__wrap {
	position: relative;
	z-index: 1;
}

.finder {
	display: grid;
	color: var(--pe-text-on-dark);
	background-color: var(--pe-bg-dark);
	border: var(--hairline) solid var(--pe-accent);
}

.finder__for .choices {
	--choices-cols: 3;
	--choices-cols-wide: 3;

	gap: 0;
	margin-top: 0;
}

.finder__for .choice {
	min-height: 3.5rem;
	border: 0;
	border-right: var(--hairline) solid var(--pe-rule-on-dark);
}

.finder__fields {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	border-top: var(--hairline) solid var(--pe-rule-on-dark);
}

.finder__fields .field {
	gap: 0;
	padding: var(--space-xs) var(--space-sm) var(--space-sm);
	border-right: var(--hairline) solid var(--pe-rule-on-dark);
	border-bottom: var(--hairline) solid var(--pe-rule-on-dark);
}

.finder__fields .field__label {
	font-size: var(--fs-3xs);
	white-space: nowrap;
}

.finder__fields .field__select {
	padding-block: var(--space-3xs) 0;
	padding-right: var(--space-md);
	font-family: var(--font-display);
	font-size: var(--fs-base);
	border-bottom: 0;
}

.finder__fields .field__select:focus-visible {
	box-shadow: none;
	text-decoration: underline;
	text-decoration-thickness: var(--hairline);
	text-underline-offset: 0.25em;
}

.finder__clear {
	justify-self: end;
	padding: var(--space-sm) var(--space-md);
	color: var(--pe-accent);
	text-decoration: underline;
	text-decoration-thickness: var(--hairline);
	text-underline-offset: 0.35em;
}

.finder__clear:hover {
	color: var(--pe-text-on-dark);
}

@media (min-width: 1024px) {
	.finder {
		grid-template-columns: auto 1fr auto;
		align-items: stretch;
	}

	.finder__for .choices {
		height: 100%;
	}

	.finder__for .choice {
		padding-inline: var(--space-sm);
	}

	.finder__fields {
		grid-template-columns: 1.5fr 1.1fr 1fr 1fr 1fr;
		border-top: 0;
	}

	.finder__fields .field {
		border-bottom: 0;
	}

	.finder__fields .field:last-child {
		border-right: 0;
	}

	.finder__clear {
		align-self: center;
		border-left: var(--hairline) solid var(--pe-rule-on-dark);
	}

	/* Hidden clear still keeps the fields' right rule from doubling. */
	.finder__clear[hidden] + * {
		border-right: 0;
	}
}


/* 02 Results =============================================================== */

/* A technical grid on the Cream: a fine line every 5rem, a firmer one every
   four, in Ink at a strength that reads as paper, not as lines. */
.listings__results {
	--grid-minor: color-mix(in srgb, var(--pe-ink) 3.5%, transparent);
	--grid-major: color-mix(in srgb, var(--pe-ink) 6.5%, transparent);

	background-color: var(--pe-bg);
	background-image:
		linear-gradient(to right, var(--grid-major) 1px, transparent 1px),
		linear-gradient(to bottom, var(--grid-major) 1px, transparent 1px),
		linear-gradient(to right, var(--grid-minor) 1px, transparent 1px),
		linear-gradient(to bottom, var(--grid-minor) 1px, transparent 1px);
	background-size: 20rem 20rem, 20rem 20rem, 5rem 5rem, 5rem 5rem;
	background-position: center top;
	color: var(--pe-text);
	/* The arc into the footer, cut from this ground so the grid runs into
	   the curve: the footer's lg divider keeps the space (footer.php). */
	--page-arc-h: clamp(4.5rem, 10vw, 12rem);
	--band-arc-h: clamp(2.5rem, 5vw, 5rem); /* the band's, from components.css */

	position: relative;
	z-index: 1;
	overflow: clip;
	/* Tucked up under the band's arc, so the grid fills the Cream either
	   side of the curve rather than starting beneath it. */
	margin-top: calc(-1 * var(--band-arc-h));
	padding-top: var(--band-arc-h);
	padding-bottom: calc(var(--space-section) + var(--page-arc-h));
	margin-bottom: calc(-1 * var(--page-arc-h));
	-webkit-mask-image:
		linear-gradient(#000, #000),
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 80' preserveAspectRatio='none'%3E%3Cpath d='M0,0 C480,106.7 960,106.7 1440,0 Z'/%3E%3C/svg%3E");
	mask-image:
		linear-gradient(#000, #000),
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 80' preserveAspectRatio='none'%3E%3Cpath d='M0,0 C480,106.7 960,106.7 1440,0 Z'/%3E%3C/svg%3E");
	-webkit-mask-size: 100% calc(100% - var(--page-arc-h) + 1px), 100% var(--page-arc-h);
	mask-size: 100% calc(100% - var(--page-arc-h) + 1px), 100% var(--page-arc-h);
	-webkit-mask-position: top, bottom;
	mask-position: top, bottom;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
}

.listings__results > .container {
	padding-top: var(--space-3xl);
}

/* Accent text on Cream uses the darkened Bronze: 4.91:1 (plain Bronze is 2:1). */
.listings__count {
	margin-bottom: var(--space-lg);
	color: var(--pe-accent-on-light);
}

.listings__count:focus {
	outline: none;
}

.property-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-2xl) var(--space-lg);
}

/* Two across from md (tablet), three from lg. */
@media (min-width: 768px) {
	.property-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.property-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

.listings__empty {
	max-width: var(--measure-narrow);
	padding-block: var(--space-2xl);
}

.listings__empty-title {
	font-size: var(--fs-2xl);
}

.listings__empty p {
	margin-top: var(--space-sm);
	color: var(--pe-text-muted);
}

.listings__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-sm);
	margin-top: var(--space-lg);
}


/* 03 Property card ========================================================= */

/*
 * A hairline Bronze frame around the photo and the details. The card is also
 * the positioning context for the title link's stretched hit area, so a click
 * anywhere on it opens the listing.
 *
 * The frame is decoration: Bronze on Cream is 2:1, which is fine for a border
 * that marks no state. What identifies the card is its title.
 */
.property-card {
	/* Arched at the top like the team's portraits, shallower for a landscape
	   frame. The frame and the photograph share the curve. */
	--card-arch: 50% 50% 0 0 / 28% 28% 0 0;

	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	background-color: var(--pe-bg);
	border: var(--hairline) solid var(--pe-accent);
	border-radius: var(--card-arch);
	transition:
		transform var(--dur-base) var(--ease-out),
		box-shadow var(--dur-base) var(--ease-out);
}

/* The lift: a soft Ink shadow, and a small rise where motion is welcome.
   Keyboard focus lifts it too, so hover is not the only way to see it. */
.property-card:hover,
.property-card:has(.property-card__link:focus-visible) {
	box-shadow: 0 var(--space-sm) var(--space-lg) color-mix(in srgb, var(--pe-ink) 12%, transparent);
}

@media (prefers-reduced-motion: no-preference) {
	.property-card:hover,
	.property-card:has(.property-card__link:focus-visible) {
		transform: translateY(calc(-1 * var(--space-3xs)));
	}
}

/* No photo yet: the same Pine-to-Deep ground the team placeholders use,
   with the palm mark. */
.property-card__media {
	display: grid;
	place-items: center;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	border-radius: var(--card-arch);
	background-color: var(--pe-surface-dark);
	background-image: linear-gradient(160deg, var(--pe-pine), var(--pe-deep));
}

.property-card__image {
	grid-area: 1 / 1;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.property-card__mark {
	width: var(--space-2xl);
	height: auto;
	opacity: 0.55;
}

.property-card__body {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	padding: var(--space-md) var(--space-md) var(--space-lg);
}

/* The gap spaces the card, not the prose flow rules in main.css, which would
   otherwise put 48px between the price and the title (p + h2). */
.property-card__body > * {
	margin: 0;
}

.property-card__price {
	font-family: var(--font-display);
	font-size: var(--fs-lg);
	line-height: var(--lh-snug);
}

.property-card__title {
	font-size: var(--fs-xl);
}

.property-card__link {
	color: inherit;
	text-decoration: none;
}

/* The link's hit area covers the whole card. */
.property-card__link::after {
	content: "";
	position: absolute;
	inset: 0;
}

.property-card__link:hover {
	color: inherit;
	text-decoration: underline;
	text-decoration-thickness: var(--hairline);
	text-underline-offset: 0.18em;
}

/*
 * Focus goes round the whole card, since the whole card is the target. In the
 * darkened Bronze: the global Bronze ring measures 2:1 on Cream, under the 3:1
 * a focus indicator needs.
 */
.property-card__link:focus-visible {
	outline: none;
}

.property-card:has(.property-card__link:focus-visible) {
	outline: 2px solid var(--pe-accent-on-light);
	outline-offset: var(--space-3xs);
}

.property-card__specs {
	display: flex;
	flex-wrap: wrap;
	color: var(--pe-text-muted);
}

.property-card__specs li + li {
	margin-left: var(--space-xs);
	padding-left: var(--space-xs);
	border-left: var(--hairline) solid var(--pe-rule);
}

.property-card__area {
	color: var(--pe-accent-on-light);
}


/* The featured card: the newest listing across the full width from lg, the
   photograph on the left and the details, with the first line of the
   description, beside it. On narrower screens it is a card like the rest. */
.property-card__excerpt {
	display: none;
	color: var(--pe-text-muted);
	font-size: var(--fs-md);
	line-height: var(--lh-loose);
	text-wrap: pretty;
}

@media (min-width: 1024px) {
	/* Not a box: the photograph stands as an arch on the Cream, the way the
	   team's portraits do, with the details beside it. */
	.property-card--featured {
		grid-column: 1 / -1;
		display: grid;
		grid-template-columns: 1.45fr 1fr;
		gap: var(--space-xl);
		border: 0;
		border-radius: 0;
		background: none;
	}

	.property-card--featured .property-card__media {
		border-radius: var(--card-arch);
		box-shadow: var(--space-xs) var(--space-xs) 0 0 color-mix(in srgb, var(--pe-ink) 8%, transparent);
	}

	.property-card--featured .property-card__media {
		aspect-ratio: 3 / 2;
	}

	.property-card--featured .property-card__body {
		justify-content: center;
		gap: var(--space-xs);
		padding: var(--space-lg) 0;
	}

	.property-card--featured .property-card__price {
		font-size: var(--fs-xl);
	}

	.property-card--featured .property-card__title {
		font-size: var(--fs-2xl);
	}

	.property-card--featured .property-card__excerpt {
		display: block;
		margin-top: var(--space-sm);
	}
}

/* 04 Pagination ============================================================ */

/* Square boxes, echoing the choice boxes. The current page is filled Forest. */
.pagination {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--space-2xs);
	margin-top: var(--space-3xl);
}

.pagination__pages {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2xs);
}

.pagination__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.75rem;  /* 44px tap target */
	min-height: 2.75rem;
	padding-inline: var(--space-sm);
	border: var(--hairline) solid var(--pe-rule);
	color: var(--pe-text);
	font-size: var(--fs-sm);
	text-decoration: none;
	transition:
		border-color var(--dur-fast) var(--ease),
		background-color var(--dur-fast) var(--ease),
		color var(--dur-fast) var(--ease);
}

.pagination__link:hover {
	border-color: var(--pe-accent-on-light);
	color: var(--pe-text);
}

.pagination__link:focus-visible {
	outline: 2px solid var(--pe-accent-on-light);
	outline-offset: 3px;
}

.pagination__link[aria-current="page"] {
	background-color: var(--pe-bg-dark);
	border-color: var(--pe-bg-dark);
	color: var(--pe-text-on-dark);
}

.pagination__gap {
	display: inline-flex;
	align-items: center;
	min-height: 2.75rem;
	padding-inline: var(--space-2xs);
	color: var(--pe-text-muted);
}


/* 05 Single property ======================================================= */

/* Page band extras --------------------------------------------------------- */

.property__back {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2xs);
	margin-bottom: var(--space-lg);
	color: var(--pe-text-on-dark);
	text-decoration: none;
	transition: color var(--dur-fast) var(--ease);
}

.property__back:hover,
.property__back:focus-visible {
	color: var(--pe-accent);
}

.property__price {
	margin-top: var(--space-md);
	font-family: var(--font-display);
	font-size: var(--fs-2xl);
	line-height: var(--lh-snug);
}

/* Cream body --------------------------------------------------------------- */

.property__content {
	background-color: var(--pe-bg);
	color: var(--pe-text);
	padding-bottom: var(--space-section);
}

.property__content > .container {
	padding-top: var(--space-2xl);
}

/* Gallery ------------------------------------------------------------------ */

.property-gallery {
	margin: 0;
}

/* The large frame keeps one shape whatever is in it, so swapping photographs
   never moves the page. Cover crops a photo to fit; on a phone the frame is
   squarer so less is lost. */
.property-gallery__main {
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background-color: var(--pe-surface-dark);
	background-image: linear-gradient(160deg, var(--pe-pine), var(--pe-deep));
}

@media (min-width: 768px) {
	.property-gallery__main {
		aspect-ratio: 3 / 2;
	}
}

.property-gallery__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.property-gallery__thumbs {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr));
	gap: var(--space-xs);
	margin-top: var(--space-xs);
}

/* Dimmed until chosen; the one on show is at full strength with a Bronze
   frame. Both change together, so the chosen one is not marked by colour
   alone. */
.property-gallery__thumb {
	display: block;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	border: var(--hairline) solid transparent;
	opacity: 0.65;
	transition:
		opacity var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease);
}

.property-gallery__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.property-gallery__thumb:hover,
.property-gallery__thumb[aria-current="true"] {
	opacity: 1;
	border-color: var(--pe-accent);
}

.property-gallery__thumb:focus-visible {
	outline: 2px solid var(--pe-accent-on-light);
	outline-offset: 2px;
}

/* Columns ------------------------------------------------------------------ */

.property__columns {
	display: grid;
	gap: var(--space-2xl);
	margin-top: var(--space-2xl);
}

/* Two columns from lg. The aside is a card, so it needs a real minimum;
   minmax(0, ...) on the main column lets the map and plan shrink rather than
   overflow. */
@media (min-width: 1024px) {
	.property__columns {
		grid-template-columns: minmax(0, 2fr) minmax(18rem, 1fr);
		column-gap: var(--space-3xl);
		align-items: start;
	}

	/* Stays in view as the page scrolls, below the floating header. */
	.property__aside {
		position: sticky;
		top: calc(var(--header-h) + var(--header-offset) + var(--space-md));
	}
}

/* Facts -------------------------------------------------------------------- */

.property__facts {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--space-lg) var(--space-md);
	padding-block: var(--space-lg);
	border-top: var(--hairline) solid var(--pe-rule);
	border-bottom: var(--hairline) solid var(--pe-rule);
}

@media (min-width: 640px) {
	.property__facts {
		grid-template-columns: repeat(4, 1fr);
	}
}

.property__fact-label {
	color: var(--pe-accent-on-light);
}

.property__fact-value {
	margin-top: var(--space-2xs);
	font-family: var(--font-display);
	font-size: var(--fs-xl);
	line-height: var(--lh-snug);
}

/* Sections ----------------------------------------------------------------- */

.property__section {
	margin-top: var(--space-2xl);
}

.property__heading {
	margin-bottom: var(--space-md);
	font-size: var(--fs-2xl);
}

/* Editor content: the flow rules in main.css space it; this only holds the
   measure. Shared name, so About and FAQ can use it too. */
.prose {
	max-width: var(--measure);
}

.prose img {
	margin-block: var(--space-lg);
}

.property__area {
	margin-bottom: var(--space-md);
	color: var(--pe-text-muted);
}

/* Floor plan --------------------------------------------------------------- */

/* Plans are usually drawn on white, which on Cream reads as a sheet; a rule
   around it makes that deliberate. */
.property__floor-plan {
	margin: 0;
}

.property__floor-plan a {
	display: block;
	border: var(--hairline) solid var(--pe-rule);
	background-color: #fff; /* the plan's own paper, not a palette colour */
}

.property__floor-plan img {
	width: 100%;
}

.property__caption {
	margin-top: var(--space-2xs);
	color: var(--pe-text-muted);
}

/* Map ---------------------------------------------------------------------- */

.property__map {
	aspect-ratio: 16 / 10;
	overflow: hidden;
	border: var(--hairline) solid var(--pe-rule);
	background-color: var(--pe-surface-dark);
}

.property__map iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
}

.property__map-link {
	display: inline-block;
	margin-top: var(--space-sm);
	color: var(--pe-accent-on-light);
}

/* Agent card --------------------------------------------------------------- */

/* Framed like a property card. The portrait is the team section's arch at a
   smaller size (the token is repeated because home.css is not loaded here). */
.agent-card {
	padding: var(--space-lg);
	border: var(--hairline) solid var(--pe-accent);
	background-color: var(--pe-bg);
}

.agent-card__eyebrow {
	margin-bottom: var(--space-md);
	color: var(--pe-accent-on-light);
}

.agent-card__portrait {
	--agent-arch: 50% 50% 0 0 / 40% 40% 0 0;

	display: grid;
	place-items: center;
	width: 8.5rem;
	aspect-ratio: 4 / 5;
	margin: 0;
	overflow: hidden;
	background-color: var(--pe-surface-dark);
	background-image: linear-gradient(160deg, var(--pe-pine), var(--pe-deep));
	border-radius: var(--agent-arch);
	box-shadow: var(--space-2xs) var(--space-2xs) 0 color-mix(in srgb, var(--pe-ink) 8%, transparent);
}

.agent-card__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 20%;
	filter: grayscale(0.9) sepia(0.12) contrast(0.92);
}

.agent-card__mark {
	width: var(--space-xl);
	height: auto;
	opacity: 0.55;
}

.agent-card__name {
	margin-top: var(--space-md);
	font-family: var(--font-display);
	font-size: var(--fs-xl);
	line-height: var(--lh-snug);
}

.agent-card__role {
	margin-top: var(--space-3xs);
	color: var(--pe-accent-on-light);
}

.agent-card__actions {
	display: grid;
	gap: var(--space-sm);
	margin-top: var(--space-lg);
}

.agent-card__whatsapp {
	justify-self: start;
	min-height: 2.75rem;
}

.agent-card__alt {
	font-size: var(--fs-sm);
	color: var(--pe-text-muted);
}

.agent-card__alt a {
	color: var(--pe-accent-on-light);
}
