/*
 * Ruhler Community Resource Directory -- public stylesheet.
 *
 * Enqueued only where it is needed (see
 * CommunityResourceDirectory\Presentation\Assets): on an individual
 * location page, and on a page/post containing the
 * [crd_locator_finder] shortcode. Every selector here is scoped under
 * .crd-locator-finder or .crd-locator-single, both collision-resistant,
 * plugin-specific class names, so nothing here can leak into the
 * surrounding theme, other plugins' markup, or ordinary posts/pages.
 *
 * Custom properties are declared on the two root wrapper classes (not
 * globally on :root) so they never leak either. Colors that aren't
 * carrying a specific status meaning use CSS system colors/currentColor
 * as neutral fallbacks -- these already track the surrounding theme's
 * (and the visitor's OS/browser) light or dark mode automatically,
 * without assuming any particular theme's own custom properties exist.
 * No external fonts, frameworks, or icon libraries are loaded.
 *
 * Token names below follow docs/PRODUCT_DESIGN_SYSTEM.md §§4-6. Every
 * value here is the exact value already in use before the token
 * refactor -- this file introduces names, it does not change any
 * rendered value.
 */

.crd-locator-finder,
.crd-locator-single {
	/* Structural colors (design system §4.3) */
	--crd-border: color-mix(in srgb, currentColor 20%, transparent);
	--crd-surface-muted: color-mix(in srgb, currentColor 5%, transparent);
	--crd-focus-ring: currentColor;

	/* Status colors (design system §4.1) */
	--crd-status-open: #1a7f37;
	--crd-status-opens-later: #9a6700;
	--crd-status-closed: #b42318;
	--crd-status-unavailable: #57606a;

	/* Spacing scale (design system §5) */
	--crd-space-1: 0.25rem;
	--crd-space-2: 0.5rem;
	--crd-space-3: 0.75rem;
	--crd-space-4: 1rem;
	--crd-space-5: 1.5rem;
	--crd-space-6: 2rem;
	--crd-space-8: 3rem;

	/* Borders, radii (design system §6) */
	--crd-radius-sm: 0.25rem;
	--crd-radius-md: 0.5rem;
	--crd-radius-pill: 999px;
	--crd-border-width: 1px;
	--crd-border-width-emphasis: 2px;

	/* Not yet named by the design system; retained as-is */
	--crd-surface-color: color-mix(in srgb, currentColor 4%, Canvas);
	--crd-transition-fast: 150ms ease-in-out;

	max-width: 60rem;
	margin: 0 auto;
	box-sizing: border-box;
	color: inherit;
}

.crd-locator-finder {
	/* Lets the integrated map/list results workspace (see
	   .crd-locator-finder__results below) respond to this component's
	   own rendered width, not the viewport -- correct in a narrow
	   sidebar or a multi-column theme layout the same as it is at any
	   viewport size, and correct independently for each shortcode
	   instance if more than one appears on a page. */
	container-type: inline-size;
	container-name: crd-locator-finder;
}

.crd-locator-single {
	max-width: 42rem;
	padding-block: var(--crd-space-4);
}

.crd-locator-finder *,
.crd-locator-finder *::before,
.crd-locator-finder *::after,
.crd-locator-single *,
.crd-locator-single *::before,
.crd-locator-single *::after {
	box-sizing: border-box;
}

@media (prefers-reduced-motion: reduce) {
	.crd-locator-finder *,
	.crd-locator-single * {
		transition: none !important;
		animation: none !important;
	}
}

.crd-locator-finder a:focus-visible,
.crd-locator-single a:focus-visible,
.crd-locator-finder button:focus-visible,
.crd-locator-single button:focus-visible,
.crd-locator-finder select:focus-visible,
.crd-locator-single select:focus-visible {
	outline: var(--crd-border-width-emphasis) solid var(--crd-focus-ring);
	outline-offset: 2px;
}

.crd-locator-finder a,
.crd-locator-single a {
	text-underline-offset: 0.15em;
}

/* -- Shared: status text (never color alone) ---------------------------- */

.crd-locator-status {
	display: inline-flex;
	align-items: center;
	gap: var(--crd-space-1);
	font-weight: 600;
	margin-block: var(--crd-space-1) var(--crd-space-4);
}

.crd-locator-status svg {
	width: 1em;
	height: 1em;
	flex-shrink: 0;
}

