/**
 * eKlektiv. — the Listora skin: every rule of ours that styles something INSIDE a
 * Listora block (the directory's search bar, grid and cards; a listing's page; our
 * own sections drawn inside a listing).
 *
 * WHY THIS IS ITS OWN FILE (1 Oct 2026, the Listora 1.9.0 bump).
 *
 * Listora 1.9.0 prints all of its front-end CSS inside the cascade layer `listora`
 * (Theme_Defenses::layer_listora_styles(), includes/core/class-theme-defenses.php)
 * and ships one unlayered rule, assets/css/listora-isolation.css:
 *
 *     :where(.listora-block) :where(*):not(...):not(#\#):not(#\#) { all: revert-layer; }
 *
 * at specificity (2,0,0). It rolls every property of every element inside a
 * Listora block back to what the `listora` layer says, so a theme's rules stop
 * applying there. That is the vendor's intent (their owner decision of 25 Sep
 * 2026), and it would have taken this whole skin with it: these rules lived in
 * directories.css, unlayered, at (0,1,0) to (0,3,2).
 *
 * The vendor's seam is the filter `wb_listora_layered_style_bases`: a stylesheet
 * whose URL starts with a listed base is printed inside the same layer, where it
 * competes with Listora's own rules by specificity and order exactly as it did
 * before. functions.php adds THIS FOLDER (assets/css/listora/) as a base, so only
 * this file is layered; directories.css stays unlayered for everything outside a
 * Listora block (the page title band, Groups, Events, Articles).
 *
 * On Listora 1.8.0 the filter does not exist, nothing is layered, and this file
 * behaves as the same rules did inside directories.css.
 *
 * RULES FOR THIS FILE
 *  - A rule belongs here when its selector, with any `:has(...)` argument set
 *    aside, names a `.listora-*` class (other than `.listora-page-wrap`, which is
 *    the template wrapper OUTSIDE the blocks) or one of our classes drawn inside
 *    a listing or a card (`.ek-service-times`, `.ek-hosted`, `.ek-lgroups`,
 *    `.ek-campuses`, `.ek-group-count`, `.ek-programme-policy`).
 *  - Custom properties cross the layer boundary untouched, so the `--ek-dir-*`
 *    and `--ds-*` tokens used here are still declared in directories.css and
 *    style.css.
 *  - `!important` inside a layer still beats an inline style, and beats every
 *    unlayered rule.
 *  - Loaded after `eklektiv-directories`, in the same order it always had.
 *  - ONE EXCEPTION stays in directories.css, unlayered: the `appearance:
 *    base-select` block for the open dropdown list. Inside the layer, under
 *    Listora 1.9.0's isolation rule, it hangs the browser (measured 1 Oct 2026;
 *    the note beside it says how). Do not move it here without re-testing.
 *
 * Kill switch: remove the `wb_listora_layered_style_bases` filter in
 * functions.php (the rules then lose to Listora 1.9.0's isolation rule).
 * Re-verify on every Listora bump: the filter name, the layer name `listora`,
 * and that `.listora-block` is still the isolation root.
 */

/* ── The house base, inside a Listora block ────────────────────────────────
   style.css has three element-level rules that reached everything on the page,
   Listora's blocks included: the box-sizing reset, the heading face, and form
   controls inheriting their type. Under Listora 1.9.0's isolation rule they stop
   at the block's edge, so they are restated here, inside the layer, at the same
   specificity they had (`:where()` adds none): Listora's own class rules win
   wherever it says something, and these fill in only where it says nothing,
   exactly as before. Keep them in step with style.css. */
:where(.listora-block),
:where(.listora-block) *,
:where(.listora-block) *::before,
:where(.listora-block) *::after {
	box-sizing: inherit;
}

:where(.listora-block) :is(h1, h2, h3, h4, h5, h6) {
	font-family: var(--ek-font);
	font-weight: 700;
	line-height: 1.2;
	text-wrap: balance;
}

:where(.listora-block) :is(button, input, optgroup, select, textarea) {
	font-family: inherit;
	font-size: inherit;
	line-height: inherit;
}

/* Listora (/listings) */
.listora-card__title,
.listora-row-title,
.listora-search__type-tab,
.listora-search__submit,
.listora-search__toggle-btn,
.listora-search__filter-label,
.listora-grid__count,
.listora-btn {
	font-family: var(--ek-dir-display);
}

html body .listora-card__title,
html body .listora-row-title,
html body .listora-search .listora-search__type-tab,
html body .listora-search .listora-search__submit,
html body .listora-search .listora-search__toggle-btn,
html body .listora-search .listora-search__filter-label,
html body .listora-grid .listora-grid__count {
	font-family: var(--ek-dir-display);
}

