/*
 * Archive filter bar.
 *
 * No surrounding frame — the controls carry their own 2px #262626 borders, and
 * whitespace does the separating. Square corners and the site's own type, so
 * this reads as part of the site rather than a widget bolted onto it.
 *
 * Four controls on one line: Search · Dates · Type · Free.
 */

.oad-af {
	/*
	 * The bar is drawn from one pair of colours -- what the lines and type are
	 * made of, and what they sit on -- so the dark variant is a swap of the two
	 * rather than a second set of rules. Everything below takes its colour from
	 * these; nothing in the bar states a colour of its own.
	 */
	/* Read from the block first, then the theme, then a literal. Two names, not
	 * one: an element's own declaration beats a value inherited from its
	 * wrapper, so if the bar declared the same property the block writes, the
	 * block could never reach it. */
	--oad-af-ink: var( --oad-af-ink-set, var( --wp--preset--color--foreground, #262626 ) );
	--oad-af-paper: var( --oad-af-paper-set, var( --wp--preset--color--background, #fff ) );

	/* The parts that can be coloured separately. Each falls back to the pair
	 * above, so the bar still reads as one thing until somebody decides
	 * otherwise -- and so the dark variant only has to swap two values. */
	--oad-af-text: var( --oad-af-text-set, var( --oad-af-ink ) );
	--oad-af-border: var( --oad-af-border-set, var( --oad-af-ink ) );
	--oad-af-field: var( --oad-af-field-set, var( --oad-af-paper ) );

	--oad-af-line: 2px solid var( --oad-af-border );

	/* Ink at reduced strength: placeholders, weekday initials, past dates. */
	--oad-af-muted: #8a8a8a;
	--oad-af-faint: #b6b6b6;
	--oad-af-fainter: #d0d0d0;

	/* The wash behind a hovered option or a selected date range. */
	--oad-af-wash: #f2f2f2;
	--oad-af-hairline: #e2e2e2;
	--oad-af-shadow: rgba( 38, 38, 38, 0.12 );

	/* No gap beneath the bar: it and the results sit inside the header's dark
	 * group, so any margin here shows through as a black strip. */
	margin: 0;

	/* Stays put while the list scrolls, directly below the header's own
	 * visible edge -- which moves as the peek-a-boo menu tucks away. Turned
	 * off from the block, in which case the map pins itself straight to the
	 * header instead: see syncStickyOffset(). */
	position: sticky;
	top: var(--oad-af-header-bottom, 0px);
	z-index: 20;
	color: var( --oad-af-text );

	/* Typography is a pair too: the family, and one size everything else is
	 * measured against. Every font-size in the bar and its calendar is in em,
	 * so changing this one value scales the whole control set together rather
	 * than leaving the labels behind. */
	--oad-af-font: var( --oad-af-font-set, "Jost", sans-serif );
	--oad-af-size: var( --oad-af-size-set, 1rem );

	font-family: var( --oad-af-font );
	font-size: var( --oad-af-size );
}

/*
 * The dark variant, chosen on the block.
 *
 * A swap of the pair, not a second set of rules -- nothing in the bar states a
 * colour of its own, so inverting ink and paper inverts the whole thing,
 * controls, dropdowns and calendar included.
 *
 * The greys are restated rather than reused. They are steps away from the
 * ground, not fixed values: a wash that reads as "just off white" becomes
 * invisible on charcoal, and a placeholder grey that is legible on white is
 * not on it.
 */
/* Doubled class, not one: the rule that paints the bar's bottom border is a
 * plain `.oad-af` further down the file, so a single class here ties on
 * specificity and loses on source order. */
.oad-af.oad-af--dark {
	--oad-af-ink: var( --wp--preset--color--background, #fff );
	--oad-af-paper: var( --wp--preset--color--foreground, #262626 );
	--oad-af-muted: #9d9d9d;
	--oad-af-faint: #7a7a7a;
	--oad-af-fainter: #5c5c5c;
	--oad-af-wash: #3d3d3d;
	--oad-af-hairline: #4a4a4a;
	--oad-af-shadow: rgba( 0, 0, 0, 0.4 );

	/* The rule under the bar has nothing left to do here: the change from
	 * charcoal to the page's own white is the boundary. Matched to the bar
	 * rather than removed, so its height -- which the sticky offsets are
	 * measured from -- is the same in both schemes. */
	border-bottom-color: var( --oad-af-paper );
}

/* Scrolls away with the page when the block asks it to. */
.oad-af.oad-af--unpinned {
	position: static;
}

.oad-af__row {
	display: flex;
	flex-wrap: nowrap;
	gap: var( --oad-af-gap );
	align-items: center;

	/* Named, because the search field's width is measured against it: the
	 * search stops at the halfway mark of the row, and everything before it
	 * counts towards that half. */
	--oad-af-gap: 1.1rem;

	/* What sits ahead of the search field. Nothing, unless the view switcher is
	 * there -- it is a fixed 48px square. */
	--oad-af-lead: 0px;
}

.oad-af__row:has( .oad-af__toggle ) {
	--oad-af-lead: calc( 48px + var( --oad-af-gap ) );
}

.oad-af__field {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	margin: 0;
	min-width: 0; /* let flex actually shrink these */
}

/* Without the location control, the bar is as it always was: the search takes
 * whatever the other controls leave. */
.oad-af__field--grow {
	flex: 1 1 16rem;
	min-width: 8rem;
}

.oad-af__field--dates,
.oad-af__field--types {
	flex: 0 1 11rem;
	min-width: 9rem;
}

/* ---- with the location control present -------------------------------------
 *
 * A fourth control needs room the row did not have, so the search is pinned to
 * the halfway mark and the three dropdowns share the other half. Scoped to
 * rows that actually carry it -- on a page with no location control the bar
 * keeps its original proportions rather than leaving half the row empty.
 *
 * Matched on the field, so both of its states count: the list of places, and
 * the "Set location" link that stands in the same slot when nowhere has been
 * chosen. They occupy identical space, so the layout must not change between
 * them -- the bar would visibly re-proportion itself as you moved between a
 * located page and an unlocated one.
 *
 * A basis rather than a grow factor: with `flex: 1` the search would take
 * whatever the others happened to leave, so the split would move every time a
 * control appeared -- and Free and the type dropdown are both conditional. */
.oad-af__row:has( .oad-af__field--place ) .oad-af__field--grow {
	flex: 0 1 calc( 50% - var( --oad-af-lead ) );
}

/* Basis 0 so they divide the space itself rather than the space left over
 * after their content, which is what keeps them the same width as each other
 * despite holding labels of very different lengths. */
.oad-af__row:has( .oad-af__field--place ) .oad-af__field--dates,
.oad-af__row:has( .oad-af__field--place ) .oad-af__field--types,
.oad-af__field--place {
	flex: 1 1 0;
	min-width: 8rem;
}

.oad-af__label {
	font-size: 0.7em;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	font-weight: 600;
	white-space: nowrap;
}

.oad-af input[type="search"],
.oad-af input[type="date"],
.oad-af__dd-summary {
	font: inherit;

	/* The one place in this bar that does not scale with --oad-af-size.
	 * At 0.95em these rendered 15.2px, and iOS Safari zooms the page when a
	 * field under 16px takes focus -- which here throws the visitor out of a
	 * filtered list. The token is pinned at 1rem for exactly that reason, so
	 * it cannot drift back under the threshold. The summary keeps the same
	 * size so the three controls still read as a set. */
	font-size: var( --wp--custom--input-size, 1rem );
	color: inherit;
	padding: 0.6rem 0.75rem;
	border: var(--oad-af-line);
	border-radius: 0;
	background: var( --oad-af-field );
	min-height: 48px;
	width: 100%;
	-webkit-appearance: none;
	appearance: none;
	box-sizing: border-box;
	display: flex;
	align-items: center;
}

.oad-af input[type="date"] {
	min-width: 0;
}

.oad-af input[type="search"]::placeholder {
	color: var( --oad-af-muted );
}

/*
 * Focus.
 *
 * The text fields draw nothing at all. They used to take the same ring as the
 * buttons below -- 3px held 2px clear of the field, so a second frame appeared
 * around the search box the moment it was clicked into, which is what it looked
 * like: an extra box, detached, where a moment before there was none.
 *
 * Everything here is still stated rather than left alone. Removing the ring is
 * not the same as removing the rule: left to itself the browser draws its own
 * default, and Bootstrap adds a blue glow on top, so the outline has to be
 * turned off explicitly and the border pinned to the colour it already is --
 * otherwise taking one frame away just lets two others in.
 *
 * Note :focus-visible would not have helped: browsers match it on a text input
 * however the focus arrived, mouse click included, so the ring would have gone
 * on showing in exactly the case it was complained about.
 */
.oad-af input[type="search"]:focus,
.oad-af input[type="date"]:focus {
	outline: none;
	border-color: var( --oad-af-border );
	box-shadow: none;
}

/*
 * The buttons keep theirs, in the site's own ink -- and on :focus-visible, so
 * it answers the keyboard and stays out of the way of the mouse. Left alone the
 * browser draws a blue that belongs to neither the site nor the theme, and is
 * the one colour on the bar that is nobody's decision.
 */
.oad-af input[type="checkbox"]:focus-visible,
.oad-af__toggle:focus-visible,
.oad-af__clear:focus-visible,
.oad-af__go:focus-visible {
	outline: 3px solid var( --oad-af-border );
	outline-offset: 2px;
	border-color: var( --oad-af-border );

	/* Bootstrap gives focused controls a blue glow of its own. */
	box-shadow: none;
}

/* ---- dropdowns (dates + types) ---- */

.oad-af__dd {
	position: relative;
	width: 100%;
}

.oad-af__dd-summary {
	cursor: pointer;
	list-style: none;
	justify-content: space-between;
	gap: 0.5rem;
	white-space: nowrap;
	overflow: hidden;
}

.oad-af__dd-summary::-webkit-details-marker {
	display: none;
}

.oad-af__dd-summary::after {
	content: "";
	flex: none;
	width: 0;
	height: 0;
	border-left: 5px solid transparent;
	border-right: 5px solid transparent;
	border-top: 6px solid var(--oad-af-ink);
}

.oad-af__dd[open] .oad-af__dd-summary::after {
	transform: rotate( 180deg );
}

.oad-af__dd-summary:focus-visible {
	outline: 3px solid var(--oad-af-ink);
	outline-offset: 2px;
}

.oad-af__dd-panel {
	position: absolute;
	z-index: 30;
	top: calc( 100% + 4px );
	left: 0;
	min-width: 100%;
	width: max-content;
	max-width: 20rem;
	max-height: 18rem;
	overflow-y: auto;
	background: var( --oad-af-field );
	border: var(--oad-af-line);
	padding: 0.5rem;
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
}

.oad-af__dd-panel--dates {
	gap: 0.75rem;
	padding: 0.85rem;
	overflow: visible; /* the native calendar must not be clipped */
	max-height: none;
}

.oad-af__sub {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
	margin: 0;
	min-width: 11rem;
}

.oad-af__dd-option {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.45rem 0.5rem;
	font-size: 0.9em;
	line-height: 1.25;
	cursor: pointer;
	margin: 0;
	min-height: 40px;
}

.oad-af__dd-option:hover,
.oad-af__dd-option:focus-within {
	background: var( --oad-af-wash );
}

.oad-af__dd-option input {
	width: 1.05rem;
	height: 1.05rem;
	accent-color: var(--oad-af-ink);
	margin: 0;
	flex: none;
}

/* ---- location -----------------------------------------------------------
 *
 * Just a list of places one step below wherever the visitor is. The rows are
 * links, not options: choosing one navigates to that place's own page, the
 * same way GeoDirectory's header switcher does. */

.oad-af__dd-panel--place {
	gap: 0.5rem;
	padding: 0.5rem;
	width: 16rem;
	max-width: 88vw;
	max-height: 26rem;

	/* Hung from its right edge, not its left. This is the last of the three
	 * dropdowns, so opening it left-aligned pushed it past the edge of the
	 * page. */
	left: auto;
	right: 0;
}

.oad-af__place-find {
	flex: none;
}

/* "Set location", shown in the same slot when nowhere has been chosen yet.
 *
 * It already carries .oad-af__dd-summary, so the box, the height and the caret
 * come from the same rules as the dropdowns beside it and cannot drift from
 * them. Only the things an anchor brings with it need undoing. */
.oad-af__setloc {
	text-decoration: none;
	color: inherit;
}

.oad-af__setloc:hover,
.oad-af__setloc:focus {
	text-decoration: none;
	color: inherit;
	background: var( --oad-af-field );
}

.oad-af__setloc:focus-visible {
	outline: 3px solid var( --oad-af-border );
	outline-offset: 2px;
}

/* The list scrolls, not the whole panel: the filter box above it stays put
 * while the places move under it. */
.oad-af__place-list {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	overflow-y: auto;
	min-height: 0;
}

.oad-af__place-option {
	display: block;
	padding: 0.45rem 0.5rem;
	font-size: 0.9em;
	line-height: 1.25;
	min-height: 40px;
	margin: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;

	/* These are links, and the theme underlines links in body copy. In a list
	 * of options they should read as options. */
	color: inherit;
	text-decoration: none;
}

.oad-af__place-option:hover,
.oad-af__place-option:focus-visible {
	background: var( --oad-af-wash );
	color: inherit;
	text-decoration: none;
}

.oad-af__place-option:focus-visible {
	outline: 3px solid var( --oad-af-border );
	outline-offset: -3px;
}

/* Where the visitor already is. Only ever set on the neighbourhood list, which
 * shows siblings -- so it marks the one they are standing in. */
.oad-af__place-option.is-current {
	font-weight: 600;
	box-shadow: inset 3px 0 0 var( --oad-af-accent );
}

/* A class rather than the hidden attribute, for the same reason the Clear
 * button uses one: Bootstrap's reboot makes [hidden] unoverridable. */
.oad-af__place-option.is-hidden {
	display: none;
}

.oad-af__place-empty {
	margin: 0;
	padding: 0.75rem 0.5rem;
	font-size: 0.9em;
	color: var( --oad-af-muted );
}

.oad-af__place-empty[hidden] {
	display: none;
}

/* ---- free ---- */

.oad-af__field--check {
	flex: none;
	flex-direction: row;
	align-items: center;
	gap: 0.5rem;
	min-height: 48px;
	cursor: pointer;
	white-space: nowrap;
	font-size: 0.95em;
}

.oad-af__field--check input {
	width: 1.2rem;
	height: 1.2rem;
	accent-color: var(--oad-af-ink);
	margin: 0;
}

/* ---- buttons ---- */

.oad-af__go {
	flex: none;
	font: inherit;
	font-size: 0.85em;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	padding: 0.6rem 1rem;
	min-height: 48px;
	border: var(--oad-af-line);
	background: var( --oad-af-ink );
	color: var( --oad-af-paper );
	cursor: pointer;
	border-radius: 0;
}

.oad-af__clear {
	flex: none;
	font: inherit;
	font-size: 0.85em;
	background: none;
	border: none;
	border-bottom: 2px solid var(--oad-af-ink);
	padding: 0 0 0.1rem;
	cursor: pointer;
	color: inherit;
	white-space: nowrap;
}

.oad-af__go[hidden] {
	display: none;
}

/* Clear keeps its space when inactive, so the row does not resize the moment a
 * filter is applied or removed. visibility (not display) also keeps it out of
 * the tab order while invisible. */
.oad-af__clear.is-invisible {
	visibility: hidden;
	pointer-events: none;
}

/* ---- results ---- */

.oad-af-results {
	transition: opacity 0.15s ease;
}

.oad-af-results[aria-busy="true"] {
	opacity: 0.55;
}

@media ( prefers-reduced-motion: reduce ) {
	.oad-af-results {
		transition: none;
	}
}

/* The content column here is ~770px, not the viewport, so the controls shrink
 * into it rather than being wrapped by a viewport breakpoint. */
@media ( max-width: 780px ) {
	.oad-af__row {
		flex-wrap: wrap;
		gap: 0.85rem;
	}

	/* The view switcher and the search share the first line: the search takes
	 * exactly what is left of it, which is also what pushes the date and type
	 * dropdowns onto the next line rather than letting them squeeze in and
	 * crush the search field to nothing. */
	.oad-af__row {
		--oad-af-gap: 0.85rem;
	}

	/* The halfway split is a desktop idea: in a column this narrow the search
	 * takes the whole of its line and the dropdowns wrap below it.
	 *
	 * Written with the same `:has()` as the desktop rule deliberately. Without
	 * it these score (0,1,0) against that rule's (0,3,0) and lose *inside their
	 * own media query* -- the search would sit at 50% on a phone, which is
	 * exactly the layout this breakpoint exists to undo. */
	.oad-af__field--grow,
	.oad-af__row:has( .oad-af__field--place ) .oad-af__field--grow {
		flex: 1 1 calc( 100% - 48px - 0.85rem );
	}

	.oad-af__field--dates,
	.oad-af__field--types,
	.oad-af__field--place,
	.oad-af__row:has( .oad-af__field--place ) .oad-af__field--dates,
	.oad-af__row:has( .oad-af__field--place ) .oad-af__field--types {
		flex: 1 1 10rem;
	}

	/* Back to hanging from the left. The right-hand anchor is there because on
	 * a wide bar this control sits near the right edge -- but once the row
	 * wraps it is the left-hand item on its line, and anchoring right pushed
	 * the panel 84px off the side of the screen. */
	.oad-af__dd-panel--place {
		left: 0;
		right: auto;
	}

	.oad-af__go {
		flex: 1 1 100%;
	}
}

/* ---- range calendar ---------------------------------------------------- */

.oad-af__dd-panel--dates {
	padding: 0;
}

.oad-af__cal {
	width: 19rem;
	max-width: 88vw;
	padding: 0.9rem;
	display: flex;
	flex-direction: column;
	gap: 0.8rem;
}

.oad-cal__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
}

.oad-cal__group {
	display: flex;
	align-items: center;
	gap: 0.15rem;
}

.oad-cal__title {
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	font-size: 0.95em;
	min-width: 3.2rem;
	text-align: center;
	font-variant-numeric: tabular-nums;
}

.oad-cal__nav {
	font: inherit;
	font-size: 1.05em;
	line-height: 1;
	background: none;
	border: none;
	cursor: pointer;
	color: inherit;
	padding: 0.3rem 0.4rem;
	border-radius: 0;
}

.oad-cal__nav:hover {
	background: var( --oad-af-wash );
}

.oad-cal__nav:focus-visible {
	outline: 2px solid var(--oad-af-ink);
	outline-offset: 1px;
}

.oad-cal__grid {
	display: grid;
	grid-template-columns: repeat( 7, 1fr );
	gap: 2px 0; /* no column gap, so the range band is continuous */
}

.oad-cal__dow {
	text-align: center;
	font-size: 0.66em;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var( --oad-af-muted );
	padding-bottom: 0.35rem;
}

.oad-cal__day {
	font: inherit;
	font-size: 0.85em;
	font-variant-numeric: tabular-nums;
	aspect-ratio: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	background: none;
	border: none;
	cursor: pointer;
	color: inherit;
	padding: 0;
	position: relative;
	border-radius: 0;
}

/* Selected days are excluded rather than relying on source order: the hover
 * selector scores higher than `.oad-cal__day.is-start`, so without this the
 * grey hover paints over the accent and a freshly clicked date looks unselected
 * until the pointer moves off it. */
.oad-cal__day:hover:not( :disabled ):not( .is-start ):not( .is-end ) {
	background: var( --oad-af-wash );
}

.oad-cal__day.is-outside {
	color: var( --oad-af-faint );
}

.oad-cal__day.is-past {
	color: var( --oad-af-fainter );
	cursor: default;
}

/* The band between the two ends. Square and edge-to-edge so consecutive
 * days read as one continuous run. */
.oad-cal__day.is-between {
	background: var( --oad-af-wash );
}

.oad-cal__day.is-start,
.oad-cal__day.is-end {
	background: var(--oad-af-accent, #262626);
	color: #1b1a18;
	font-weight: 700;
}

.oad-cal__day:focus-visible {
	outline: 2px solid var(--oad-af-ink);
	outline-offset: -2px;
}

.oad-cal__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.6rem;
	padding-top: 0.2rem;
}

.oad-cal__reset {
	font: inherit;
	font-size: 0.82em;
	background: none;
	border: 2px solid var(--oad-af-ink);
	padding: 0.45rem 0.9rem;
	cursor: pointer;
	color: inherit;
	border-radius: 0;
	min-height: 40px;
}

.oad-cal__done {
	font: inherit;
	font-size: 0.82em;
	font-weight: 600;
	background: var(--oad-af-ink);
	color: var( --oad-af-paper );
	border: 2px solid var(--oad-af-ink);
	padding: 0.45rem 0.9rem;
	cursor: pointer;
	border-radius: 0;
	min-height: 40px;
	flex: 1;
	text-align: center;
}

.oad-cal__reset:hover,
.oad-cal__done:hover {
	opacity: 0.85;
}

@media ( max-width: 480px ) {
	.oad-af__cal {
		width: 17rem;
	}
}

/* Second level inside the Type dropdown. */
.oad-af__dd-sub {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
	border-left: 2px solid var( --oad-af-hairline );
	margin: 0 0 0.25rem 0.85rem;
	padding-left: 0.35rem;
}

.oad-af__dd-sub[hidden] {
	display: none;
}

.oad-af__dd-option--sub {
	font-size: 0.85em;
	min-height: 34px;
	padding: 0.3rem 0.45rem;
}

/* The bar now sits under the site header, so it spans the page.
 *
 * The horizontal inset is measured off the site logo by the script, so the
 * first control starts exactly where the logo does and the two read as one
 * column. The clamp is only the fallback for before that runs, or if the
 * header ever stops having a logo to measure. */
.oad-af {
	padding: 1rem var( --oad-af-inset, clamp( 0.85rem, 4vw, 2rem ) );
	background: var( --oad-af-paper );

	/* The one rule under the bar. Nothing directly beneath it may carry a top
	 * border of its own, or the two stack into a 4px line -- see the map. */
	border-bottom: 2px solid var(--oad-af-ink);
}

/* ---- results section: view switcher, list + map, poster wall ------------ */

.oad-af-section {
	margin: 0;
}


/* List + Map: a third of the width for the map, the rest for the list. */
/* One third map, two thirds list -- applied once a map is present. Without
 * one the list simply runs full width. */
.oad-af-section--list .oad-af-body:has( .oad-af-map ) {
	display: grid;
	grid-template-columns: 1fr 2fr;
	gap: 0;
	align-items: start;
}

.oad-af-section--list .oad-af-map {
	position: sticky;
	/* Stated rather than inherited from the theme's reset: the height is a
	 * viewport calc, and under content-box the two rules would add 2px and put
	 * the bottom edge just off screen. */
	box-sizing: border-box;
	/* Below the sticky header, not behind it. */
	top: var(--oad-af-sticky-top, 0px);
	height: calc( 100vh - var(--oad-af-sticky-top, 0px) );

	/* No border-top: the bar's own bottom rule sits immediately above and the
	 * pair read as a single 4px line. The bottom edge has nothing beneath it --
	 * the list runs on in the next column -- so it is drawn, closing the map off
	 * against the foot of the viewport it is pinned to. */
	border-right: 2px solid #262626;
	border-bottom: 2px solid #262626;
	overflow: hidden;
}

/* The list card draws its own 2px rule on top as the separator between rows,
 * so the very first card's rule lands directly beneath the bar (and beneath the
 * map on a phone) and the two read as one 4px line. The rule above the first
 * card is already drawn, so drop its own. The inline style the card template
 * emits is why this needs !important. */
.oad-af-section--list .oad-af-results .geodir-post:first-child > .card > div > .wp-block-columns:first-child {
	border-top-width: 0 !important;
}

/* Close the list off.
 *
 * Each card draws its own 2px rule on top as the separator between rows, so the
 * last one has nothing beneath it and the list trails away rather than ending.
 * Scoped to the results, so nothing else on the site gains a rule.
 *
 * !important because one of the site's own snippets sets
 * `.geodir-listings .geodir-post { border-style: none !important }`, which no
 * amount of specificity beats. */
.oad-af-section--list .oad-af-results .geodir-widget-posts > *:last-child:not( .geodir-info ) {
	border-bottom-width: 2px !important;
	border-bottom-style: solid !important;
	border-bottom-color: var( --wp--preset--color--foreground, #262626 ) !important;
}

/* One card per line, always.
 *
 * The list card is a full-width row -- title on the left, date on the right --
 * so two of them side by side reads as a grid, not a list. GeoDirectory emits
 * the row with `row-cols-sm-2`, and this theme sets its `sm` breakpoint at
 * 500px rather than Bootstrap's 576, so from 500px up the cards were halving:
 * a larger phone, or any phone on its side. Stated here rather than left to
 * whichever stylesheet loads last. */
.oad-af-section--list .oad-af-results .geodir-widget-posts > *:not( .geodir-info ) {
	flex: 0 0 100% !important;
	width: 100% !important;
	max-width: 100% !important;
}

/* Where the map used to sit, now that it has moved into the section. */
.oad-af-vacated {
	display: none !important;
}

/* The template gives its map a fixed height inline; in the column it should
 * fill the berth. Every level of the map's own nesting has to be named --
 * a couple of generic child selectors left the inner ones at zero. */
.oad-af-map .geodir-wgt-map,
.oad-af-map .geodir-map-wrap,
.oad-af-map .stick_trigger_container,
.oad-af-map .geodir_map_container,
.oad-af-map .map_background,
.oad-af-map .top_banner_section_in,
.oad-af-map .main_map_wrapper,
.oad-af-map .iprelative,
.oad-af-map .geodir-map-canvas,
.oad-af-map .leaflet-container {
	height: 100% !important;
	min-height: 100% !important;
	width: 100% !important;
}

/* The poster wall has no map: six across, separated only by the grid. */
.oad-af-section--wall .oad-af-map {
	display: none;
}

/* The grid between posters -- one variable sets its thickness, and the gap,
 * the shadows and the column arithmetic all follow from it.
 *
 * The rule is drawn by the poster on its far side of the join -- each one
 * paints its own top and left edges into the gap the row leaves for it -- so
 * every line belongs to exactly one poster and no join can ever stack two into
 * a double-width line. Three shadows rather than two: the third fills the
 * little square where a vertical rule crosses a horizontal one, which the
 * first two leave open.
 *
 * The lines that fall outside the wall are drawn just the same and clipped off
 * by the row: above the first row, where the bar's own bottom rule already
 * sits, and left of the first column. Nothing is drawn on the right or below,
 * so the wall meets the edge of the page and the end of the results with a
 * poster, not a rule.
 *
 * The gap defaults to the thickness of the rule -- that gap is what the rule
 * is drawn into, so without one the posters would sit on top of it. A gap set
 * on the block widens the space and the rule keeps its own thickness, against
 * the poster's leading edge. */
.oad-af-section--wall {
	--oad-af-grid: 2px;
	--oad-af-grid-colour: #262626;
}

.oad-af-section--wall .oad-af-body {
	display: block;
}

/* The poster card renders in GeoDirectory's 5-column layout; these widths
 * make it six across. Expressed in flex, not grid, because the cards sit in a
 * Bootstrap .row whose display:flex wins. */
/* Six across and edge to edge by default; the results block can say otherwise.
 *
 * The column count is deliberately not declared on the section itself, only in
 * the breakpoints below -- a base value here would sit closer to the element
 * than the block's own, and quietly overrule it. So the default lives in the
 * var() fallback instead, where the block's value wins by inheritance and the
 * breakpoints still win on a narrow screen. */
.oad-af-section--wall .oad-af-results .geodir-widget-posts {
	display: flex !important;
	flex-wrap: wrap !important;
	margin: 0 !important;
	padding: 0 !important;
	gap: var( --oad-af-gap, var( --oad-af-grid ) ) !important;

	/* The row's box is exactly the posters' bounds, so this takes off the
	 * grid lines that hang outside the wall and leaves the ones between. */
	overflow: hidden;
}

.oad-af-section--wall .oad-af-results .geodir-widget-posts > *:not( .geodir-info ) {
	/* The gaps come out of the row before it is divided, or the last card in
	 * each row is pushed onto the next one. */
	flex: 0 0 calc(
		( 100% - ( var( --oad-af-cols, 6 ) - 1 ) * var( --oad-af-gap, var( --oad-af-grid ) ) )
		/ var( --oad-af-cols, 6 )
	) !important;
	width: auto !important;
	max-width: none !important;
	margin: 0 !important;
	padding: 0 !important;

	/* Left rule, top rule, and the corner where the two meet. !important and a
	 * class heavier than the rule below that strips the card's own shadow. */
	box-shadow:
		calc( -1 * var( --oad-af-grid ) ) 0 0 var( --oad-af-grid-colour ),
		0 calc( -1 * var( --oad-af-grid ) ) 0 var( --oad-af-grid-colour ),
		calc( -1 * var( --oad-af-grid ) ) calc( -1 * var( --oad-af-grid ) ) 0 var( --oad-af-grid-colour ) !important;
}

@media ( max-width: 1100px ) {
	.oad-af-section--wall {
		--oad-af-cols: 4;
	}
}

@media ( max-width: 780px ) {
	/* Matches the :has() selector above, which otherwise outscores this and
	 * keeps the two columns on a phone. */
	.oad-af-section--list .oad-af-body:has( .oad-af-map ) {
		grid-template-columns: 1fr;
	}

	/* Half the screen, above the list. Still no top border -- the bar's is
	 * directly above it here too; only the edge against the list is drawn. */
	.oad-af-section--list .oad-af-map {
		position: static;
		height: 50vh;
		border-right: 0;
		border-bottom: 2px solid #262626;
	}

	.oad-af-section--wall {
		--oad-af-cols: 3;
	}
}

/* ---- view toggle, sitting left of the search field ---------------------- */

.oad-af__toggle {
	flex: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border: var(--oad-af-line);
	background: var( --oad-af-field );
	color: var( --oad-af-text );
	border-radius: 0;
	text-decoration: none;
}

.oad-af__toggle:hover {
	background: var(--oad-af-ink);
	color: var( --oad-af-paper );
}

.oad-af__toggle:focus-visible {
	outline: 3px solid var(--oad-af-ink);
	outline-offset: 2px;
}

/* ---- the section sits on the page's own white, not a dark band ---------- */

.oad-af-section,
.oad-af-body,
.oad-af-results {
	background: var( --oad-af-surface, var( --wp--preset--color--background, #fff ) );
}

/* The poster wall may stand on its own colour -- posters read differently
 * against a dark ground than a list beside a map does. Set on the section's
 * view class, which the switcher rewrites in place, so the change lands the
 * moment the view does and needs no second render. Falls back to the shared
 * surface, so leaving it unset keeps both views as they were.
 *
 * Ties with the rule above on specificity and wins on source order; the two
 * inner selectors are a class heavier and win outright. */
.oad-af-section--wall,
.oad-af-section--wall .oad-af-body,
.oad-af-section--wall .oad-af-results {
	background: var( --oad-af-surface-wall, var( --oad-af-surface, var( --wp--preset--color--background, #fff ) ) );
}

/* Poster cards are borderless whatever classes the widget emits; without this
 * Bootstrap's default .card shows a rounded, bordered box. The card's shape is
 * not set here -- the site's global styles put every .geodir-image-container
 * .ratio at 3/4, so the wall is portrait and the ratio-16x9 class the card
 * template emits never takes effect. */
.oad-af-section--wall .oad-af-results .card,
.oad-af-section--wall .oad-af-results .geodir-post,
.oad-af-section--wall .oad-af-results .wp-block-group {
	border: 0 !important;
	border-radius: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
}

.oad-af-section--wall .oad-af-results img,
.oad-af-section--wall .oad-af-results .geodir-image-container,
.oad-af-section--wall .oad-af-results .geodir-post-slider {
	border-radius: 0 !important;
}

/* The poster sits in its frame whole, not bled past it.
 *
 * Snippet 112 ("Event Category Archive - Close gap between cards") grows every
 * card image from the second onward to calc(100% + 4px) and then scales it
 * 1.005, and snippet 108 does the same at +2px for the first. Both were written
 * to swallow the subpixel seams the old archive grid left between cards, and
 * neither second selector is scoped to the .consistent-columns layout they were
 * written for -- so they land on any GeoDirectory card image, this wall
 * included. Measured here that is 215.9x286.5 of image inside a 210.8x281.1
 * frame, clipped by the container's overflow: about 2.5px off each side and
 * 2.7px off the top and bottom of every poster.
 *
 * The wall has no seams to hide: it draws its own grid with the box-shadows
 * above and leaves an exact gap for them, measured at a uniform 3px. So the
 * bleed is undone rather than tuned.
 *
 * .geodir-post is load-bearing. Without it this ties snippet 112 on
 * specificity, and a tie broken by source order lands only some of the
 * declarations -- the width, not the height or the transform. */
.oad-af-section--wall .oad-af-results .geodir-post .carousel-item.active img,
.oad-af-section--wall .oad-af-results .geodir-post .geodir-images-image img {
	width: 100% !important;
	height: 100% !important;
	max-width: 100% !important;
	transform: none !important;
}

/* ---- nothing found ------------------------------------------------------
 *
 * GeoDirectory puts its "no listings" notice inside the same row as the cards,
 * so every rule above that sizes a card was catching it too -- a sentence
 * squeezed into a sixth of the page and hard against the left edge. It is not a
 * card: it spans the row, and stands in the middle of the space where the
 * results would have been.
 */
.oad-af-results .geodir-widget-posts > .geodir-info {
	flex: 0 0 100%;
	width: 100%;
	max-width: 100%;
	padding: clamp( 3.5rem, 12vw, 7rem ) 1.5rem;
	text-align: center;

	/* !important on these two only: the notice carries Bootstrap's `d-block`
	 * and `mx-1`, both of which are !important, so a plain declaration here
	 * leaves it a left-aligned block with a stray 4px either side. */
	display: flex !important;
	margin: 0 !important;

	align-items: center;
	justify-content: center;
}

/* Bootstrap's own alert colours belong to a different site. */
.oad-af-results .geodir-info .alert {
	max-width: 32rem;
	color: inherit;

	/* A sentence the visitor reads, so it takes the body rung and the body
	 * leading rather than the bar's own em scale -- it sits in the results
	 * area, not in the control strip. */
	font-size: var( --wp--preset--font-size--custom-9, 1.05rem );
	line-height: var( --wp--custom--line-height--body, 1.55 );

	/* The site draws a 2px box on every .alert. A notice that nothing matched
	 * is not an error to be boxed off -- it is the state of the page. */
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
	border: 0 !important;
	border-radius: 0 !important;
}

.oad-af-results .geodir-info .alert i {
	display: block;
	margin: 0 0 0.6rem;
	font-size: var( --wp--preset--font-size--custom-6, 1.6rem );
	opacity: 0.45;
}

.oad-af-results .geodir-info .alert a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 3px;
}


/* ---- the poster behind a title ------------------------------------------ */

/* Shown while a pointer rests on a title in the list view. A pointer only:
 * there is nothing here on a touch screen, where a tap opens the event.
 *
 * On the body rather than in the list, because both the bar and the map are
 * sticky and each one is a stacking context nothing inside the list could be
 * drawn over. That also puts it outside .oad-af, so it cannot inherit the bar's
 * colour pair and states its own -- the same two theme presets, same fallbacks.
 *
 * Square, 2px, no shadow: the frame the rest of the page is drawn with -- and
 * three-sided. Its right edge is laid inside the map's own right border, the
 * line the list begins at, so a fourth rule there would double it to 4px. The
 * one the page already draws is the one that shows. */
.oad-af-poster {
	position: fixed;
	left: 0;
	top: 0;
	z-index: 1000;
	box-sizing: border-box;

	/* A column and a half of the site's grid, worked out in the script -- see
	 * sizePoster(). This is only what it measures before that lands. */
	width: 15rem;
	margin: 0;
	padding: 0;
	border: 2px solid var( --wp--preset--color--foreground, #262626 );
	border-right: 0;
	background: var( --wp--preset--color--background, #fff );

	/* It stands where the pointer is going. Left catchable it would take the
	 * hover off the title it belongs to and close itself. */
	pointer-events: none;

	visibility: hidden;
	opacity: 0;
	transition: opacity 120ms ease;
}

.oad-af-poster.is-open {
	visibility: visible;
	opacity: 1;
}

/* Up against whatever is pinned above the list -- the site header, or the bar's
 * own bottom rule. Both draw that line already, so the poster does not draw a
 * second one under it. Same rule as its right edge, on the other axis. */
.oad-af-poster--tucked {
	border-top: 0;
}

/* Kept out of the way of anyone who does not want things appearing and fading
 * as they move. The poster is still shown -- it is the point -- but at once. */
@media ( prefers-reduced-motion: reduce ) {
	.oad-af-poster {
		transition: none;
	}
}

/* The whole poster, at its own shape -- the wall crops to 3:4, but there is no
 * grid to keep here and a cropped preview of a piece of artwork is worse than
 * a small one. The frame is sized to that shape in the script, so the picture
 * simply fills it and there is nothing to letterbox. */
.oad-af-poster img {
	display: block;
	width: 100%;
	height: auto;
}