.crd-locator-status--open_now { color: var(--crd-status-open); }
.crd-locator-status--closed_today { color: var(--crd-status-closed); }
.crd-locator-status--opens_later { color: var(--crd-status-opens-later); }
.crd-locator-status--hours_unavailable { color: var(--crd-status-unavailable); }

/* -- Shared: service-category badges ------------------------------------ */

.crd-locator-badge-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--crd-space-2);
}

.crd-locator-badge {
	display: inline-block;
	border: 1px solid var(--crd-border);
	border-radius: var(--crd-radius-pill);
	padding: var(--crd-space-1) var(--crd-space-2);
	font-size: 0.85em;
	line-height: 1.6;
	background: var(--crd-surface-color);
}

/* -- Shared: address ------------------------------------------------------ */

.crd-locator-address {
	display: flex;
	align-items: flex-start;
	gap: var(--crd-space-1);
	font-style: normal;
	line-height: 1.6;
}

.crd-locator-address svg {
	width: 1em;
	height: 1em;
	flex-shrink: 0;
	margin-top: 0.2em;
}

/* -- Shared: Call / Visit website actions ------------------------------- */

.crd-locator-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
	margin-block: var(--crd-space-2);
}

.crd-locator-action {
	display: inline-flex;
	align-items: center;
	gap: var(--crd-space-1);
	border: 1px solid var(--crd-border);
	border-radius: var(--crd-radius-md);
	padding: var(--crd-space-2) var(--crd-space-4);
	text-decoration: none;
	transition: background-color var(--crd-transition-fast), border-color var(--crd-transition-fast);
}

.crd-locator-action svg {
	width: 1em;
	height: 1em;
	flex-shrink: 0;
}

.crd-locator-action:hover,
.crd-locator-action:focus-visible {
	background: var(--crd-surface-color);
}

/* -- Shared: weekly hours ------------------------------------------------- */

.crd-locator-hours-list {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 0.35rem 1.25rem;
	margin: 0;
}

.crd-locator-hours-list dt {
	font-weight: 600;
}

.crd-locator-hours-list dd {
	margin: 0;
}

/* -- Shared: schedule-exceptions notice ---------------------------------- */

.crd-locator-exceptions {
	border: 1px solid var(--crd-border);
	border-left-width: 4px;
	border-radius: var(--crd-radius-md);
	padding: var(--crd-space-3) var(--crd-space-4);
	background: var(--crd-surface-color);
}

.crd-locator-exceptions-list {
	list-style: none;
	margin: var(--crd-space-2) 0 0;
	padding: 0;
	display: grid;
	gap: var(--crd-space-2);
}

/* -- Shared: card / surface -------------------------------------------------- */

.crd-locator-surface {
	border: 1px solid var(--crd-border);
	border-radius: var(--crd-radius-md);
	padding: var(--crd-space-4);
	background: var(--crd-surface-color);
}

/* =========================================================================
   Individual location page (.crd-locator-single)
   ========================================================================= */

.crd-locator-single__back-link {
	display: inline-block;
	margin-bottom: var(--crd-space-4);
}

.crd-locator-single__name {
	margin-top: 0;
}

.crd-locator-single__section {
	margin-block: var(--crd-space-5);
}

.crd-locator-single__section h2 {
	margin-bottom: var(--crd-space-2);
}

.crd-locator-single__summary {
	display: grid;
	gap: var(--crd-space-5);
}

@media (min-width: 640px) {
	.crd-locator-single__summary {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 480px) {
	.crd-locator-single .crd-locator-hours-list {
		grid-template-columns: 1fr;
		gap: 0;
	}

	.crd-locator-single .crd-locator-hours-list dd {
		margin-bottom: var(--crd-space-2);
	}
}

/* =========================================================================
   Public directory list (.crd-locator-finder)
   ========================================================================= */

.crd-locator-finder__heading {
	margin-top: 0;
}

.crd-locator-finder__controls {
	display: flex;
	flex-wrap: wrap;
	gap: var(--crd-space-5);
	align-items: flex-start;
	margin-bottom: 1.25rem;
	padding: var(--crd-space-3) var(--crd-space-4);
	border: 1px solid var(--crd-border);
	border-radius: var(--crd-radius-md);
	background: var(--crd-surface-color);
}

/* Primary group: search is the toolbar's main action, given the most
   width and first position (design system §10). A single full-width
   child (the search field, label+input+button together) so its own
   height is driven only by that field's content, not stray wrapping. */
.crd-locator-finder__controls-primary {
	display: flex;
	flex: 2 1 20rem;
}

/* Secondary group: service filter, Open Now, and Clear filters read as
   one visually secondary cluster next to the primary search group --
   a grouping change only, per design system §10. */
.crd-locator-finder__controls-secondary {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--crd-space-3);
	flex: 1 1 20rem;
}

