/* --------------------------------------------------------------------------
 * PadelMap — single court & courts archive styles.
 * Loaded conditionally by inc/assets.php only on those views.
 * Uses design tokens from theme.json (CSS vars resolved by WP).
 * ----------------------------------------------------------------------- */

:root {
	--padelmap-radius:  16px;
	--padelmap-shadow:  0 1px 2px rgba(15,23,42,0.04), 0 4px 12px rgba(15,23,42,0.06);
	--padelmap-border:  1px solid #E5E7EB;
}

/* ===== Shared utilities ================================================ */

.padelmap-chip {
	display: inline-flex;
	align-items: center;
	gap: 0.25rem;
	padding: 0.25rem 0.625rem;
	border-radius: 999px;
	background: var(--wp--preset--color--padelmap-sun);
	color: var(--wp--preset--color--padelmap-charcoal);
	font-size: 0.875rem;
	font-weight: 600;
	line-height: 1;
}

.padelmap-btn {
	display: inline-block;
	padding: 0.75rem 1.5rem;
	border: 0;
	/* Modern, slightly rounded — not a pill. */
	border-radius: 8px;
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.2;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 180ms ease, color 180ms ease, transform 150ms ease, box-shadow 180ms ease;
}
/* Higher specificity (a.…) wins against Kadence's `.entry-content a { color: … }`
   which was repainting the second CTA white when sitting inside post content. */
a.padelmap-btn--primary,
.padelmap-btn--primary {
	background: var(--wp--preset--color--padelmap-court, #1F8A3F);
	color: #ffffff;
}
a.padelmap-btn--primary:hover,
a.padelmap-btn--primary:focus,
.padelmap-btn--primary:hover,
.padelmap-btn--primary:focus {
	/* Lighter — not darker — on hover so the button stays visible against
	   the dark hero scrim (going darker blended into the gradient). */
	background: var(--wp--preset--color--padelmap-court-light, #2EA855);
	color: #ffffff;
	transform: translateY(-1px);
	box-shadow: 0 6px 18px rgba(31, 138, 63, 0.32);
}
a.padelmap-btn--primary:focus-visible,
.padelmap-btn--primary:focus-visible {
	outline: 3px solid var(--wp--preset--color--padelmap-sun, #D4F33B);
	outline-offset: 2px;
}

/* ===== Single court ==================================================== */

.padelmap-court-single .padelmap-court-hero {
	position: relative;
	color: #fff;
	min-height: 360px;
	display: flex;
	align-items: flex-end;
	margin-bottom: 2rem;
	overflow: hidden;
	border-radius: 0 0 var(--padelmap-radius) var(--padelmap-radius);
}
.padelmap-court-hero__media {
	position: absolute;
	inset: 0;
}
.padelmap-court-hero__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.padelmap-court-hero__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(26,31,46,0.15) 0%, rgba(26,31,46,0.85) 100%);
}
.padelmap-court-hero__inner {
	position: relative;
	padding: 2rem 1.5rem;
	max-width: 1100px;
	margin: 0 auto;
	width: 100%;
}
.padelmap-court-hero__eyebrow {
	margin: 0 0 0.25rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	font-size: 0.75rem;
	font-weight: 600;
	color: var(--wp--preset--color--padelmap-sun);
}
.padelmap-court-hero__title {
	margin: 0 0 1rem;
	font-size: clamp(1.75rem, 4vw + 1rem, 3rem);
	line-height: 1.1;
	/* Override theme/Kadence heading colour — hero sits on a dark scrim. */
	color: #fff;
	text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
.padelmap-court-hero__meta {
	display: flex;
	align-items: center;
	gap: 1rem;
	flex-wrap: wrap;
}

.padelmap-court-body {
	max-width: 1100px;
	margin: 0 auto;
	padding: 0 1.5rem 4rem;
}
.padelmap-court-content {
	max-width: 720px;
	margin-bottom: 2.5rem;
	font-size: 1.0625rem;
	line-height: 1.6;
}

.padelmap-court-section-title {
	margin: 3rem 0 1rem;
	font-size: 1.5rem;
}

.padelmap-court-details {
	margin: 2rem 0 3rem;
}
.padelmap-court-details__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 1.5rem;
}
/* Allow grid items to shrink so long unbroken strings (URLs, addresses)
   don't blow out the column width. */
.padelmap-court-details__grid > * {
	min-width: 0;
}
.padelmap-court-details__block {
	padding: 1.25rem 1.5rem;
	border: var(--padelmap-border);
	border-radius: var(--padelmap-radius);
	background: #fff;
	min-width: 0;
}
.padelmap-court-details__block h3 {
	margin: 0 0 0.75rem;
	font-size: 1rem;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--padelmap-slate);
}
.padelmap-court-details__block dl {
	margin: 0;
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 0.5rem 1rem;
	font-size: 0.95rem;
}
.padelmap-court-details__block dt {
	font-weight: 600;
	color: var(--wp--preset--color--padelmap-slate);
}
.padelmap-court-details__block dd {
	margin: 0;
	min-width: 0;
	overflow-wrap: anywhere;
	word-break: break-word;
}
.padelmap-court-details__block dd a {
	overflow-wrap: anywhere;
	word-break: break-word;
}
.padelmap-court-details__hours {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.95rem;
}
.padelmap-court-details__hours th {
	text-align: left;
	font-weight: 600;
	color: var(--wp--preset--color--padelmap-slate);
	padding: 0.25rem 0.5rem 0.25rem 0;
}
.padelmap-court-details__hours td {
	padding: 0.25rem 0;
}
.padelmap-court-details__closed {
	color: var(--wp--preset--color--padelmap-slate);
	opacity: 0.7;
}
.padelmap-court-details__amenities {
	list-style: none;
	padding: 0;
	margin: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

/* Social icons — sit in the Contact <dd> next to the "Social" label.
   Rendered as a <ul>: we reset list styling defensively (the theme has
   a higher-specificity ul rule elsewhere) and lay children out horizontally.
   Tap targets are 44×44 to meet WCAG 2.5.5 AAA and Apple/Google touch guidance. */
.padelmap-court-details__socials,
.padelmap-court-details__socials li {
	list-style: none;
}
.padelmap-court-details .padelmap-court-details__socials {
	margin: 0;
	padding: 0;
	padding-inline-start: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0;
}
.padelmap-court-details .padelmap-court-details__socials li {
	margin: 0;
	padding: 0;
	display: inline-flex;
}
.padelmap-court-details .padelmap-court-details__socials a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 999px;
	background: transparent;
	color: var(--wp--preset--color--padelmap-ocean);
	text-decoration: none;
	transition: opacity 150ms ease;
}
.padelmap-court-details .padelmap-court-details__socials a:hover,
.padelmap-court-details .padelmap-court-details__socials a:focus-visible {
	opacity: 0.65;
}
.padelmap-court-details .padelmap-court-details__socials svg {
	display: block;
	width: 20px;
	height: 20px;
	fill: currentColor;
}
.padelmap-court-details .padelmap-court-details__socials svg path {
	fill: currentColor;
}
.padelmap-court-details__amenities li {
	padding: 0.25rem 0.625rem;
	background: var(--wp--preset--color--padelmap-cream);
	border-radius: 999px;
	font-size: 0.875rem;
}
.padelmap-court-details__cta {
	margin-top: 1.5rem;
}

