/*
 * posts.css — Events, Stories & News, and a single post.
 *
 * WHERE THIS SITS IN THE CASCADE: after components.css, which is what
 * inc/enqueue.php declares as its dependency. Everything here is a COMPONENT,
 * in components.css's sense — a card, a list, a date — rather than the traced
 * per-comp treatment of a specific composition that belongs in
 * art-direction.css. That ordering is why an art-directed page can still
 * overrule any of it: a composition may overrule a default, never the reverse.
 *
 * NO NEW COLOURS, TYPE SCALE OR SPACING PRIMITIVES. Every value below is a
 * theme.json token or a clamp() in the same shape the rest of the theme uses.
 * These pages did not exist when the design was drawn, so the only honest way
 * to make them look like the site is to build them out of the site's existing
 * vocabulary — .bb-eyebrow, .bb-section-title, .bb-link-arrow — rather than to
 * invent a parallel one that drifts.
 *
 * ALSO LOADED IN THE EDITOR (inc/setup.php's add_editor_style), for the same
 * reason components.css is: a staff member editing a post should not be shown
 * something that looks broken. art-direction.css is NOT an editor style, so
 * the one thing here that reads from it — the picture rail's
 * --bb-clip-card-a/-b/-c masks — resolves to no mask at all in wp-admin. That
 * is a square-edged well rather than a broken one, and the listing the rail
 * belongs to is a front-end template the editor never renders anyway.
 */

/* ==========================================================================
   The listing sections on /events/ and /stories-and-news/
   ========================================================================== */

.bb-post-section {
	margin-block-start: clamp( 2.5rem, 6vw, 4rem );
}

/* The two Events headings sit closer to their lists than a section title
   normally would: they are labels on a list, not the opening of a band. */
.bb-post-section > .bb-section-title {
	margin-bottom: 1.25rem;
}

.bb-post-empty {
	color: var(--wp--preset--color--forest);
	font-style: italic;
	margin: 0;
}

/* ==========================================================================
   A summary card
   ========================================================================== */

/* A CONTAINER, so the picture rail below can be sized in `cqi` off the list's
   own inline size instead of off a percentage the grid cannot resolve. The
   whole reason is written out under "The picture rail". */
.bb-post-list-wrap {
	display: grid;
	gap: clamp( 1.5rem, 3vw, 2.25rem );
	container-type: inline-size;
}

.bb-post-summary {
	/* A rule rather than a box. The page is already a warm cream field and a
	   stack of bordered cards on it reads as an admin table; a hairline is
	   enough to separate two entries, and it survives a card whose excerpt is
	   one line next to one whose excerpt is five. */
	border-top: 1px solid rgba( 57, 62, 46, 0.18 );
	padding-block-start: clamp( 1.25rem, 2.5vw, 1.75rem );
	margin: 0;
}

.bb-post-summary:first-child {
	border-top: 0;
	padding-block-start: 0;
}

.bb-post-summary__kind {
	color: var(--wp--preset--color--terracotta-text);
	margin: 0 0 0.35rem;
}

.bb-post-date {
	display: block;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	color: var(--wp--preset--color--forest);
	margin-bottom: 0.25rem;
}

.bb-post-summary__title {
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp( 1.3rem, 2.6vw, 1.7rem );
	font-weight: 500;
	line-height: 1.15;
	margin: 0 0 0.5rem;
}

.bb-post-summary__title a {
	color: var(--wp--preset--color--forest);
	text-decoration: none;
}

.bb-post-summary__title a:hover,
.bb-post-summary__title a:focus {
	color: var(--wp--preset--color--terracotta-text);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.bb-post-summary__where {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--forest);
	margin: 0 0 0.5rem;
}

.bb-post-summary__excerpt {
	margin: 0 0 0.75rem;
	max-width: 60ch;
}

/* Inside a card that now has a rail, the 60ch measure binds only between about
   a 780px and a 1150px viewport — wide enough to be invisible on a large
   monitor and narrow enough to be invisible on a phone, so all it produces is a
   gutter that wanders down the list on a laptop. The grid column is the measure
   here. */