.crd-locator-finder__field {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
}

.crd-locator-finder__field--search {
	width: 100%;
}

/* Search input and its submit button share one row and one comfortable
   height: default flex stretch makes the button match the input's
   height exactly, rather than the browser's own, shorter default
   button sizing. */
.crd-locator-finder__search-row {
	display: flex;
	align-items: stretch;
	gap: var(--crd-space-2);
}

.crd-locator-finder__field label {
	font-weight: 600;
	font-size: 0.9em;
}

.crd-locator-finder__field select {
	padding: 0.4rem 0.6rem;
	border: 1px solid var(--crd-border);
	border-radius: 0.35rem;
	background: Canvas;
	color: inherit;
}

.crd-locator-finder__search-input {
	padding: 0.4rem 0.6rem;
	border: 1px solid var(--crd-border);
	border-radius: 0.35rem;
	background: Canvas;
	color: inherit;
	font: inherit;
	flex: 1 1 0%;
	min-width: 6rem;
}

/* Its own rule (not a change to the shared .crd-locator-action links
   used elsewhere for Call/Visit website) so the search button never
   grows/shrinks, never wraps its label, and matches the input's own
   font -- native <button> elements don't inherit font by default the
   way <a> elements already do. */
.crd-locator-finder__search-submit {
	flex: 0 0 auto;
	font: inherit;
	white-space: nowrap;
}

.crd-locator-finder__field--checkbox {
	flex-direction: row;
	align-items: center;
	gap: var(--crd-space-2);
}

/* A fixed-service instance's smallest-appropriate-treatment
   replacement for the visitor-facing dropdown (design system §9-10):
   plain text, not a control, so nothing about it looks selectable or
   changeable. */
.crd-locator-finder__field--fixed-service {
	justify-content: flex-end;
}

.crd-locator-finder__fixed-service {
	font-weight: 600;
	font-size: 0.9em;
}

.crd-locator-finder__field--checkbox label {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	font-weight: 600;
	font-size: 0.9em;
}

/* "Clear filters" as a small button-styled control (design system §9's
   one public button-like family), not a bare link. */
.crd-locator-finder__clear-filters {
	display: inline-flex;
	align-items: center;
	align-self: flex-end;
	padding: var(--crd-space-1) var(--crd-space-3);
	border: 1px solid var(--crd-border);
	border-radius: var(--crd-radius-pill);
	background: Canvas;
	color: inherit;
	text-decoration: none;
	font-weight: 600;
	font-size: 0.9em;
	transition: background-color var(--crd-transition-fast);
}

.crd-locator-finder__clear-filters:hover,
.crd-locator-finder__clear-filters:focus-visible {
	background: var(--crd-surface-color);
}

/* Beacon Packet 5: the locate/restore buttons and status text read as
   one grouped component (design system §9/§10) -- a single
   level-0-elevation container (border + radius-md + padding, matching
   the card/toolbar treatment elsewhere) rather than three
   incidental-looking controls sharing only a flex gap.

   `inline-flex`, not `flex`: a `flex` container is still a block box
   that stretches to its parent's full content width regardless of how
   little it actually holds -- with both buttons `hidden` until
   JS/geolocation feature-detection confirms Near Me is available (and
   the status paragraph empty until there is something to announce),
   that produced a large, nearly empty bordered panel around a single
   small pill (Packet 5 visual-correction finding). `inline-flex`
   shrink-wraps this idle, button-only state to its own content's width.

   `max-width: min(32rem, 100%)`, not `max-width: 100%` alone: once the
   status paragraph holds a real sentence (loading/success/error copy),
   shrink-to-fit sizing asks "how wide would this prefer to be laid out
   on one line, unwrapped" to size the box itself -- and once that
   unwrapped preferred width exceeds the available row, shrink-to-fit's
   result is simply the *entire* available width (confirmed identically
   in Chromium and WebKit), reproducing the same full-width empty-feeling
   panel this component exists to avoid, even though the actual wrapped
   text only needs a couple of lines at a modest width. Capping at 32rem
   forces that wrap to happen at a width the pill cluster still looks
   intentional at, while `100%` keeps that cap from ever exceeding a
   narrow viewport. */