/* ── Listora's map block with no tile source (Kevin, 11 Sep 2026) ──────────
   Listora ships no default map tiles on purpose (OpenStreetMap's public tiles
   are not licensed for plugin-scale use), so an unset tile source renders a
   "The map is not available." band above the listings
   (blocks/listing-map/render.php:288-300, .listora-map__unconfigured inside the
   block wrapper). Hide the block in that state and give the space back. It is
   self-healing: set a tile source in Listora → Settings → Maps and the real map
   renders, so the notice (and this rule) no longer match. */
.listora-map-wrapper:has(.listora-map__unconfigured) { display: none !important; }

/* Fallback for browsers without :has(): at least drop the notice itself. */
.listora-map__unconfigured { display: none !important; }

/* Chips and Filters on one line, the same move Groups makes above: Listora
 * renders them as siblings (`__type-tabs` then `__actions-row`) inside
 * `.listora-search`, so a wrapping row puts them together without touching the
 * markup. */
.listora-search {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ek-dirhead-gap);
	margin-block-end: var(--ek-dirhead-gap);
}

.listora-search > * {
	flex: 1 1 100%;
	min-width: 0;
}

.listora-search > .listora-search__type-tabs {
	flex: 1 1 320px;
	margin-block-start: 0;
}

.listora-search > .listora-search__actions-row {
	flex: 0 0 auto;
}

/* The toolbar was a 66px white band holding one sentence and two controls. */
.listora-grid__toolbar {
	padding-block: 0;
	margin-block: var(--ek-dirhead-gap) 0;
	align-items: center;
}

.listora-grid__count {
	font-size: 13px;
	color: var(--ek-dir-hint);
}

/* Listora's rating badge on a listing photo, in dark.
 *
 * `.listora-card__rating` (blocks/listing-card/style.css:172-187) is a fixed
 * `rgba(0,0,0,0.7)` scrim in BOTH themes, but its text is
 * `var(--listora-fg-inverse)` — "text on an inverted surface" — which Listora
 * flips from #ffffff to #121212 in dark. So in dark the "5.0" became near-black
 * on near-black and vanished, while light was fine.
 *
 * Fixed on the element, not the token: --listora-fg-inverse is used 82 times
 * as text but 28 times as a BACKGROUND, so lifting it would repaint fills all
 * over the directory. White, because the scrim under it never changes.
 *
 * For the record, Listora gets its trigger right: it follows the site toggle
 * via [data-bx-mode] and deliberately does not honour a bare OS dark
 * preference (listora-base.css:95-101), so no toggle bridge is needed here.
 */
[data-bn-theme="dark"] .listora-card__rating,
[data-theme="dark"] .listora-card__rating,
[data-bx-mode="dark"] .listora-card__rating {
	color: #FFFFFF;
}

/* `!important` because Listora declares both inline on the pill, and only an
   important declaration outranks an inline one. */
.listora-badge-pill {
	--badge-bg:   var(--ds-accent) !important;
	--badge-text: #FFFFFF !important;
}

html:is([data-theme="dark"], [data-bx-mode="dark"]) .listora-badge--type {
	color: color-mix(in srgb, var(--listora-type-color, var(--listora-primary)) 40%, #FFFFFF);
}

/* Search placeholders on the vendors' own bars: Eventonomy and Listora print
   #757575 (3.19 dark, 3.62 night). Dana's ink2 clears 4.5 on every surface. */
.listora-search__input::placeholder,
.listora-input::placeholder {
	color: var(--ds-ink2) !important; /* Eventonomy sets its placeholder with !important. */
	opacity: 1;
}

/* ── Our sections on a listing (Service times, Programmes here / Where it runs, Groups at …) ──
   `wb_listora_before_detail_tabs` fires INSIDE Listora's two-column grid
   (.listora-detail__content: main + a 320px sidebar) but BEFORE .listora-detail__main,
   so each section became a grid item of its own: it took the main column and pushed
   Listora's tabs into the sidebar's 320px (Kevin, 30 Sep 2026: "they are pushing the
   button strip off to the right"). Each takes a full row instead, and the tabs and the
   sidebar keep their columns underneath. */
.listora-detail__content > .ek-service-times,
.listora-detail__content > .ek-hosted,
.listora-detail__content > .ek-lgroups {
	grid-column: 1 / -1;
	min-width: 0;
}

.ek-service-times > h3,
.ek-hosted > h3,
.ek-lgroups > h3 {
	margin: 0 0 8px;
	font-size: 1rem;
	color: var(--ek-dir-heading);
}

.ek-hosted__line,
.ek-hosted__list,
.ek-lgroups__list {
	margin: 0;
	padding: 12px 16px;
	list-style: none;
	background: var(--ek-dir-surface);
	border: 1px solid var(--ek-dir-line);
	border-radius: 12px;
	overflow-wrap: anywhere;
}

.ek-hosted__list li + li,
.ek-lgroups__row + .ek-lgroups__row {
	margin-top: 8px;
	padding-top: 8px;
	border-top: 1px solid var(--ek-dir-line);
}

.ek-hosted__town,
.ek-lgroups__kind,
.ek-lgroups__meets {
	color: var(--ek-dir-muted);
	font-size: .875rem;
}

.ek-lgroups__name { font-weight: 600; }

/* Service times as a row on the church's Worship tab (30 Sep 2026): one line per day. */
.ek-service-times--tab {
	list-style: none;
	margin: 0;
	padding: 0;
}

.ek-service-times--tab .ek-service-times__row + .ek-service-times__row {
	margin-top: 4px;
}

.ek-service-times--tab .ek-service-times__day {
	font-weight: 600;
	margin-right: .5em;
}

/* A main church's campuses, a row on its Organization tab (1 Oct 2026): one per line. */
.ek-campuses {
	list-style: none;
	margin: 0;
	padding: 0;
}

.ek-campuses li + li {
	margin-top: 4px;
}

/* "Service Times" at the end of a church's description opens the Worship tab (1 Oct 2026).
   A full-height tap target; the tab strip it scrolls to stops short of the screen's edge. */
.ek-service-times-link {
	margin: 8px 0 0;
}

.ek-service-times-link a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	font-weight: 600;
}