.bb-post-list-wrap > .bb-post-summary .bb-post-summary__excerpt {
	max-width: none;
}

.bb-post-summary__more {
	margin: 0;
}

/* ==========================================================================
   The picture rail
   ==========================================================================

   SCOPED TO .bb-post-list-wrap, not to .bb-post-summary on its own. index.php
   puts that same class on a card built from core block classes with no __body
   wrapper, so an unscoped grid would drop its excerpt into the rail's column
   and nothing in the test suite renders that template.

   THE TRACK IS DEFINITE, AND THAT IS WHAT THIS BLOCK IS FOR.

   0.9.0 sized the rail as an `auto` track and put the width on the ITEM as a
   percentage — `inline-size: clamp( 7rem, 26%, 13rem )` — so that a card with
   no rail collapsed to one column on its own, with no modifier class and no
   branch in PHP. Live, the first three cards looked right and every card after
   them had a picture several times too big with the margins to match.

   A percentage on a grid item inside an `auto` track is CYCLIC: the spec
   resolves it as `auto` while the track is being sized, so the track is sized
   from the item's INTRINSIC contribution instead. From the fourth card down
   WordPress adds `loading="lazy"` and `sizes="auto, …"` by itself — its
   above-the-fold heuristic, which is exactly why the first three were exempt —
   and core ships a global rule to go with them:

       img:is([sizes="auto" i], [sizes^="auto," i]) {
           contain-intrinsic-size: 3000px 1500px;
       }

   3000px is therefore what the track was being sized from. "The picture grew"
   and "the margins are broken" were one defect, not two.

   The fix is to take the width out of the track-sizing loop altogether: the
   list is a CONTAINER, the track is a clamp in `cqi`, and the media element
   only fills whatever track it is handed. `26cqi` is the same measure the
   `26%` meant — 26% of the list's inline size — resolved where no image's
   intrinsic size can reach it. Anything that puts an `auto` track back here
   puts the bug back with it.

   The rail's WIDTH is what aligns the list. Its height is free to follow the
   picture, which is what lets a 2.96:1 banner and a phone portrait sit in the
   same column without either being gutted. */

.bb-post-list-wrap > .bb-post-summary {
	display: grid;
	grid-template-columns: minmax( 0, 1fr ) clamp( 7rem, 26cqi, 13rem );
	gap: clamp( 1rem, 3vw, 2rem );
	align-items: start;
	/* The containing block for the title's stretched link, below. */
	position: relative;
}

/* What the `auto` track used to do for free, done by a literal class instead.
   Every page in a set of search results and every event has no rail at all,
   and a fixed track would leave a 13rem hole beside those rows and make the
   list ragged — which is the thing the tile exists to prevent.
   template-parts/post-list.php emits this modifier from the same decision that
   produced the markup, so the two cannot disagree. */
.bb-post-list-wrap > .bb-post-summary--no-media {
	grid-template-columns: minmax( 0, 1fr );
}

.bb-post-summary__body {
	min-width: 0;
}

/* The well fills its track and can never be wider than it: the width lives on
   the track above, and min-inline-size:0 switches off a grid item's automatic
   minimum size, which is the other route by which an image's intrinsic width
   could prise the column back open.

   THE EDGE IS THE HOME PAGE'S, not a rounded rectangle. --bb-clip-card-a/-b/-c
   are the three traced programme-card masks on :root in art-direction.css —
   the same shapes Early Literacy, Learning Academy and Scholarships wear — and
   that file loads on every page, so the tokens are already here.

   NO border-radius AND NO overflow: hidden. The mask does the clipping, so a
   rounded overflow box underneath it is redundant, and it is precisely the
   combination style.css:99-107 and motion.css:435-442 both record Safari
   mis-rendering. isolation:isolate stays for the reason it is on every
   .bb-shape-* there: it keeps compositing predictable under a mask. */