.crd-locator-finder__near-me {
	display: inline-flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--crd-space-3);
	max-width: min(32rem, 100%);
	margin-bottom: var(--crd-space-4);
	padding: var(--crd-space-3) var(--crd-space-4);
	border: var(--crd-border-width) solid var(--crd-border);
	border-radius: var(--crd-radius-md);
	background: var(--crd-surface-color);
}

/* Author CSS always outranks the UA stylesheet's own `[hidden]` rule
   at equal specificity, so the `display: inline-flex` above would
   otherwise keep rendering this wrapper (as empty bordered chrome)
   despite the `hidden` attribute assets/js/near-me.js controls it
   with -- see templates/finder-list.php's progressive-enhancement
   contract comment. */
.crd-locator-finder__near-me[hidden] {
	display: none;
}

.crd-locator-finder__near-me-button,
.crd-locator-finder__near-me-restore {
	cursor: pointer;
	padding: var(--crd-space-2) var(--crd-space-4);
	border: var(--crd-border-width) solid var(--crd-border);
	border-radius: var(--crd-radius-pill);
	/* Design system §9's one public button family: a filled pill,
	   subtly tinted (not a bare outline) so it reads as a real control
	   without introducing a hardcoded color -- color-mix against
	   currentColor keeps it theme-adaptive in both light and dark
	   contexts, exactly like this file's other structural colors. */
	background: color-mix(in srgb, currentColor 8%, Canvas);
	color: inherit;
	font: inherit;
	font-weight: 600;
	transition: background-color var(--crd-transition-fast), color var(--crd-transition-fast);
}

.crd-locator-finder__near-me-button:hover,
.crd-locator-finder__near-me-restore:hover {
	background: color-mix(in srgb, currentColor 14%, Canvas);
}

.crd-locator-finder__near-me-status {
	font-size: 0.9em;
	margin: 0;
	/* No flex-basis: a percentage flex-basis makes an inline-flex
	   container's own shrink-to-fit width calculation assume this item
	   alone needs the container's full available width (confirmed in
	   both Chromium and WebKit), reproducing the exact full-width
	   "empty panel" look this component exists to avoid the moment
	   status text becomes non-empty. A plain flex item wraps onto its
	   own line naturally via flex-wrap once it and the buttons no
	   longer fit one line, without that intrinsic-sizing pitfall. */
	min-width: 12rem;
}

.crd-locator-finder__near-me-status:empty {
	display: none;
}

.crd-locator-finder__distance {
	font-weight: 600;
	margin-block: 0;
}

.crd-locator-finder__count {
	font-weight: 600;
	margin-block: 0 var(--crd-space-4);
}

/* Container-aware, not viewport-based: auto-fit measures the grid's own
   available width (whatever that is in the active theme/context), so
   the column count already adapts without a media query. minmax(min(100%,
   20rem), 1fr) both sets a readable minimum card width and guarantees
   that minimum can never exceed the container itself, so a single
   column never overflows a narrower-than-20rem context (see the mobile
   width acceptance check). At this component's own ~60rem cap (see the
   shared root above), that minimum yields two columns rather than the
   previous three-narrow-plus-one-orphan result; a genuinely wider
   container will still open up a third column and beyond on its own. */
.crd-locator-finder__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--crd-space-5);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
	align-items: start;
}

.crd-locator-finder__card {
	border: 1px solid var(--crd-border);
	border-radius: var(--crd-radius-md);
	padding: var(--crd-space-5);
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: var(--crd-space-3);
	overflow-wrap: break-word;
	word-break: break-word;
}

/* Selected card/marker relationship (design system §12; map is enabled
   only when a location has coordinates, see the selected-indicator
   span's own render condition in templates/finder-list.php): a
   border-width change plus the visible, persistent "Selected on map"
   text/icon cue below -- never color alone, and never lost once the
   pointer or keyboard focus moves elsewhere, matching
   .crd-locator-finder__marker--selected's own non-color-only treatment
   on the map side. */