.listora-detail__tabs {
	scroll-margin-top: 16px;
}

/* "3 groups" on a church's or ministry's card and beside its title (1 Oct 2026):
   plain words in the text's own ink, no badge, no colour of its own. */
.ek-group-count {
	color: var(--ek-dir-strong);
	font-size: .875rem;
	font-weight: 600;
	line-height: 1.4;
	white-space: nowrap;
}

.ek-group-count--card {
	display: block;
	margin-top: 8px;
}

.ek-group-count--title {
	display: inline-flex;
	align-items: center;
}

/* A listing's buttons on a phone (Kevin, 1 Oct 2026: "so big they take up most of
   the screen and prevent the user from seeing the actual listing info", then "On
   mobile we don't need the labels in those buttons"). Listora stacks them
   full-width, one per row: six rows, 309px at 375. Here they are one row of icons,
   44px tall, sharing the width equally however many there are.
   The words are still in the page for a screen reader: they are drawn at no size,
   never removed. */
@media (max-width: 767px) {
	.listora-detail__actions {
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		gap: 6px;
	}

	.listora-detail__actions > .listora-btn {
		flex: 1 1 0;
		justify-content: center;
		align-items: center;
		gap: 0;
		width: auto;
		min-width: 0;
		min-height: 44px;
		padding: 0;
		font-size: 0;
		line-height: 0;
	}

	.listora-detail__actions > .listora-btn svg {
		flex: none;
		width: 22px;
		height: 22px;
	}

	/* How many have saved it stays readable beside the bookmark. */
	.listora-detail__actions > .listora-btn .listora-detail__favorite-count:not([hidden]) {
		margin-left: 4px;
		font-size: .75rem;
		line-height: 1;
	}

	/* With no word to change, the pressed state is drawn: a wash behind Compare when the listing is in it. */
	.listora-detail__actions > .listora-btn[aria-pressed="true"] {
		background: var(--ek-dir-teal-wash);
	}
}

/* A saved listing's bookmark is filled, at every width. */
.listora-detail__actions > .listora-btn.is-favorited svg {
	fill: currentColor;
}

/* The list a Listora dropdown opens (Kevin, 1 Oct 2026: "all types drop down needs
   styling help", then, in Night, "looks weird": navy choices inside a white box).
   The browser paints the open list's own box with the CLOSED picker's background
   colour. Listora leaves the type picker in the search bar see-through, so its box
   was white in every scheme, whatever the choices inside it were given.
   So the picker itself gets the bar's own ground (the scheme's surface: closed, it
   looks exactly as it did), and the choices get the same ground and the scheme's
   ink. `background-color`, never `background`, which would wipe the caret
   (playbook §2); `html body` in front to out-specify Listora's sheet. */
html body .listora-search .listora-search__select {
	background-color: var(--ds-surface);
}

.listora-select option,
.listora-select optgroup {
	background-color: var(--ds-surface);
	color: var(--ds-ink);
}

/* Save shows no number (Kevin, 1 Oct 2026: "Remove the count of saves from all
   listings"). Sponsor\ListingIcons takes it out of what Listora renders; this is
   for a number Listora's own script writes back in after a tap. Out-specified and
   `!important` because the script also clears the node's `hidden`. */
html body .listora-favorite-btn__count,
html body .listora-detail__favorite-count {
	display: none !important;
}