.bb-post-summary__media {
	inline-size: 100%;
	min-inline-size: 0;
	aspect-ratio: 1 / 1;
	background-color: var(--wp--preset--color--base-alt);
	-webkit-mask-size: 100% 100%;
	mask-size: 100% 100%;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	isolation: isolate;
}

/* Cycled down the list, so two neighbours never share an edge — the same
   property basic_borrego_post_card_tile()'s adjacency rule enforces for the
   cacti. nth-child rather than a modifier class: it needs no PHP, it creates
   no class for tools/test-pages.php's orphan check to trip on, and it
   guarantees the variety in the order the list actually renders rather than in
   the order the posts happen to hash.

   The three shapes were traced at fixed ratios (card-a 1.546, card-b 1.365,
   card-c 1.232) but with preserveAspectRatio='none' inside a unit viewBox, so
   they are built to stretch to their box — which is how .bb-hero__photo--stack
   and .bb-home-donate__media already reuse --bb-clip-card-b at other
   proportions. The four well ratios below are unchanged; the curve flexes with
   them.

   THE TILE IS MASKED BY THESE RULES TOO, because it carries the same class: a
   cactus medallion with an organic edge beside the photographs rather than a
   rounded box among them, and its tint is a background INSIDE the mask, so it
   takes the same shape. */
.bb-post-list-wrap > .bb-post-summary:nth-child( 3n + 1 ) .bb-post-summary__media {
	-webkit-mask-image: var(--bb-clip-card-a);
	mask-image: var(--bb-clip-card-a);
}

.bb-post-list-wrap > .bb-post-summary:nth-child( 3n + 2 ) .bb-post-summary__media {
	-webkit-mask-image: var(--bb-clip-card-b);
	mask-image: var(--bb-clip-card-b);
}

.bb-post-list-wrap > .bb-post-summary:nth-child( 3n ) .bb-post-summary__media {
	-webkit-mask-image: var(--bb-clip-card-c);
	mask-image: var(--bb-clip-card-c);
}

.bb-post-summary__img {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	/* Faces sit in the top third of a snapshot. The same bias
	   .bb-scholar-card__photo already uses, so a portrait crops the same way
	   here as it does on the awardees page. */
	object-position: center 32%;
}

/* Four wells, one per shape of photograph. */
.bb-post-summary__media--pano {
	aspect-ratio: 2.5 / 1;
}

.bb-post-summary__media--wide {
	aspect-ratio: 4 / 3;
}

.bb-post-summary__media--square {
	aspect-ratio: 1 / 1;
}

.bb-post-summary__media--tall {
	aspect-ratio: 4 / 5;
}

.bb-post-summary__media--tall .bb-post-summary__img {
	object-position: center 22%;
}

/* --------------------------------------------------------------------------
   The tile, where a post has no picture
   -------------------------------------------------------------------------- */

.bb-post-summary__tile {
	display: grid;
	place-items: center;
	aspect-ratio: 1 / 1;
}

.bb-post-summary__glyph {
	display: block;
	inline-size: 58%;
	line-height: 0;
}

/* Every rule the decorative .bb-botanical carries is restated here rather than
   overridden, because this glyph is not that: the art arrives unwrapped from
   basic_borrego_botanical_art(), so nothing has to be undone and nothing
   disappears at 781px. */
.bb-post-summary__glyph svg {
	display: block;
	inline-size: 100%;
	block-size: auto;
}

.bb-post-summary__tile--flip .bb-post-summary__glyph {
	transform: scaleX( -1 );
}

/* Four tints from the palette, seeded per post so the three photoless Scholar
   Stories — which fall consecutively on their own shelf — never draw the same
   tile twice in a column. Each is the palette colour at low alpha on the card
   ground, so the cactus reads as a watermark rather than as a filled panel. */
.bb-post-summary__tile--sage {
	background-color: rgba( 143, 163, 122, 0.18 );
	color: var(--wp--preset--color--forest);
}