.crd-locator-finder__item--selected .crd-locator-finder__card {
	border-width: var(--crd-border-width-emphasis);
	border-color: var(--crd-focus-ring);
	background: var(--crd-surface-muted);
}

.crd-locator-finder__name {
	margin-top: 0;
	margin-bottom: 0;
}

.crd-locator-finder__name-link {
	color: inherit;
	text-decoration-thickness: 1px;
}

.crd-locator-finder__selected-indicator {
	display: inline-flex;
	align-items: center;
	gap: var(--crd-space-1);
	font-size: 0.875em;
	font-weight: 600;
	margin: 0;
}

.crd-locator-finder__selected-indicator svg {
	width: 1em;
	height: 1em;
}

.crd-locator-finder__description {
	margin-block: var(--crd-space-1);
}

.crd-locator-finder__services-label {
	font-weight: 600;
}

/* Extra separation (on top of the card's own default gap) marks the
   two remaining boundaries the visual review called weak: services are
   a distinct "categorization" concern from the contact facts above
   them, and Hours reads as the card's closing, expandable section.
   Scoped to the finder card specifically so the single-location page's
   own (differently laid out) use of these same shared classes is
   unaffected. */
.crd-locator-finder__card .crd-locator-badge-list {
	margin-top: var(--crd-space-2);
}

.crd-locator-finder__schedule {
	margin-top: var(--crd-space-3);
}

.crd-locator-finder__schedule summary {
	cursor: pointer;
	font-weight: 600;
}

/* Design system §11: icon-paired, level-0 container using
   --crd-surface-muted -- the same visual language already established
   for the map's own failure fallback (.crd-locator-finder__map-fallback
   below) -- for all three empty/failure states this class covers
   (nothing published, filtered to zero, and the new provider-failure
   state), so an intentional state reads as intentional instead of a
   placeholder dashed box. */
.crd-locator-finder__empty-state {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--crd-space-2);
	padding: var(--crd-space-5);
	border-radius: var(--crd-radius-md);
	background: var(--crd-surface-muted);
	text-align: center;
	font-size: 1.05em;
}

.crd-locator-finder__empty-state svg {
	width: 1.5rem;
	height: 1.5rem;
}

.crd-locator-finder [hidden] {
	display: none !important;
}

/* Visible-on-focus skip link, offered only when there is a map to skip
   (see its render condition in templates/finder-list.php) -- the
   standard clip-based hidden-but-focusable pattern, never `display:
   none`/`visibility: hidden`, which would remove it from the tab order
   entirely instead of merely hiding it visually until reached. */
