/* ============================================================
   Courses and workshops listing - layout, results and the bespoke
   panel (archive-ldm_offering.php, template-parts/listing/). List v2:
   docs/notes/listing-pages.md 3.4-3.8 (desktop) and 4.4-4.6 (mobile).
   The level pills: listing-levels.css; the form, sidebar and filter
   panel: listing-filters.css; the paging band: listing-pagination.css.

   Layout
   - From 1024px: a three-track grid - the Cream sidebar (to the
     viewport's left edge; its content on the container's left edge,
     258px wide, 27px clear of the Cream's edge: 365px at 1440), the
     White results column (25px after the Cream, at most 948px: x
     390-1338 at 1440, as drawn) and the container's right margin.
     The sidebar's content is sticky (below).
   - Below 1024px: one column on the container. With JS the sidebar is
     hidden and its form lives in the filter panel; without JS - or
     when listing.js cannot run or load (.is-static, set by the script
     or by the script tag's onerror, inc/enqueue.php) - the sidebar
     shows above the results as a Cream block.
   - Results: the shared offering cards. The grid follows its own width
     (container queries): one inset card under 560px (318px at 402, the
     homepage's 42px inset; capped at 416px), two columns from 560px,
     three from 780px with 24px gaps (cards of about 244px and up; the
     card's CTA drops its format word, "View" alone, below 310px), the designed 36px gaps
     from 900px (292px at 1440). On a desktop that is three cards from
     about 1222px wide (two at 1024-1221: about 285-370px each), on
     tablets three from about 868px.
   - The count line (not designed): 14px Grey Dark between the pills and
     the cards, inside the designed 52px gap.
   - Bespoke panel: the shared CTA panel in its List v2 size
     (template-parts/components/cta-panel.php, cta-panel.css); here only
     its place: 66px under the cards, the results column's width.
   ============================================================ */

.listing {
	--listing-side-content: 258px;   /* search field and filter groups (design x 77-334 at 1440) */
	--listing-side-pad: 27px;        /* content to the Cream column's edge (x 334-365) */
	--listing-main-gap: 25px;        /* Cream edge to the results (x 365-390) */
	--listing-main-max: 948px;       /* results column at 1440 (x 390-1337) */
	--listing-top: 64px;             /* section top to the level heading row (phones) */
	--listing-bottom: 56px;          /* bespoke panel to the section's end (phones; 70 desktop) */
	background-color: var(--color-surface);
}

/* ---------- Sidebar: a Cream block above the results (no JS, < 1024) ---------- */

.listing__sidebar {
	background-color: var(--color-surface-sidebar);
}

.listing__sidebar-inner {
	width: 100%;
	max-width: calc(var(--listing-side-content) + 2 * var(--gutter) + 120px);
	margin-inline: auto;
	padding: 40px var(--gutter);
}

/* With JS the form is in the filter panel below 1024px (unless the
   script could not run or load: .is-static). */
html.has-js .listing:not(.is-static) .listing__sidebar {
	display: none;
}

/* ---------- Results column ---------- */

.listing__main {
	width: 100%;
	max-width: calc(var(--container-max) + 2 * var(--gutter));
	margin-inline: auto;
	padding: var(--listing-top) var(--gutter) var(--listing-bottom);
}

.listing-results,
.listing-bespoke,
.listing-notice {
	max-width: var(--listing-main-max);
}

/* Why a booking could not be made (inc/booking.php: the date's page was
   taken down). Not designed: the course page's reason box. */
.listing-notice {
	margin-bottom: 24px;
	padding: 14px 18px;
	border-left: 4px solid var(--color-error);
	background-color: var(--dates-surface-alt);
	color: var(--color-text);
	font-size: var(--fs-small);
	font-weight: var(--fw-medium);
	line-height: var(--lh-body);
}

.listing-notice p {
	margin: 0;
}

.listing-results {
	container: listing-results / inline-size;
}

/* The count: a quiet caption, 18px under the pills (20 from 1024px) and
   10px over the cards (the designed 52px gap: 49 on phones, 51 on
   desktops). Focus lands on the hidden heading before it after a page
   change: from the keyboard, the count shows the ring. */
.listing-results__head {
	margin: 18px 0 10px;
}

.listing-results__count {
	color: var(--color-text-muted);
	font-size: var(--fs-small);
	line-height: var(--lh-body);
}

.listing-results__title:focus {
	outline: none;
}

.listing-results__head:has(.listing-results__title:focus-visible) .listing-results__count {
	outline: 2px solid var(--color-focus-light);
	outline-offset: 4px;
	border-radius: 2px;
}

/* While a new state loads (listing.js): the cards dim, after a beat so
   quick answers do not flicker. Opacity only, so nothing moves. */
.listing-results__body {
	transition: opacity 0.2s ease;
}

.listing.is-loading .listing-results__body {
	opacity: 0.5;
	transition-delay: 0.15s;
}

.listing-results__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	justify-items: center;
	gap: var(--gap-cards);
	margin: 0;
	padding: 0 max(0px, var(--inset-card-mobile) - var(--gutter));
	list-style: none;
}