.bb-post-summary__tile--gold {
	background-color: rgba( 201, 162, 39, 0.16 );
	color: var(--wp--preset--color--forest-deep);
}

.bb-post-summary__tile--terracotta {
	background-color: rgba( 182, 99, 66, 0.15 );
	color: var(--wp--preset--color--terracotta-text);
}

.bb-post-summary__tile--forest {
	background-color: rgba( 57, 62, 46, 0.12 );
	color: var(--wp--preset--color--forest);
}

/* --------------------------------------------------------------------------
   One link across the whole card
   -------------------------------------------------------------------------- */

/* The title's anchor, stretched. The picture beside it is therefore clickable
   without being a second anchor to the same place: one tab stop, named by the
   title, and a target the size of the card. The cost is that dragging to select
   text across a card is swallowed by the overlay, and that any second link
   added inside a card in future needs its own position — which the Read more
   line below already demonstrates. */
.bb-post-summary__title a::after {
	content: "";
	position: absolute;
	inset: 0;
}

.bb-post-summary__more a {
	position: relative;
}

/* NO HOVER SCALE ON THE PICTURE, and this is deliberate rather than forgotten.
   The well is masked now, and motion.css:435-442 is explicit that the lift
   belongs on the UNMASKED wrapper and never on the masked element — a
   transformed child inside a masked box is the same stacking-context hazard
   Safari mis-renders, and it is what made the corners flash square. The
   stretched title link above already gives the whole card hover feedback in
   colour and underline; the photograph does not need to move as well. */

/* --------------------------------------------------------------------------
   Narrow screens
   -------------------------------------------------------------------------- */

@media ( max-width: 640px ) {
	/* A small square at the START of the row, NOT a full-width banner above the
	   headline. The banner was tried on paper and it turns a scannable list into
	   an image stack showing about one and a half posts per screen; the point of
	   a hairline list is that you can read down it. A single square also spares
	   the four well shapes from being flattened into one ratio on the very
	   screen where a portrait has least room to lose. */
	.bb-post-list-wrap > .bb-post-summary {
		grid-template-columns: 5.5rem minmax( 0, 1fr );
		gap: 1rem;
	}

	.bb-post-list-wrap > .bb-post-summary--no-media {
		grid-template-columns: 1fr;
	}

	.bb-post-summary__body {
		order: 2;
	}

	.bb-post-summary__media {
		order: 1;
		aspect-ratio: 1 / 1;
	}
}

/* ==========================================================================
   Pagination
   ========================================================================== */

.bb-post-pagination {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem;
	margin-block-start: clamp( 2rem, 4vw, 3rem );
}

.bb-post-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.5rem;
	min-height: 2.5rem;
	padding: 0 0.6rem;
	border: 1px solid rgba( 57, 62, 46, 0.25 );
	border-radius: 999px;
	color: var(--wp--preset--color--forest);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	text-decoration: none;
}

.bb-post-pagination .page-numbers:hover,
.bb-post-pagination .page-numbers:focus {
	border-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--terracotta-text);
}

.bb-post-pagination .page-numbers.current {
	background-color: var(--wp--preset--color--forest);
	border-color: var(--wp--preset--color--forest);
	color: var(--wp--preset--color--base);
}

.bb-post-pagination .page-numbers.dots {
	border-color: transparent;
	min-width: 1.5rem;
}

/* ==========================================================================
   A single post
   ========================================================================== */

.bb-post-article__kind {
	color: var(--wp--preset--color--terracotta-text);
	margin: 0 0 0.5rem;
}

/* Deliberately quiet. On an event this sits under the title while the event's
   OWN date is in the card below, and the reader must never mistake which of
   the two is the one they need to put in a calendar. */
.bb-post-article__posted {
	font-size: var(--wp--preset--font-size--x-small);
	color: rgba( 57, 62, 46, 0.7 );
	margin: 0 0 1.25rem;
}