.crd-locator-finder__skip-map {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.crd-locator-finder__skip-map:focus {
	position: static;
	display: inline-block;
	width: auto;
	height: auto;
	margin: 0 0 var(--crd-space-3);
	padding: var(--crd-space-2) var(--crd-space-4);
	overflow: visible;
	clip: auto;
	white-space: normal;
	background: var(--crd-surface-color);
	color: inherit;
	border: var(--crd-border-width) solid var(--crd-border);
	border-radius: var(--crd-radius-sm);
}

/* -- Integrated map/list results workspace (map enabled only; see
      templates/finder-list.php's $map_enabled branch) -----------------
   One flex container, no border/background of its own (avoiding nested
   panel chrome -- the map and each card already carry their own
   border), so the map and list read as two halves of one results area
   rather than two unrelated boxes. Map-panel precedes list-panel in
   document order (per docs/MAP_AND_DISCOVERY_ARCHITECTURE.md's
   list-is-canonical principle, the list itself is unaffected -- this
   only changes where the *map* sits relative to it), so visual order,
   DOM order, and keyboard tab order all agree once the container query
   below places them side by side; stacked (the default, narrow-width
   case), that same order simply reads top to bottom. */
.crd-locator-finder__results {
	display: flex;
	flex-direction: column;
	gap: var(--crd-space-5);
	margin-bottom: var(--crd-space-5);
}

.crd-locator-finder__map-panel {
	display: flex;
	flex-direction: column;
	gap: var(--crd-space-2);
}

.crd-locator-finder__map-heading {
	margin: 0;
	font-size: 1em;
}

.crd-locator-finder__map-context {
	margin: 0;
	font-size: 0.875em;
}

.crd-locator-finder__list-panel {
	/* Without this, a flex item's default min-width: auto can keep it
	   from ever shrinking below its content's own intrinsic width (long
	   card text/URLs), which would fight the side-by-side layout below
	   instead of letting the card grid reflow to the narrower column. */
	min-width: 0;
}

/* Side by side once this component itself (not the viewport) is wide
   enough for both halves to be genuinely useful -- correct inside a
   narrow theme sidebar or multi-column layout the same as at any
   viewport width. Map on the left, list on the right, matching DOM
   order exactly (no `order` property is used, so keyboard/visual/DOM
   order can never disagree). */
@container crd-locator-finder (min-width: 40rem) {
	.crd-locator-finder__results {
		flex-direction: row;
		align-items: flex-start;
	}

	.crd-locator-finder__map-panel {
		flex: 1 1 44%;
		/* Sticky, not fixed: this keeps the map connected to whichever
		   cards are currently in view instead of scrolling out of sight
		   after the first card, while still stopping naturally at the
		   end of .crd-locator-finder__results (a sticky element cannot
		   escape its containing block, so it can never drift over the
		   footer -- it simply stops being "stuck" once the results
		   workspace itself scrolls past). `top` offsets by
		   --wp-admin--admin-bar--height, the custom property WordPress
		   core itself sets on <html> only while the admin toolbar is
		   shown (and already uses for its own `scroll-padding-top`) --
		   0px when logged out or the bar is hidden, so the map is never
		   hidden behind it either way, with a small extra gap for
		   breathing room. Narrow/stacked widths never opt into this
		   rule at all (see the plain, non-sticky declaration above),
		   matching the approved mobile layout exactly. */
		position: sticky;
		top: calc(var(--wp-admin--admin-bar--height, 0px) + var(--crd-space-3));
	}

	.crd-locator-finder__list-panel {
		flex: 1 1 56%;
	}

	/* One readable column on the (now narrower) list side, rather than
	   the standalone, map-disabled grid's own auto-fit multi-column
	   behavior -- scoped to this container only, so the map-disabled
	   directory view is completely unaffected. */
	.crd-locator-finder__list-panel .crd-locator-finder__list {
		grid-template-columns: 1fr;
	}
}

/* -- Optional map (only rendered when an administrator has enabled and
      configured a tile provider; see Admin\MapSettings) --------------- */

.crd-locator-finder__map {
	/* No margin-top: this now sits inside .crd-locator-finder__map-panel,
	   below the "Map view" heading and context text, spaced by that
	   panel's own `gap` -- an extra top margin here would double up with
	   it. */
	height: 24rem;
	max-width: 100%;
	border: 1px solid var(--crd-border);
	border-radius: var(--crd-radius-md);
	background: var(--crd-surface-color);
	position: relative;
	overflow: hidden;
	/* Narrow-screen overflow fix (Beacon Packet 5's known-defect scope):
	   Leaflet's own internal zoom-animation proxy element (`.leaflet-proxy`,
	   appended inside this container by Leaflet itself) is a legitimate,
	   by-design part of every Leaflet map -- at rest it always carries a
	   CSS transform scaled to the current zoom level (2^(zoom-1), so a
	   moderately zoomed-in map already means a four- or five-figure scale
	   factor), confirmed directly on this component in testing. `overflow:
	   hidden` above already clips it in most engines, but `contain: layout
	   paint` is the correct, purpose-built CSS primitive for this exact
	   case: it makes this component's own box an unconditional hard
	   clip/containing-block boundary for every descendant Leaflet creates
	   inside it, independent of engine-specific `overflow` edge cases at
	   extreme transform values, and without touching any ancestor -- scoped
	   to this one plugin-owned component only, never html/body/a theme
	   container. */
	contain: layout paint;
	/* Loading skeleton (design system §11): a quiet, static-by-default
	   diagonal pattern fills the container the instant it renders,
	   before Leaflet has initialized or any tile has painted over it --
	   a visible "this is loading" cue rather than a blank/empty box.
	   Real tile images are opaque, so this is naturally and fully
	   covered once tiles load; the failure-state fallback below also
	   paints its own opaque surface over it. The subtle shift version is
	   wrapped in prefers-reduced-motion: no-preference (design system
	   §14); reduced motion keeps the same pattern static instead of
	   moving. */
	background-image: repeating-linear-gradient(
		135deg,
		var(--crd-surface-muted) 0,
		var(--crd-surface-muted) 0.75rem,
		transparent 0.75rem,
		transparent 1.5rem
	);
	background-size: 4rem 4rem;
}

@media (prefers-reduced-motion: no-preference) {
	.crd-locator-finder__map {
		animation: crd-locator-map-loading-shift 2.4s linear infinite;
	}
}

@keyframes crd-locator-map-loading-shift {
	from {
		background-position: 0 0;
	}
	to {
		background-position: 4rem 0;
	}
}

.crd-locator-finder__map-fallback {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--crd-space-2);
	text-align: center;
	padding: var(--crd-space-4);
	margin: 0;
	/* Matches the empty-state container treatment (design system §11):
	   an opaque muted surface, so this fully covers the loading pattern
	   above once a failure is confirmed, rather than layering failure
	   text over a still-visible "loading" background. */
	background: var(--crd-surface-muted);
}