/* "Good to know" — WYSIWYG additional details, full-width below the grid. */
.padelmap-court-details__notes {
	margin: 2rem 0 0;
	padding: 1.5rem 1.75rem;
	border: var(--padelmap-border);
	border-radius: var(--padelmap-radius);
	background: #fff;
}
.padelmap-court-details__notes h3 {
	margin: 0 0 0.75rem;
	font-size: 1rem;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--padelmap-slate);
}
.padelmap-court-details__notes-body {
	font-size: 1rem;
	line-height: 1.55;
	color: var(--wp--preset--color--padelmap-charcoal);
	overflow-wrap: anywhere;
}
.padelmap-court-details__notes-body p:first-child { margin-top: 0; }
.padelmap-court-details__notes-body p:last-child  { margin-bottom: 0; }
.padelmap-court-details__notes-body a {
	color: var(--wp--preset--color--padelmap-court);
	overflow-wrap: anywhere;
	word-break: break-word;
}

.padelmap-court-map {
	width: 100%;
	height: 360px;
	border-radius: var(--padelmap-radius);
	overflow: hidden;
	border: var(--padelmap-border);
}

/* ===== Courts archive ================================================== */

.padelmap-archive-page .padelmap-archive-header {
	max-width: 1400px;
	margin: 2rem auto 1.5rem;
	padding: 0 1.5rem;
}
.padelmap-archive-header__title {
	margin: 0 0 0.5rem;
	font-size: clamp(1.75rem, 3vw + 1rem, 2.5rem);
}
.padelmap-archive-header__subtitle {
	margin: 0;
	color: var(--wp--preset--color--padelmap-slate);
	font-size: 1.0625rem;
}

.padelmap-archive {
	max-width: 1400px;
	margin: 0 auto 4rem;
	padding: 0 1.5rem;
}

.padelmap-archive__filters {
	display: grid;
	/* Search · City · Type · Amenity · Max price · Reset */
	grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr auto;
	gap: 0.75rem;
	align-items: end;
	padding: 1rem 1.25rem;
	background: #fff;
	border: var(--padelmap-border);
	border-radius: var(--padelmap-radius);
	margin-bottom: 1.5rem;
}

/* When the favorites chip is visible (only for users with >=1 favorite),
   expand the grid to 7 tracks so the chip + Reset sit inline instead of
   the extra item wrapping to a new row. `[hidden]` on the chip keeps
   this selector inert for first-time visitors, so the filter row's
   visual footprint doesn't change for them at all. `:has()` support:
   Safari 15.4+, Chrome 105+, Firefox 121+ — matches our baseline. */
.padelmap-archive__filters:has(.padelmap-archive__fav-chip:not([hidden])) {
	grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr auto auto;
}
/* Toggle button is a grid item that's hidden on desktop — it has no
   reserved column, so grid auto-placement just skips it. */
.padelmap-archive__toggle {
	display: none !important;
}

@media (max-width: 1100px) {
	.padelmap-archive__filters {
		grid-template-columns: 1fr 1fr 1fr;
	}
	.padelmap-archive__reset {
		grid-column: 1 / -1;
	}
}