/* A grid cell, so the card inside stretches to the row height. */
.listing-results__item {
	display: grid;
	width: 100%;
	max-width: 26rem;
}

@container listing-results (min-width: 560px) {
	.listing-results__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		padding: 0;
	}

	.listing-results__item {
		max-width: none;
	}
}

@container listing-results (min-width: 780px) {
	.listing-results__grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 24px;
	}
}

@container listing-results (min-width: 900px) {
	.listing-results__grid {
		gap: var(--gap-cards);
	}
}

/* ---------- Empty state (not designed) ---------- */

.listing-empty {
	padding: 32px 24px;
	border: var(--border-hairline) solid var(--color-border);
	border-radius: var(--radius-md);
	background-color: var(--color-surface-warm);
}

.listing-empty__title {
	color: var(--color-heading);
	font-size: var(--fs-ui-lg);
	font-weight: var(--fw-semibold);
	line-height: var(--lh-body);
}

.listing-empty__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px 32px;
	margin: 16px 0 0;
	padding: 0;
	list-style: none;
}

.listing-empty__link {
	color: var(--color-link);
}

.listing-empty__link:focus-visible .icon {
	color: var(--color-arrow-hover-on-light);
}

@media (hover: hover) {
	.listing-empty__link:hover .icon {
		color: var(--color-arrow-hover-on-light);
	}
}

.listing-empty__link:focus-visible {
	outline-color: var(--color-focus-light);
}

/* ---------- Bespoke panel: its place (its look: cta-panel.css) ---------- */

.listing-bespoke {
	margin-top: 66px;
}

/* ============================================================
   Tablet
   ============================================================ */

@media (min-width: 768px) {
	.listing {
		--listing-top: 58px;
		--listing-bottom: 64px;
	}
}

/* ============================================================
   Desktop: sidebar beside the results
   ============================================================ */

@media (min-width: 1024px) {
	.listing {
		--listing-edge: max(var(--gutter), (100% - var(--container-max)) / 2);
		--listing-sticky-gap: 24px;
		--listing-focus-room: 8px;
		--listing-top: 70px;
		--listing-bottom: 70px;
		display: grid;
		grid-template-columns:
			calc(var(--listing-edge) + var(--listing-side-content) + var(--listing-side-pad))
			minmax(0, 1fr)
			var(--listing-edge);
	}

	html.has-js .listing:not(.is-static) .listing__sidebar {
		display: block;
	}

	/* The form's top lines up with the level pills: the results column's
	   top padding plus the level heading row (listing-levels.css: 45px
	   and 19px). */
	.listing__sidebar {
		padding-top: calc(var(--listing-top) + 45px + 19px - var(--listing-focus-room));
		padding-bottom: var(--listing-bottom);
	}

	/* Sticky below the header - below the floating header while it shows
	   (navigation.js 3), moving with it at its speed. The form is about
	   850px tall (868 with the padding): in a window under about 900px
	   tall (about 995px while the header floats; more under the WordPress
	   toolbar) the sidebar scrolls on its own - the designer's "sticky
	   scrolling", with every control still reachable. The 8px padding
	   keeps focus rings inside its scroll area. */
	.listing__sidebar-inner {
		position: sticky;
		top: calc(var(--toolbar-fixed-h) + var(--listing-sticky-gap) - var(--listing-focus-room));
		width: calc(var(--listing-side-content) + var(--listing-side-pad) + var(--listing-focus-room));
		max-width: none;
		max-height: calc(100vh - var(--toolbar-fixed-h) - 2 * var(--listing-sticky-gap) + 2 * var(--listing-focus-room));
		margin: 0 0 0 auto;
		padding: var(--listing-focus-room) var(--listing-side-pad) var(--listing-focus-room) var(--listing-focus-room);
		overflow-y: auto;
		scrollbar-width: thin;
		scrollbar-color: var(--color-scrollbar) transparent;
		transition:
			top var(--header-slide-duration) var(--ease-out-cubic),
			max-height var(--header-slide-duration) var(--ease-out-cubic);
	}

	.site-header.is-floating ~ main .listing__sidebar-inner {
		top: calc(var(--toolbar-fixed-h) + var(--header-bar-h) + var(--listing-sticky-gap) - var(--listing-focus-room));
		max-height: calc(100vh - var(--toolbar-fixed-h) - var(--header-bar-h) - 2 * var(--listing-sticky-gap) + 2 * var(--listing-focus-room));
	}

	.listing__main {
		grid-column: 2;
		max-width: none;
		margin: 0;
		padding: var(--listing-top) 0 var(--listing-bottom) var(--listing-main-gap);
	}

	.listing-levels {
		max-width: var(--listing-main-max);
	}

	.listing-results__head {
		margin-top: 20px;
	}
}

/* Reduced motion: the header only fades (header.css), so the sidebar
   moves up only once a leaving header has faded out - never under it -
   and down at once when the header comes back. */
@media (min-width: 1024px) and (prefers-reduced-motion: reduce) {
	.listing__sidebar-inner {
		transition-property: top, max-height;
		transition-duration: 0s;
		transition-delay: var(--header-slide-duration);
	}

	.site-header.is-floating ~ main .listing__sidebar-inner {
		transition-delay: 0s;
	}
}