.bb-event-card {
	background-color: var(--wp--preset--color--base-alt);
	border-inline-start: 3px solid var(--wp--preset--color--terracotta);
	border-radius: 0 8px 8px 0;
	padding: clamp( 0.9rem, 2vw, 1.25rem ) clamp( 1rem, 2.5vw, 1.5rem );
	margin: 0 0 1.75rem;
}

.bb-event-card p {
	margin: 0;
}

.bb-event-card__date {
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp( 1.15rem, 2.4vw, 1.5rem );
	font-weight: 500;
	color: var(--wp--preset--color--forest);
	line-height: 1.2;
}

.bb-event-card__time,
.bb-event-card__where {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--forest);
	margin-top: 0.25rem;
}

.bb-post-article__back {
	margin-block-start: clamp( 2rem, 4vw, 3rem );
}

/* The arrow leads, so the whole control mirrors "Read more →". */
.bb-link-arrow--back {
	flex-direction: row;
}

/* ==========================================================================
   The [bb_latest_posts] shortcode, and the pattern that wraps it
   ========================================================================== */

.bb-post-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 1rem;
}

.bb-post-list__item {
	display: grid;
	gap: 0.15rem;
	padding-block-end: 1rem;
	border-bottom: 1px solid rgba( 57, 62, 46, 0.18 );
}

.bb-post-list__item:last-child {
	border-bottom: 0;
	padding-block-end: 0;
}

.bb-post-list__title {
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp( 1.05rem, 2vw, 1.25rem );
	font-weight: 500;
	color: var(--wp--preset--color--forest);
	text-decoration: none;
	line-height: 1.2;
}

.bb-post-list__title:hover,
.bb-post-list__title:focus {
	color: var(--wp--preset--color--terracotta-text);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.bb-post-list__meta,
.bb-post-list__excerpt {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--forest);
}

/* ==========================================================================
   The Event details box, in wp-admin
   ========================================================================== */

.bb-event-meta input {
	margin-top: 0.25rem;
}

/* ==========================================================================
   Search results

   The count sits between the heading and the form as its own line, rather than
   inside the <h1>: a number and a quoted phrase in one heading reads badly
   aloud and wraps worse on a phone.
   ========================================================================== */

.bb-search-count {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--forest);
	margin: 0 0 1.25rem;
}

/* ==========================================================================
   The filter chips — /events/ and /stories-and-news/

   Chips, not a <select>: each type is a real bookmarkable URL, and the row
   doubles as a visible statement of what kinds of thing this site publishes.
   The set is data-driven — a sub-category added under Events or under
   Stories & News in wp-admin gets a chip without any change to this file.

   NAMED bb-type-filter, NOT bb-event-filter, since 2026-09-03: one row of
   chips now serves both pages from template-parts/type-filter.php, and a class
   naming only one of them would have been a lie in the stylesheet the next
   person greps.
   ========================================================================== */

.bb-type-filter {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 1.75rem 0 2.25rem;
}

.bb-type-filter__chip {
	display: inline-block;
	padding: 0.4em 1em;
	border: 1px solid rgba( 57, 62, 46, 0.28 );
	border-radius: 9999px;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.3;
	color: var(--wp--preset--color--forest);
	background-color: transparent;
	text-decoration: none;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.bb-type-filter__chip:hover,
.bb-type-filter__chip:focus {
	border-color: var(--wp--preset--color--terracotta-text);
	color: var(--wp--preset--color--terracotta-text);
	text-decoration: none;
}

/* The current filter is stated by colour AND by aria-current in the markup, so
   it is not carried by colour alone. */
.bb-type-filter__chip.is-current {
	background-color: var(--wp--preset--color--forest);
	border-color: var(--wp--preset--color--forest);
	color: var(--wp--preset--color--base);
}

.bb-type-filter__chip.is-current:hover,
.bb-type-filter__chip.is-current:focus {
	background-color: var(--wp--preset--color--terracotta-text);
	border-color: var(--wp--preset--color--terracotta-text);
	color: var(--wp--preset--color--base);
}