@media (max-width: 720px) {
	/* Search + icon-only Filters button share one row. Additional filters
	   wrap to a new line below when the form gets .is-open. */
	.padelmap-archive__filters {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		align-items: end;
		gap: 0.5rem;
		padding: 0.875rem 1rem;
	}

	.padelmap-archive__field--search {
		flex: 1 1 auto;
		min-width: 0;
		margin: 0;
	}

	/* Square icon button. Width matches input height roughly so the two
	   sit at the same baseline. Background transparent so the dark icon
	   reads cleanly on the white filter bar. */
	.padelmap-archive__toggle {
		display: inline-flex !important;
		align-items: center;
		justify-content: center;
		flex: 0 0 auto;
		width: 42px;
		height: 42px;
		padding: 0;
		border: 1px solid rgba(0, 0, 0, 0.18);
		border-radius: 10px;
		background: transparent;
		color: var(--wp--preset--color--padelmap-charcoal, #1A1F2E) !important;
		cursor: pointer;
		transition: background-color 180ms ease, border-color 180ms ease, color 180ms ease;
	}

	/* "Filters" text becomes screen-reader only — visual users see the icon. */
	.padelmap-archive__toggle-label {
		position: absolute !important;
		width: 1px;
		height: 1px;
		padding: 0;
		margin: -1px;
		overflow: hidden;
		clip: rect(0, 0, 0, 0);
		white-space: nowrap;
		border: 0;
	}

	/* Filter icon — three horizontal lines, decreasing. Mask uses
	   currentColor so the icon picks up the button's text color. */
	.padelmap-archive__toggle::before {
		content: '';
		display: inline-block;
		width: 22px;
		height: 22px;
		background-color: currentColor;
		-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'><line x1='4' y1='7' x2='20' y2='7'/><line x1='7' y1='12' x2='17' y2='12'/><line x1='10' y1='17' x2='14' y2='17'/></svg>") center / 22px no-repeat;
		mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'><line x1='4' y1='7' x2='20' y2='7'/><line x1='7' y1='12' x2='17' y2='12'/><line x1='10' y1='17' x2='14' y2='17'/></svg>") center / 22px no-repeat;
	}
	/* Drop the chevron from the earlier design — icon alone is enough.
	   ::after is repurposed below as a count badge when filters are active. */
	.padelmap-archive__toggle::after {
		display: none;
	}

	/* Active-filter count badge — sits in the top-right corner of the
	   toggle. JS sets data-active-count on the button; the attribute
	   selector both drives visibility and provides the numeric label.
	   `button.` prefix is here for the same reason as on the reset:
	   Kadence's own button rules would otherwise strip our background. */
	button.padelmap-archive__toggle[data-active-count]:not([data-active-count=""]) {
		position: relative;
	}
	button.padelmap-archive__toggle[data-active-count]:not([data-active-count=""])::after {
		content: attr(data-active-count);
		display: inline-flex;
		align-items: center;
		justify-content: center;
		position: absolute;
		top: -6px;
		right: -6px;
		min-width: 18px;
		height: 18px;
		padding: 0 4px;
		/* Colors are hex + !important + long-hand border to survive Kadence's
		   button rules (which use !important on shorthand `background` and
		   `border`). Splitting border into its 3 long-hand parts means a
		   theme `border: none` shorthand can't wipe out just our color. */
		background-color: #1B4F8A !important;
		color: #FFFFFF !important;
		border-width: 2px !important;
		border-style: solid !important;
		border-color: #1B4F8A !important;
		border-radius: 999px;
		font-size: 11px;
		font-weight: 700;
		line-height: 1;
		font-variant-numeric: tabular-nums;
		box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
	}

	.padelmap-archive__toggle:hover,
	.padelmap-archive__toggle:focus {
		background: rgba(0, 0, 0, 0.05);
		border-color: rgba(0, 0, 0, 0.30);
	}

	/* Active (filters open) — button fills with brand green, icon goes white. */
	.padelmap-archive__toggle[aria-expanded="true"] {
		background: var(--wp--preset--color--padelmap-court, #1F8A3F);
		color: #ffffff !important;
		border-color: var(--wp--preset--color--padelmap-court, #1F8A3F);
	}
	.padelmap-archive__toggle[aria-expanded="true"]:hover,
	.padelmap-archive__toggle[aria-expanded="true"]:focus {
		background: var(--wp--preset--color--padelmap-court-light, #2EA855);
		border-color: var(--wp--preset--color--padelmap-court-light, #2EA855);
	}

	/* Hide all filter fields + Reset + Favorites chip by default. Adding
	   .is-open reveals them as full-width rows wrapped below the
	   search/toggle row. */
	.padelmap-archive__filters .padelmap-archive__field:not(.padelmap-archive__field--search),
	.padelmap-archive__filters .padelmap-archive__reset,
	.padelmap-archive__filters .padelmap-archive__fav-chip {
		display: none;
	}
	.padelmap-archive__filters.is-open .padelmap-archive__field:not(.padelmap-archive__field--search) {
		display: flex;
		flex-direction: column;
		gap: 0.25rem;
		flex: 1 0 100%;
	}
	.padelmap-archive__filters.is-open .padelmap-archive__reset {
		display: inline-flex;
		flex: 1 0 100%;
		margin-top: 0.25rem;
	}
	/* Favorites chip on mobile — visible when the drawer is open (.is-open)
	   AND the user has favorites (JS clears the [hidden] attr). Kept at its
	   natural 40x40 icon-only size; flows inline on its own row because
	   the max-price field before it takes flex-basis 100%. */
	.padelmap-archive__filters.is-open .padelmap-archive__fav-chip:not([hidden]) {
		display: inline-flex;
	}
	/* Subtle divider above the first revealed filter (sits right after the
	   toggle in DOM, so we target that sibling). Mobile-scoped media query
	   keeps this from affecting desktop. */
	.padelmap-archive__filters.is-open .padelmap-archive__toggle + .padelmap-archive__field {
		padding-top: 0.5rem;
		border-top: 1px solid rgba(0, 0, 0, 0.08);
	}
}
.padelmap-archive__field {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
}
.padelmap-archive__field > span {
	font-size: 0.75rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--padelmap-slate);
}
.padelmap-archive__field input,
.padelmap-archive__field select {
	padding: 0.5rem 0.75rem;
	border: var(--padelmap-border);
	border-radius: 8px;
	font: inherit;
	background: #fff;
	transition: border-color 150ms ease, box-shadow 150ms ease;
}

/* --- Active-filter feedback -------------------------------------------------
   JS toggles .is-active on each field whose control has a value. Label turns
   court-green and the control gets a matching border + soft ring so users can
   scan the bar and see which filters are engaged. */
.padelmap-archive__field.is-active > span {
	color: var(--wp--preset--color--padelmap-court);
}
.padelmap-archive__field.is-active input,
.padelmap-archive__field.is-active select {
	border-color: var(--wp--preset--color--padelmap-court);
	box-shadow: 0 0 0 3px rgba(31, 138, 63, 0.15);
}

.padelmap-archive__reset {
	padding: 0.5rem 1rem;
	border: var(--padelmap-border);
	border-radius: 8px;
	background: var(--wp--preset--color--padelmap-cream);
	/* Override Kadence's white-on-brand default button colour. */
	color: var(--wp--preset--color--padelmap-charcoal);
	cursor: pointer;
	font-weight: 600;
	transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
}

/* Favorites-only filter chip — icon-only star button that sits between
   the filter fields and Reset. Only visible when the user has >=1
   favorite (JS toggles [hidden]). Sized to match Reset's height so
   they align on the same baseline. Count badge in the top-right mirrors
   the pattern used on the mobile Filters toggle. */
.padelmap-archive__fav-chip {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: var(--padelmap-border);
	border-radius: 999px;
	background: var(--wp--preset--color--padelmap-cream);
	color: var(--wp--preset--color--padelmap-charcoal);
	cursor: pointer;
	transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
}
.padelmap-archive__fav-chip[hidden] {
	display: none;
}
.padelmap-archive__fav-chip-icon {
	display: block;
	color: #E9B22A;
	pointer-events: none;
}
/* Outline star in the idle chip — the amber colour still hints at the
   favorite theme but the shape reads as "empty" until pressed. */
.padelmap-archive__fav-chip[aria-pressed="false"] .padelmap-archive__fav-chip-icon path {
	fill: none;
}
.padelmap-archive__fav-chip:hover,
.padelmap-archive__fav-chip:focus-visible {
	background: #efece2;
	outline: none;
}
/* Pressed = green border + ring, matching the "engaged filter" affordance
   applied to city / type / amenity fields elsewhere in the filter row.
   The star inside stays amber so the favorites semantic (star = your
   picks) is preserved via the icon; the chrome speaks the filter-active
   language shared with every other engaged control. */
.padelmap-archive__fav-chip[aria-pressed="true"] {
	background: rgba(31, 138, 63, 0.08);
	border-color: var(--wp--preset--color--padelmap-court, #1F8A3F);
	box-shadow: 0 0 0 3px rgba(31, 138, 63, 0.15);
}
.padelmap-archive__fav-chip[aria-pressed="true"] .padelmap-archive__fav-chip-icon path {
	fill: currentColor;
}
.padelmap-archive__reset:hover,
.padelmap-archive__reset:focus {
	background: #efece2;
	color: var(--wp--preset--color--padelmap-charcoal);
}

/* Active-state Reset — mirror the green highlight the filter fields get
   (green border + soft ring) while keeping the base cream background and
   charcoal text. This stays reliably readable because we never fight
   Kadence for `background-color` (which the parent theme overrides with
   `!important`); only border-color and box-shadow, which it doesn't touch. */
.padelmap-archive__filters.has-active-filters button.padelmap-archive__reset {
	border-color: var(--wp--preset--color--padelmap-court);
	box-shadow: 0 0 0 3px rgba(31, 138, 63, 0.15);
}
.padelmap-archive__filters.has-active-filters button.padelmap-archive__reset:hover,
.padelmap-archive__filters.has-active-filters button.padelmap-archive__reset:focus {
	border-color: var(--wp--preset--color--padelmap-court-dark);
	box-shadow: 0 0 0 3px rgba(31, 138, 63, 0.25);
}

.padelmap-archive__layout {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 1.5rem;
}
@media (max-width: 900px) {
	.padelmap-archive__layout {
		grid-template-columns: 1fr;
	}
	.padelmap-archive__map {
		/* Map above list on mobile: visitors scan spatially first, then read
		   the results below. Overrides the DOM order (list-first) which we
		   keep for a11y/SEO. */
		order: -1;
		position: static;
		min-height: 360px;
	}
}

.padelmap-archive__list {
	min-height: 200px;
}
.padelmap-archive__count {
	margin: 0.75rem 0 0;
	font-size: 0.875rem;
	color: var(--wp--preset--color--padelmap-slate);
}
.padelmap-archive__loading,
.padelmap-archive__empty {
	padding: 1rem;
	color: var(--wp--preset--color--padelmap-slate);
	text-align: center;
}

.padelmap-archive__items {
	list-style: none;
	padding: 0;
	margin: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: 1rem;
}
/* Card = outer <li> in the archive list.
   Hover/active raise is on the <li> so the marker->card scroll flash still
   works (JS toggles .padelmap-archive__card--active on the <li>). */
.padelmap-archive__card {
	border: var(--padelmap-border);
	border-radius: var(--padelmap-radius);
	background: #fff;
	overflow: hidden;
	transition: transform 200ms ease, box-shadow 200ms ease;
}
.padelmap-archive__card:hover,
.padelmap-archive__card--active,
.padelmap-archive__card:focus-within {
	transform: translateY(-2px);
	box-shadow: var(--padelmap-shadow);
}

/* Inner <article> hosts the stretched-link overlay. Must be positioned so
   the title link's ::after has a containing block. Uses grid so the
   actions row is pinned to the bottom regardless of body content length —
   card heights stay uniform across the grid. */
.padelmap-archive__card-inner {
	position: relative;
	display: grid;
	grid-template-rows: auto 1fr auto;
	height: 100%;
	color: inherit;
}

/* Media + body deliberately NOT positioned. The stretched-link ::after
   positions relative to its nearest positioned ancestor, which must be
   .card-inner — if we position media or body they steal that anchor
   and the overlay only covers part of the card, breaking click-anywhere. */
.padelmap-archive__card-media {
	aspect-ratio: 3 / 2;
	background: var(--wp--preset--color--padelmap-cream);
}
.padelmap-archive__card-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.padelmap-archive__card-noimg {
	width: 100%;
	height: 100%;
	background:
		linear-gradient(135deg, rgba(31,138,63,0.15), rgba(27,79,138,0.15)),
		var(--wp--preset--color--padelmap-cream);
}
.padelmap-archive__card-body {
	padding: 0.875rem 1rem 1rem;
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
}
.padelmap-archive__card-city {
	margin: 0;
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--padelmap-slate);
}
.padelmap-archive__card-title {
	margin: 0;
	font-size: 1.125rem;
	line-height: 1.25;
}
/* Stretched link — the title anchor's ::after fills the card so any click
   on blank card space (media, body, chip, whitespace) opens the detail
   page. Actions row overrides via z-index below. */
.padelmap-archive__card-title-link {
	color: inherit;
	text-decoration: none;
}
.padelmap-archive__card-title-link:hover,
.padelmap-archive__card-title-link:focus-visible {
	color: var(--wp--preset--color--padelmap-court, #1F8A3F);
}
.padelmap-archive__card-title-link::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 0;
	border-radius: inherit;
}
.padelmap-archive__card-title-link:focus-visible::after {
	outline: 3px solid var(--wp--preset--color--padelmap-sun, #D4F33B);
	outline-offset: -3px;
}
.padelmap-archive__card-addr {
	margin: 0;
	font-size: 0.875rem;
	color: var(--wp--preset--color--padelmap-slate);
}

.padelmap-archive__map {
	border-radius: var(--padelmap-radius);
	overflow: hidden;
	border: var(--padelmap-border);
}
/* Desktop-only: sticky map that hangs beside the scrolling list.
   Kept in its own min-width query so the mobile block above (which places
   the map above the list in normal flow) doesn't have to fight source order. */
@media (min-width: 901px) {
	.padelmap-archive__map {
		min-height: 480px;
		position: sticky;
		top: 80px;
		align-self: start;
	}
}

/* Highlight a marker on card hover (set by JS) */
.padelmap-marker--active {
	filter: drop-shadow(0 0 4px var(--wp--preset--color--padelmap-sun));
}

/* ============================================================
   Court card quick actions — Call / Book / Directions
   ------------------------------------------------------------
   Rendered by inc/card-actions.php (PHP) and mirrored in
   assets/js/courts-archive.js (JS). Both must stay in sync.

   Style: Material-3-inspired tonal buttons — filled primary
   (Call) + two soft-tinted "tonal" secondaries. Compact and
   contemporary; not the equal-weight pill row of 2018 real-
   estate cards.

   Space: three (or two/one) equal tracks via
   `grid-auto-columns: minmax(0, 1fr)`. The `minmax(0, ...)`
   is load-bearing — without it, long BG labels ("Резервирай",
   "Навигация") push the tracks past the card's `overflow:hidden`
   boundary and the third button silently disappears.

   Container queries collapse labels to icon-only when a card
   is narrower than 320px (two-pane layouts, dense grids). The
   card gets `container-type: inline-size` further up.

   z-index:1 keeps the row above the .card-title-link::after
   stretched-link overlay so button clicks are captured here
   and never trigger the card's whole-card navigation.
   ============================================================ */
/* Default = compact "chip row" — icon-only 36px squares packed to the
   left. This is the state most cards land in (single-column mobile, and
   ~330px cards in the desktop two-pane). Labels are opt-in for wide
   cards only (see the container query below). */
.padelmap-card-actions {
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
	justify-content: flex-start;
	align-items: center;
	gap: 6px;
	padding: 10px 14px 14px;
	position: relative;
	z-index: 1;
	/* Query root for the wide-card label reveal below. Querying our own
	   width matches the card width, so the same rule works on the archive
	   block and the pattern-rendered card without any wrapper coordination. */
	container-type: inline-size;
	container-name: pmactions;
	/* Gaps + padding fall through to the stretched title link so the
	   "click anywhere to open" affordance survives; buttons opt back in. */
	pointer-events: none;
}
.pm-action {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 5px;
	flex-shrink: 0;
	width: 36px;                /* icon-only chip — square */
	height: 36px;
	padding: 0;
	border: 0;
	border-radius: 10px;
	font-size: 0.8125rem;       /* 13px — for the wide-card label mode */
	font-weight: 500;
	line-height: 1.2;
	letter-spacing: -0.005em;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	transition:
		background-color 160ms cubic-bezier(0.4, 0, 0.2, 1),
		color 160ms cubic-bezier(0.4, 0, 0.2, 1),
		box-shadow 160ms cubic-bezier(0.4, 0, 0.2, 1),
		transform 100ms cubic-bezier(0.4, 0, 0.2, 1);
	-webkit-tap-highlight-color: transparent;
	pointer-events: auto;
}
.pm-action__icon {
	width: 18px;
	height: 18px;
	flex-shrink: 0;
}
.pm-action__label {
	/* Visually hidden by default (icon-only chips). aria-label on the
	   anchor carries the meaning for screen readers. The wide-card
	   query below re-exposes labels when there's room. */
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}
.pm-action:active {
	transform: scale(0.94);
}
.pm-action:focus-visible {
	outline: 2px solid var(--wp--preset--color--padelmap-court, #1F8A3F);
	outline-offset: 2px;
}

/* Primary: Call — filled brand green with subtle elevation. Contemporary
   flat-with-lift look (M3 "filled button"). */
.pm-action--call {
	background: var(--wp--preset--color--padelmap-court, #1F8A3F);
	color: #fff;
	box-shadow: 0 1px 2px rgba(15, 23, 42, 0.10);
}
.pm-action--call:hover {
	background: var(--wp--preset--color--padelmap-court-dark, #155F2A);
	box-shadow: 0 2px 6px rgba(31, 138, 63, 0.28);
}

/* Secondary: Book — tonal ocean-blue. */
.pm-action--book {
	background: rgba(27, 79, 138, 0.10);
	color: var(--wp--preset--color--padelmap-ocean, #1B4F8A);
}
.pm-action--book:hover {
	background: rgba(27, 79, 138, 0.18);
}

/* Tertiary: Directions — tonal slate. */
.pm-action--dir {
	background: rgba(74, 81, 99, 0.08);
	color: var(--wp--preset--color--padelmap-slate, #4A5163);
}
.pm-action--dir:hover {
	background: rgba(74, 81, 99, 0.16);
	color: var(--wp--preset--color--padelmap-charcoal, #1A1F2E);
}

/* Quaternary: Instagram — tonal pink-slate hint. Recognisable IG glyph
   plus a warm tonal so it reads as a social/vibe-check action, not a
   primary flow. Subtle enough to sit next to the other tonals. */
.pm-action--ig {
	background: rgba(196, 39, 137, 0.08);
	color: #A6217A;
}
.pm-action--ig:hover {
	background: rgba(196, 39, 137, 0.16);
	color: #7A1058;
}

/* Wide card (≥ 460px actions row) — enough room to reveal labels for
   all 4 buttons in BG (widest is "Резервирай" ≈ 72px @ 13px). Chips
   grow from 36×36 squares to auto-width pills with padding. */
@container pmactions (min-width: 460px) {
	.padelmap-card-actions {
		display: grid;
		grid-auto-flow: column;
		grid-auto-columns: minmax(0, 1fr);
		gap: 6px;
	}
	.pm-action {
		width: auto;
		height: auto;
		min-height: 38px;
		padding: 0 10px;
	}
	.pm-action__icon {
		width: 16px;
		height: 16px;
	}
	.pm-action__label {
		/* Un-hide */
		position: static;
		width: auto;
		height: auto;
		margin: 0;
		overflow: hidden;
		text-overflow: ellipsis;
		clip: auto;
		white-space: nowrap;
		min-width: 0;
	}
}
/* Viewport fallback for browsers without @container support (~4% in 2026).
   Kept as a media query so the label mode still activates on larger phones/
   desktops where cards will typically be roomy. */
@supports not (container-type: inline-size) {
	@media (min-width: 900px) {
		.padelmap-card-actions {
			display: grid;
			grid-auto-flow: column;
			grid-auto-columns: minmax(0, 1fr);
		}
		.pm-action {
			width: auto;
			height: auto;
			min-height: 38px;
			padding: 0 10px;
		}
		.pm-action__label {
			position: static;
			width: auto;
			height: auto;
			margin: 0;
			overflow: hidden;
			text-overflow: ellipsis;
			clip: auto;
			white-space: nowrap;
			min-width: 0;
		}
	}
}

/* Reduced motion — kill the press-scale and any transitions. */
@media (prefers-reduced-motion: reduce) {
	.pm-action,
	.padelmap-archive__card {
		transition: none;
	}
	.pm-action:active {
		transform: none;
	}
}

/* ============================================================
   Sticky mobile action bar — single-court detail (issue #2)
   ------------------------------------------------------------
   Bottom-fixed bar with Call / Book / Directions pinned to the
   thumb zone on phones. Rendered by
     padelmap_render_card_actions( $post_id, 'stickybar' )
   from single-court.php. Uses the same .pm-action--* button
   BEM as the card actions so a single set of colour rules
   drives both surfaces.

   Layout on mobile is a native-app tab-bar pattern: icon on
   top, label under. Feels more like a first-party mobile UI
   and gives each action its own recognisable pictogram even
   at 320px viewports where the BG "Резервирай" label ellipsizes
   at inline layouts.

   Hidden entirely on ≥769px — the detail hero already carries
   a primary Book CTA and the screen is roomy enough not to
   need a fixed shortcut.
   ============================================================ */
.padelmap-sticky-actions {
	display: none;
}

@media (max-width: 768px) {
	.padelmap-sticky-actions {
		position: fixed;
		bottom: 0;
		left: 0;
		right: 0;
		/* Leaflet's own CSS puts .leaflet-container at z-index 800 and
		   .leaflet-control at z-index 1000 (see assets/vendor/leaflet/
		   leaflet.css). Sit clearly above both so the map + its zoom /
		   attribution controls scroll under the bar, not over it. */
		z-index: 1010;
		display: grid;
		grid-auto-flow: column;
		grid-auto-columns: 1fr;
		gap: 4px;
		padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
		background: rgba(255, 255, 255, 0.94);
		backdrop-filter: saturate(180%) blur(14px);
		-webkit-backdrop-filter: saturate(180%) blur(14px);
		border-top: 1px solid rgba(15, 23, 42, 0.08);
		box-shadow: 0 -2px 12px rgba(15, 23, 42, 0.06);
	}

	/* Stacked icon-over-label (tab-bar style). Overrides the base 36×36
	   chip so the bar's buttons grow to fill their grid track and
	   surface the label for context. */
	.padelmap-sticky-actions .pm-action {
		flex-direction: column;
		width: auto;
		height: auto;
		min-height: 52px;
		padding: 6px 8px;
		gap: 2px;
		border-radius: 10px;
	}
	.padelmap-sticky-actions .pm-action__icon {
		width: 20px;
		height: 20px;
	}
	/* Un-hide label (base .pm-action__label is visually-hidden by default). */
	.padelmap-sticky-actions .pm-action__label {
		position: static;
		width: auto;
		height: auto;
		margin: 0;
		clip: auto;
		font-size: 0.6875rem; /* 11px — tab-bar scale */
		font-weight: 500;
		line-height: 1;
		letter-spacing: 0;
		overflow: hidden;
		text-overflow: ellipsis;
		max-width: 100%;
	}

	/* Push single-court content up so the sticky bar never overlaps the
	   last section (map / footer). Uses safe-area so the padding accounts
	   for iOS home-indicator when a court is opened as PWA / standalone. */
	body.single-court {
		padding-bottom: calc(72px + env(safe-area-inset-bottom));
	}
}

/* ============================================================
   Search-suggest — autocomplete dropdown for the archive search
   ------------------------------------------------------------
   Attaches to the search input inside .padelmap-archive.
   Rendered by assets/js/search-suggest.js. Dropdown is absolute-
   positioned under the input; the existing filter-refetch flow
   under the archive keeps working, so the dropdown is additive.
   ============================================================ */

.padelmap-suggest {
	position: relative;
	/* Match how the field slot behaves in the filter row — grow to fill
	   the search track without breaking the row layout. */
	flex: 1;
	min-width: 0;
	/* Promote the whole wrapper into its own stacking context so the
	   dropdown below can't get pinned under Leaflet's .leaflet-container
	   (z-index 800) or .leaflet-control (1000). isolation is the
	   sledgehammer version of "create a stacking context" that survives
	   even when the parent flex/grid has no z-index of its own. */
	z-index: 1020;
	isolation: isolate;
}

.padelmap-suggest__panel {
	position: absolute;
	top: calc(100% + 6px);
	left: 0;
	right: 0;
	/* Above Leaflet's controls (1000) and the sticky action bar (1010)
	   so the dropdown always wins when both surfaces overlap. */
	z-index: 1020;
	/* Force GPU compositing on the panel. Mobile Chrome promotes the
	   map to its own compositor layer once Leaflet applies transforms
	   after fitBounds (the archive re-runs fitBounds on every filter/
	   search fetch). Composited layers paint in a different order than
	   CSS z-index alone can control — without will-change here the map
	   layer paints ON TOP of the dropdown after refresh, even though
	   z-index says otherwise. Promoting the panel to its own layer
	   restores the correct visual order. transform: translateZ(0) is
	   the older sibling of will-change; both together maximise
	   compatibility across mobile browsers. */
	will-change: transform;
	transform: translateZ(0);
	max-height: 60vh;
	overflow-y: auto;
	background: #fff;
	border: 1px solid rgba(15, 23, 42, 0.08);
	border-radius: 12px;
	box-shadow: 0 12px 28px rgba(15, 23, 42, 0.10), 0 2px 4px rgba(15, 23, 42, 0.04);
	padding: 8px 0;
	font-size: 0.9375rem;
}

.padelmap-suggest__group {
	list-style: none;
	margin: 0;
	padding: 0;
}

.padelmap-suggest__group-heading {
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--padelmap-slate, #4A5163);
	padding: 8px 14px 4px;
}

.padelmap-suggest__item {
	position: relative;
	display: flex;
	align-items: center;
	gap: 4px;
	padding: 4px 8px;
	transition: background-color 120ms ease;
}
.padelmap-suggest__item.is-active {
	background: var(--wp--preset--color--padelmap-cream, #F8F6F0);
}

.padelmap-suggest__link {
	flex: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 6px 8px;
	color: inherit;
	text-decoration: none;
	border-radius: 8px;
}
.padelmap-suggest__link:hover {
	color: inherit;
}

.padelmap-suggest__thumb {
	flex-shrink: 0;
	width: 40px;
	height: 40px;
	border-radius: 8px;
	object-fit: cover;
	background: var(--wp--preset--color--padelmap-cream, #F8F6F0);
}
.padelmap-suggest__thumb--empty {
	background: linear-gradient(135deg, rgba(31,138,63,0.12), rgba(27,79,138,0.12));
}
.padelmap-suggest__pin {
	flex-shrink: 0;
	width: 40px;
	height: 40px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 8px;
	background: var(--wp--preset--color--padelmap-cream, #F8F6F0);
	color: var(--wp--preset--color--padelmap-ocean, #1B4F8A);
}

.padelmap-suggest__body {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.padelmap-suggest__title {
	font-weight: 500;
	color: var(--wp--preset--color--padelmap-charcoal, #1A1F2E);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.padelmap-suggest__meta {
	font-size: 0.75rem;
	color: var(--wp--preset--color--padelmap-slate, #4A5163);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.padelmap-suggest__actions {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	flex-shrink: 0;
	padding-right: 6px;
}

.padelmap-suggest__action {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	border-radius: 8px;
	color: var(--wp--preset--color--padelmap-slate, #4A5163);
	text-decoration: none;
	background: transparent;
	transition: background-color 120ms ease, color 120ms ease;
}
.padelmap-suggest__action:hover,
.padelmap-suggest__action:focus-visible {
	color: var(--wp--preset--color--padelmap-charcoal, #1A1F2E);
	background: rgba(15, 23, 42, 0.06);
	outline: none;
}
.padelmap-suggest__action--call:hover,
.padelmap-suggest__action--call:focus-visible {
	color: var(--wp--preset--color--padelmap-court, #1F8A3F);
	background: rgba(31, 138, 63, 0.10);
}
.padelmap-suggest__action--book:hover,
.padelmap-suggest__action--book:focus-visible {
	color: var(--wp--preset--color--padelmap-ocean, #1B4F8A);
	background: rgba(27, 79, 138, 0.10);
}

.padelmap-suggest__empty {
	padding: 14px 16px;
	margin: 0;
	color: var(--wp--preset--color--padelmap-slate, #4A5163);
	font-size: 0.875rem;
	text-align: center;
}

/* On narrow phones, prioritise the tap-target size and pack the row a bit
   tighter to fit more results without vertical scrolling. */
@media (max-width: 480px) {
	.padelmap-suggest__panel {
		max-height: 70vh;
	}
	.padelmap-suggest__action {
		width: 34px;
		height: 34px;
	}
	.padelmap-suggest__thumb,
	.padelmap-suggest__pin {
		width: 36px;
		height: 36px;
	}
}

/* ============================================================
   Favorites (issue #12) — star toggle
   ------------------------------------------------------------
   Two placements:
     .padelmap-fav-btn--card → corner overlay on any court card.
     .padelmap-fav-btn--hero → inline chip in the single-court
                               hero meta row.

   State is driven entirely by aria-pressed (set by assets/js/
   favorites.js on mount and on click). Default = outline.
   Pressed = filled brand sun (yellow). The same SVG node stays
   in place — we just flip fill via CSS + a subtle pop animation.

   Contract with the archive card: the button is a *sibling* of
   .padelmap-archive__card-media inside .padelmap-archive__card-
   inner. That container is already `position: relative` so the
   button can absolute-position without any extra wrapper. It
   sits at z-index 2, above the stretched-link ::after overlay
   (which is z-index 0) so clicks on the star don't navigate.

   Contract with the pattern card (patterns/court-card.php): the
   featured image + star sit inside a `.padelmap-card__media`
   group; that class gets position:relative below so the star's
   absolute positioning is scoped to the media area, not the
   whole card (which would place it over the body text).
   ============================================================ */

/* Provide the positioning context for the pattern-based card's star
   overlay. The archive card's .card-inner is already positioned. */
.padelmap-card__media {
	position: relative;
}

.padelmap-fav-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: 0;
	padding: 0;
	cursor: pointer;
	color: #fff;
	-webkit-tap-highlight-color: transparent;
	transition:
		transform 120ms cubic-bezier(0.4, 0, 0.2, 1),
		color 160ms ease,
		background-color 160ms ease,
		box-shadow 160ms ease;
}

/* Card variant — top-right corner of the card media. 40px hit target
   with a barely-there tint so the star sits *on* the photo rather than
   in a solid pill. Legibility comes from a drop-shadow on the SVG
   (below) and the white default icon colour, not the background. */
.padelmap-fav-btn--card {
	position: absolute;
	top: 10px;
	right: 10px;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.1);
	color: #fff;
	/* Sit above the stretched-link ::after (z-index 0) so clicks land
	   here, not on the card-wide navigation overlay. */
	z-index: 2;
}
.padelmap-fav-btn--card:hover {
	background: rgba(255, 255, 255, 0.25);
}
/* Give the outline star enough silhouette to read on both dark
   photography and washed-out light photography, without a heavy
   background pill. Drop-shadow follows the star's alpha shape,
   unlike box-shadow which would trace the button's square border. */
.padelmap-fav-btn--card .padelmap-fav-btn__icon {
	filter: drop-shadow(0 1px 2px rgba(15, 23, 42, 0.55));
}

/* Hero variant — same shape as the primary Book CTA so it slots
   into the hero meta row without visual weight imbalance. */
.padelmap-fav-btn--hero {
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.15);
	backdrop-filter: blur(4px);
	-webkit-backdrop-filter: blur(4px);
	border: 1px solid rgba(255, 255, 255, 0.35);
	color: #fff;
}
.padelmap-fav-btn--hero:hover {
	background: rgba(255, 255, 255, 0.28);
}

/* Icon inherits currentColor. In the default (unpressed) state we
   want an outline star — override the inline `fill="currentColor"`
   with fill:none via CSS. When aria-pressed=true the fill snaps
   back to currentColor and the button colour changes to brand sun. */
.padelmap-fav-btn__icon {
	display: block;
	pointer-events: none;
}
.padelmap-fav-btn[aria-pressed="false"] .padelmap-fav-btn__icon path {
	fill: none;
}
/* Pressed = amber. Chosen over the brand's optic-yellow "sun" (#D4F33B)
   because that yellow washes out on the near-white pill behind the card
   button. Amber #E9B22A still reads as "star / favorite" and hits AA
   contrast on both the card pill and the hero's translucent chip. */
.padelmap-fav-btn[aria-pressed="true"] {
	color: #E9B22A;
}
.padelmap-fav-btn[aria-pressed="true"] .padelmap-fav-btn__icon path {
	fill: currentColor;
}

/* Focus ring for keyboard users. Match the card title's focus ring
   colour so both surfaces read as part of the same UI system. */
.padelmap-fav-btn:focus-visible {
	outline: 2px solid var(--wp--preset--color--padelmap-court, #1F8A3F);
	outline-offset: 2px;
}

/* Pop animation on toggle — the JS adds .padelmap-fav-btn--pop right
   after flipping aria-pressed, and removes it on animationend via CSS
   (see @keyframes below). Kept subtle so it reads as feedback, not spectacle. */
.padelmap-fav-btn--pop {
	animation: padelmapFavPop 260ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes padelmapFavPop {
	0%   { transform: scale(1); }
	40%  { transform: scale(1.22); }
	100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
	.padelmap-fav-btn,
	.padelmap-fav-btn--pop {
		transition: none;
		animation: none;
	}
}