.crd-locator-finder__map-fallback svg {
	width: 1.5rem;
	height: 1.5rem;
}

/* Selected marker (the map-side half of the card/marker relationship
   above): a size increase plus a soft glow, never color alone. Leaflet
   positions/stacks every marker via its own inline `style.transform`/
   `style.zIndex` (set directly on the element, so an external
   stylesheet's `transform`/`z-index` would simply be overridden by it,
   design-system `!important` ban notwithstanding) -- `scale` is a
   distinct CSS property from `transform` precisely so this can compose
   with Leaflet's own positioning instead of fighting it. */
.crd-locator-finder__marker--selected {
	scale: 1.2;
	filter: drop-shadow(0 0 0.25rem var(--crd-focus-ring));
}

@media (prefers-reduced-motion: no-preference) {
	.crd-locator-finder__marker--selected {
		transition: scale var(--crd-transition-fast);
	}
}

@media (max-width: 480px) {
	.crd-locator-finder__controls {
		flex-direction: column;
		align-items: stretch;
	}

	/* flex: none resets the row-axis grow/shrink/basis set for the wide
	   desktop layout -- without it, the same values are reinterpreted
	   against the vertical axis once each container becomes a column,
	   stretching the primary group and the search field far taller than
	   their content. */
	.crd-locator-finder__controls-primary,
	.crd-locator-finder__controls-secondary {
		flex: none;
		flex-direction: column;
		align-items: stretch;
	}

	/* Search input and button stack as their own full-width controls
	   (matching the rest of the mobile toolbar) instead of sharing the
	   desktop's single row. */
	.crd-locator-finder__search-row {
		flex-direction: column;
		align-items: stretch;
	}

	.crd-locator-finder__search-submit {
		width: 100%;
	}

	.crd-locator-finder__clear-filters {
		align-self: stretch;
		justify-content: center;
	}

	.crd-locator-finder__map {
		height: 18rem;
	}
}

/* A wide-layout map needs real presence, not the same shallow strip the
   narrow, stacked layout uses -- 24rem next to a multi-card column read
   as a small preview image with a large empty gap beneath it once the
   map (sticky) stopped scrolling and the list (much taller) kept going.
   30rem gives it a substantial, primary-tool footprint on an ordinary
   desktop viewport while still comfortably fitting beside the card
   column. `min(...)` keeps the short-viewport safeguard from Packet 5's
   desktop integration: on a genuinely short viewport the second operand
   (driven by the real available height) becomes smaller than 30rem and
   wins instead, so the map shrinks rather than overflowing past the
   viewport, exactly as before -- only the normal-height baseline grew.
   Placed after (not inside) the base .crd-locator-finder__map rule
   above, deliberately: both selectors have equal specificity, and CSS
   resolves that by source order, so this override would otherwise be
   silently ignored regardless of whether the container condition
   matches. Narrow/stacked widths never enter this container query at
   all, so the approved mobile map height (18rem, in the existing
   @media (max-width: 480px) rule) is completely untouched. */
@container crd-locator-finder (min-width: 40rem) {
	.crd-locator-finder__map {
		height: min(30rem, calc(100vh - var(--wp-admin--admin-bar--height, 0px) - 8rem));
	}
}
