/*
 * Composition components — reusable across pages, owned by no page.
 *
 * WHY THIS FILE EXISTS
 *
 * art-direction.css states its own contract in its header: it is art direction
 * for specific compositions, traced from a comp. sections.css holds the bands
 * those compositions are built from. Neither is the right home for primitives
 * that ordinary PAGE CONTENT reaches for, because page content is authored in
 * the dashboard by staff, not in pattern files by a developer.
 *
 * Everything here is written to that standard:
 *
 *   - No page name appears in any selector. A rule that only makes sense on one
 *     page belongs in art-direction.css instead.
 *   - Every value comes from a theme.json preset. No new colors, no new type
 *     scale, no magic numbers that a future page would have to match by eye.
 *   - The COLOR rules key off the classes WordPress itself emits
 *     (.has-forest-background-color and friends), so they protect any block a
 *     staff member builds with the palette swatches — not only the blocks this
 *     file was written for. The SHAPE rules are opt-in classes.
 *
 * That split is the important one. Color failures are invisible until someone
 * with low vision hits them; shape is obvious the moment you look. So color is
 * automatic and shape is asked for.
 *
 * CASCADE POSITION: after sections.css, before art-direction.css. These are
 * defaults that a specific composition is allowed to overrule.
 *
 * @package BasicBorrego
 */

/* --------------------------------------------------------------------------
   On-dark guardrails
   --------------------------------------------------------------------------
   style.css already redirects HEADINGS inside a colored band to inherit the
   band's color, and explains why. Links and buttons have exactly the same
   problem and were never covered, because until now every dark band in this
   theme was hand-authored markup with no prose links or core buttons in it.

   Page content changes that. docs/editor-cheat-sheet.md actively teaches staff
   to make a colored band by grouping blocks and picking a background swatch,
   and a call-to-action band is precisely where someone then puts a link.

   The numbers, on forest #393E2E:

       terracotta-text  #8F4529   1.60:1   the theme.json default. Invisible.
       terracotta-on-dark #D6906F 4.25:1   passes AA for body text.
       base             #EFE7DB   8.90:1

   theme.json emits its element styles inside :where(), which carries zero
   specificity, so a single class wins cleanly — the same mechanism style.css
   relies on. */

.has-forest-background-color :is( a, a:visited ),
.has-forest-deep-background-color :is( a, a:visited ),
.has-terracotta-text-background-color :is( a, a:visited ) {
	color: var(--wp--preset--color--terracotta-on-dark);
}

.has-forest-background-color :is( a, a:visited ):hover,
.has-forest-deep-background-color :is( a, a:visited ):hover,
.has-terracotta-text-background-color :is( a, a:visited ):hover {
	color: var(--wp--preset--color--base);
}

.has-forest-background-color :is( a, a:visited ):focus-visible,
.has-forest-deep-background-color :is( a, a:visited ):focus-visible,
.has-terracotta-text-background-color :is( a, a:visited ):focus-visible {
	outline: 2px solid var(--wp--preset--color--base);
	outline-offset: 2px;
}

/*
 * Buttons on dark, inverted.
 *
 * theme.json paints every button terracotta-text on base. On a forest band the
 * FILL drops to 1.60:1 against the band, so the button's shape dissolves and
 * only its cream label survives — it stops reading as a button at a glance and
 * fails WCAG 1.4.11 for the control itself.
 *
 * The theme already answered this once: .bb-btn-invert (art-direction.css)
 * flips to a cream fill with a terracotta-text label, and every hand-authored
 * on-dark call to action uses it. This is that same treatment, applied to the
 * core button block so staff get it without knowing the class exists.
 */
.has-forest-background-color .wp-block-button__link,
.has-forest-deep-background-color .wp-block-button__link,
.has-terracotta-text-background-color .wp-block-button__link {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--terracotta-text);
}

.has-forest-background-color .wp-block-button__link:hover,
.has-forest-deep-background-color .wp-block-button__link:hover,
.has-terracotta-text-background-color .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--base-alt);
	color: var(--wp--preset--color--terracotta-text);
}

.has-forest-background-color .wp-block-button__link:focus-visible,
.has-forest-deep-background-color .wp-block-button__link:focus-visible,
.has-terracotta-text-background-color .wp-block-button__link:focus-visible {
	outline: 2px solid var(--wp--preset--color--base);
	outline-offset: 2px;
}

/* An outline button reads as secondary next to the filled one. Opt-in, and it
   is the one button variant that needs a class because core has no notion of
   it. */
.has-forest-background-color .is-style-outline .wp-block-button__link,
.has-forest-deep-background-color .is-style-outline .wp-block-button__link {
	background-color: transparent;
	color: var(--wp--preset--color--base);
	border-color: currentColor;
}

/* --------------------------------------------------------------------------
   Prose that lands directly in a flush composition
   --------------------------------------------------------------------------
   A composed page's <main> is is-layout-flow with no gutter and no content
   width — see basic_borrego_main_classes(). Every existing composed page gets
   away with that because each of its children is a <section> carrying its own
   inner wrapper.

   A staff member clicking "+" between two sections and typing a paragraph does
   not get that wrapper, and their text runs from one edge of the display to the
   other. This catches the handful of block types that can plausibly be added at
   the top level of a composition and gives them the article measure.

   Deliberately NOT `.bb-main--flush > *`: the sections themselves are direct
   children too, and constraining those would undo every full-bleed band on the
   home and about pages. Only core's own prose blocks are named. */

.bb-main--flush > :is(
	p,
	.wp-block-paragraph,
	.wp-block-heading,
	.wp-block-list,
	.wp-block-quote,
	.wp-block-table,
	.wp-block-details
) {
	max-width: var(--wp--style--global--content-size);
	margin-inline: auto;
	padding-inline: var(--wp--preset--spacing--40);
	box-sizing: content-box;
}

/* --------------------------------------------------------------------------
   Band
   --------------------------------------------------------------------------
   The full-bleed colored band with soft organic edges, as a class any page can
   apply to a group block.

   This is deliberately the SAME component as the home page's impact band rather
   than a lookalike: it reuses that band's traced wave masks and amplitudes from
   :root, so a band on a new page and the band on the home page are the same
   object at the same proportions. A near-copy with slightly different waves
   would read as a mistake.

   Usage: a core/group, align full, with a palette background color. The
   background class does the color (and picks up the guardrails above); this
   does the shape. */

.bb-band {
	position: relative;
	padding-block: clamp( 3.5rem, 7vw, 5.5rem );
	margin-block:
		calc( var(--bb-amp-impact-top, 0) * 1vw )
		calc( var(--bb-amp-impact-bot, 0) * 1vw );
}

.bb-band::before,
.bb-band::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	background-color: inherit;
	-webkit-mask-size: 100% 100%;
	mask-size: 100% 100%;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	pointer-events: none;
}

/*
 * The `, 0` fallbacks matter. The wave masks and their amplitudes are declared
 * on :root in art-direction.css, which the BLOCK EDITOR does not load. Without a
 * fallback the height would compute to auto and the mask would be invalid,
 * which is a solid rectangle of color floating above the band while a staff
 * member edits. Falling back to zero height means the editor simply shows a
 * band with straight edges — accurate enough, and never alarming.
 */
.bb-band::before {
	bottom: 100%;
	height: calc( var(--bb-amp-impact-top, 0) * 1vw );
	-webkit-mask-image: var(--bb-divider-impact-top);
	mask-image: var(--bb-divider-impact-top);
}

.bb-band::after {
	top: 100%;
	height: calc( var(--bb-amp-impact-bot, 0) * 1vw );
	-webkit-mask-image: var(--bb-divider-impact-bot);
	mask-image: var(--bb-divider-impact-bot);
}

/* --------------------------------------------------------------------------
   Stat
   --------------------------------------------------------------------------
   A figure and its label. Sized to match .bb-home-impact__figure exactly, so a
   stat on any page is the same size as a stat on the home page.

   Applied to a PARAGRAPH, not a heading. A figure is not a section title, and
   four headings reading "$820K+ / 553 / 27 / 45" would put four meaningless
   entries in the document outline that screen-reader users navigate by. */

.bb-stat {
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp( 1.5rem, 3.4vw, 2.3rem );
	font-weight: 500;
	line-height: 1.05;
	margin-block: 0 0.35rem;
}

.bb-stat-label {
	font-size: var(--wp--preset--font-size--x-small);
	line-height: 1.35;
	opacity: 0.88;
	margin-block: 0;
}

/* Gold hairlines between stats, matching the impact band. Applied to the
   columns block that holds them; :first-child keeps the leading edge clean. */
.bb-stat-row .wp-block-column + .wp-block-column {
	border-inline-start: 1px solid rgba( 201, 162, 39, 0.45 );
	padding-inline-start: clamp( 0.6rem, 2vw, 1.6rem );
}

/* --------------------------------------------------------------------------
   Panel
   --------------------------------------------------------------------------
   A soft raised surface for a self-contained piece of content: an action card,
   a callout, a sidebar note.

   Distinct from .bb-card (art-direction.css), which is the home page's
   photograph-led program card with a traced mask and a fixed aspect ratio.
   This one is type-only and takes whatever blocks are put in it. */

.bb-panel {
	background-color: var(--wp--preset--color--base-alt);
	border-radius: 10px;
	padding: clamp( 1.25rem, 3vw, 2rem );
	height: 100%;
	box-sizing: border-box;
}

/* On a dark band, a panel needs to lift AWAY from the band rather than sink
   into it. */
.has-forest-background-color .bb-panel,
.has-forest-deep-background-color .bb-panel {
	background-color: rgba( 239, 231, 219, 0.08 );
}

.bb-panel > :first-child {
	margin-block-start: 0;
}

.bb-panel > :last-child {
	margin-block-end: 0;
}

/* A panel whose job is to move someone onward: the action sits at the bottom
   edge however much copy is above it, so a row of them lines up. */
.bb-panel--action {
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
}

.bb-panel--action .wp-block-buttons {
	margin-block-start: auto;
	padding-block-start: 0.5rem;
}

/* --------------------------------------------------------------------------
   Matched card rows
   --------------------------------------------------------------------------
   A row of .bb-panel cards that reads as ONE object rather than as two or
   three loose boxes. Put .bb-cards on the Columns block; nothing goes on the
   columns themselves.

   WHY THIS EXISTS AT ALL. WordPress lays a Columns block out with flex and
   pins `align-items: normal !important` on .wp-block-columns, so every card
   sizes to its own content. .bb-panel's `height: 100%` therefore resolves
   against nothing and a row goes ragged the moment one heading wraps to two
   lines and its neighbour does not. Overriding align-items does not fix it
   reliably; making the ROW a grid does, because then the row's height is the
   row's business.

   SUBGRID is what aligns the bands INSIDE the cards. Each column adopts the
   row's tracks, so eyebrow, heading, description and action each sit on one
   shared line across the whole set — with no hand-tuned min-heights, and with
   short headings costing nothing. Four rows is the shape every card in this
   theme has; a set with a different number sets --bb-card-rows.

   The column count is read off the markup rather than configured, so the same
   class serves a pair and a trio.

   Below 782px WordPress already stacks the columns and none of this applies. */

@media ( min-width: 782px ) {

	.bb-cards {
		display: grid;
		align-items: stretch;
		grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
	}

	.bb-cards:has( > .wp-block-column:nth-child( 3 ):last-child ) {
		grid-template-columns: repeat( 3, minmax( 0, 1fr ) );
	}

	.bb-cards:has( > .wp-block-column:nth-child( 4 ):last-child ) {
		grid-template-columns: repeat( 4, minmax( 0, 1fr ) );
	}

	@supports ( grid-template-rows: subgrid ) {

		.bb-cards {
			grid-template-rows: repeat( var( --bb-card-rows, 4 ), auto );
		}

		.bb-cards > .wp-block-column {
			display: grid;
			grid-template-rows: subgrid;
			grid-row: span var( --bb-card-rows, 4 );
			row-gap: 0;
		}
	}
}

/* Without subgrid the bands cannot share a track, so the two elements that
   vary in depth reserve their taller state instead. Costs a blank line under a
   short heading; keeps the row aligned. */
@supports not ( grid-template-rows: subgrid ) {

	.bb-cards > .wp-block-column > :is( h2, h3 ),
	.bb-cards--compact > .wp-block-column > .bb-eyebrow {
		min-height: 2.3em;
	}

	@supports ( height: 1lh ) {

		.bb-cards > .wp-block-column > :is( h2, h3 ),
		.bb-cards--compact > .wp-block-column > .bb-eyebrow {
			min-height: 2lh;
		}
	}
}

/* Grid rows carry the rhythm, so the children must not also carry margins —
   .bb-panel--action's gap and core's block margins would both add to it. */
.bb-cards > .wp-block-column > * {
	margin-block: 0;
}

.bb-cards > .wp-block-column > .bb-eyebrow {
	margin-block-end: 0.55rem;
}

.bb-cards > .wp-block-column > :is( h2, h3 ) {
	margin-block-end: 0.75rem;
	text-wrap: balance;
}

/* The card's action, ruled off at the foot. Every card in a row ends on the
   same line whatever the copy above it does, and a button stretches to the
   card so a row of them is one shape rather than several lozenges. */
.bb-cards > .wp-block-column > .bb-card-action {
	align-self: end;
	width: 100%;
	margin-block-start: auto;
	padding-block-start: 1.15rem;
	border-block-start: 1px solid rgba( 143, 69, 41, 0.16 );
}

.bb-cards > .wp-block-column > .bb-card-action .wp-block-button {
	width: 100%;
}

.bb-cards > .wp-block-column > .bb-card-action .wp-block-button__link {
	display: block;
	width: 100%;
	text-align: center;
}

/* --bb-cards--compact: the glyph moves onto the eyebrow's line.

   The icon set above draws through a block-level ::before on the panel, which
   spends a whole row on a 1.9rem mark. In a dense row of cards that row is the
   difference between a card you can take in at a glance and one you scroll. The
   glyph is redrawn at cap height on the eyebrow instead — same artwork, same
   --bb-icon custom property, one row instead of two. */
.bb-cards--compact > .wp-block-column::before {
	display: none;
}

.bb-cards--compact > .wp-block-column > .bb-eyebrow {
	display: flex;
	align-items: center;
	gap: 0.5em;
}

.bb-cards--compact > .wp-block-column > .bb-eyebrow::before {
	content: "";
	flex: none;
	width: 1.05em;
	height: 1.05em;
	background-color: var(--wp--preset--color--terracotta-text);
	-webkit-mask-image: var(--bb-icon);
	mask-image: var(--bb-icon);
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
}

.has-forest-background-color .bb-cards--compact > .wp-block-column > .bb-eyebrow::before,
.has-forest-deep-background-color .bb-cards--compact > .wp-block-column > .bb-eyebrow::before {
	background-color: var(--wp--preset--color--terracotta-on-dark);
}

/* --------------------------------------------------------------------------
   Reveal
   --------------------------------------------------------------------------
   Long copy shown two lines at a time, opened by touching it.

   A native <details> whose <summary> IS the paragraph. That is the whole trick:
   the text is not duplicated into a teaser and a body, there is no JavaScript,
   the control is keyboard-operable and announced as a disclosure for free, and
   it still reads if scripts never run. Collapsed, the copy fades away under a
   chevron rather than stopping at a hard edge, so the control costs no row of
   its own — which is the point in a card whose height is shared with its
   neighbours.

   Markup (a core/html block, since <details> is not a core block):

     <details class="bb-reveal"><summary class="bb-reveal-text">
       <span class="bb-reveal-copy">…</span>
       <span class="bb-reveal-cue" aria-hidden="true"></span>
     </summary></details>

   --bb-reveal-lines changes how much shows. The fade is painted in the surface
   colour, so a reveal on a ground other than .bb-panel's sets --bb-reveal-fade
   to that ground or the last line ends in a smear of the wrong colour. */

:root {

	/*
	 * Lets `height: auto` be animated, which is what makes opening a reveal a
	 * movement rather than a jump. Inherited, so it has to be set high; harmless
	 * everywhere else, since nothing transitions height unless it says so.
	 */
	interpolate-size: allow-keywords;
}

.bb-reveal {
	--bb-reveal-lines: 2;
	--bb-reveal-fade: var(--wp--preset--color--base-alt);

	margin-block: 0;
}

.bb-reveal-text {
	display: block;
	position: relative;
	cursor: pointer;
	list-style: none;
	border-radius: 4px;
	padding-inline-end: 1.6em;
	height: calc( var( --bb-reveal-lines ) * 1lh );
	overflow: hidden;
}

@supports not ( height: 1lh ) {

	.bb-reveal-text {
		height: calc( var( --bb-reveal-lines ) * 1.45em );
	}
}

/* Safari still draws summary's disclosure triangle through this pseudo. */
.bb-reveal-text::-webkit-details-marker {
	display: none;
}

/* Left to right, not top to bottom: the cut is mid-line, so what needs to
   dissolve is the end of the last line, not the line itself. */
.bb-reveal-text::before {
	content: "";
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	height: 1.35em;
	pointer-events: none;
	background: linear-gradient( to right, transparent 55%, var( --bb-reveal-fade ) 88% );
}

.bb-reveal[ open ] > .bb-reveal-text {
	height: auto;
}

.bb-reveal[ open ] > .bb-reveal-text::before {
	opacity: 0;
}

.bb-reveal-cue {
	position: absolute;
	inset-inline-end: 0.1em;
	bottom: 0.42em;
	width: 0.5em;
	height: 0.5em;
	border-right: 1.8px solid var(--wp--preset--color--terracotta-text);
	border-bottom: 1.8px solid var(--wp--preset--color--terracotta-text);
	transform: rotate( 45deg ) translate( -0.05em, -0.05em );
}

.bb-reveal[ open ] > .bb-reveal-text > .bb-reveal-cue {
	bottom: 0.18em;
	transform: rotate( -135deg ) translate( -0.05em, -0.05em );
}

.bb-reveal-text:hover .bb-reveal-cue {
	border-color: var(--wp--preset--color--terracotta);
}

.bb-reveal-text:focus-visible {
	outline: 2px solid var(--wp--preset--color--terracotta-text);
	outline-offset: 4px;
}

@media ( prefers-reduced-motion: no-preference ) {

	.bb-reveal-text {
		transition: height 320ms cubic-bezier( 0.22, 0.61, 0.36, 1 );
	}

	.bb-reveal-text::before {
		transition: opacity 180ms ease;
	}

	.bb-reveal-cue {
		transition:
			transform 320ms cubic-bezier( 0.22, 0.61, 0.36, 1 ),
			bottom 320ms cubic-bezier( 0.22, 0.61, 0.36, 1 ),
			border-color 150ms ease;
	}
}

/* This year's dates for a form the hub has closed, printed by
   [bb_form_window] (inc/website-settings.php) immediately BEFORE the buttons.

   Before, not after, because of the rule directly above: the buttons are
   pushed to the panel's bottom edge so a row of cards lines up, and a note
   sitting under them would break that alignment the moment two cards' notes
   differ in length.

   Deliberately quiet rather than alarming. The button still works, the form is
   simply not open yet, and a warning-coloured box would read as an error on a
   page whose job is to encourage an application. */
.bb-form-window {
	margin-block: 0;
	padding-inline-start: 0.75rem;
	border-inline-start: 3px solid var(--wp--preset--color--sage);
	font-size: 0.95rem;
	line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Steps
   --------------------------------------------------------------------------
   A numbered process, applied to an ordinary ordered core/list block.

   Distinct from .bb-timeline (sections.css), which needs hand-authored markup
   with a year span and a text span per item. This one needs nothing but a list
   a staff member can type into, which is the whole point: the steps of a
   process are exactly the kind of content that changes without a developer. */

.bb-steps {
	list-style: none;
	counter-reset: bb-step;
	margin-block: 1.5rem 0;
	padding-inline-start: 0;
	display: grid;
	gap: clamp( 0.9rem, 2vw, 1.4rem );
}

.bb-steps > li {
	counter-increment: bb-step;
	position: relative;
	padding-inline-start: 3.1rem;
	min-height: 2.2rem;
}

.bb-steps > li::before {
	content: counter( bb-step );
	position: absolute;
	inset-inline-start: 0;
	inset-block-start: -0.1rem;
	width: 2.2rem;
	height: 2.2rem;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background-color: var(--wp--preset--color--terracotta-text);
	color: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	line-height: 1;
}

/* The connecting rail, drawn between the markers rather than through them. */
.bb-steps > li:not( :last-child )::after {
	content: "";
	position: absolute;
	inset-inline-start: 1.05rem;
	inset-block-start: 2.3rem;
	bottom: calc( var(--wp--preset--spacing--30) * -1 );
	width: 2px;
	background-color: rgba( 143, 69, 41, 0.28 );
}

.bb-steps strong {
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
	color: var(--wp--preset--color--forest);
}

.has-forest-background-color .bb-steps strong,
.has-forest-deep-background-color .bb-steps strong {
	color: inherit;
}

/* --------------------------------------------------------------------------
   Disclosure
   --------------------------------------------------------------------------
   Styles core/details globally — no class required, so every disclosure on the
   site matches whether or not whoever added it knew this file existed.

   CONSTRAINT, from motion.css and chrome.css: nothing but content-visibility
   may be declared on ::details-content. Animating disclosure means animating an
   element INSIDE the details, the way .bb-mega__panel does. Nothing here
   animates, which keeps it out of the way of that rule entirely. */

.wp-block-details {
	border-block-end: 1px solid rgba( 201, 162, 39, 0.5 );
	padding-block: 0.9rem;
}

.wp-block-details > summary {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 600;
	color: var(--wp--preset--color--forest);
	cursor: pointer;
	list-style: none;
	display: flex;
	align-items: baseline;
	gap: 0.65rem;
}

.wp-block-details > summary::-webkit-details-marker {
	display: none;
}

/* The marker is drawn rather than inherited so it can carry the theme's color
   and rotate on open. */
.wp-block-details > summary::before {
	content: "";
	flex: 0 0 auto;
	width: 0.5rem;
	height: 0.5rem;
	border-right: 2px solid var(--wp--preset--color--terracotta-text);
	border-bottom: 2px solid var(--wp--preset--color--terracotta-text);
	transform: rotate( -45deg );
	transition: transform 160ms ease;
}

.wp-block-details[open] > summary::before {
	transform: rotate( 45deg );
}

.wp-block-details > summary:focus-visible {
	outline: 2px solid var(--wp--preset--color--terracotta-text);
	outline-offset: 3px;
}

.has-forest-background-color .wp-block-details,
.has-forest-deep-background-color .wp-block-details {
	border-block-end-color: rgba( 201, 162, 39, 0.4 );
}

.has-forest-background-color .wp-block-details > summary,
.has-forest-deep-background-color .wp-block-details > summary {
	color: inherit;
}

.has-forest-background-color .wp-block-details > summary::before,
.has-forest-deep-background-color .wp-block-details > summary::before {
	border-color: var(--wp--preset--color--terracotta-on-dark);
}

/* --------------------------------------------------------------------------
   Tables
   --------------------------------------------------------------------------
   Core ships a grey bordered table that belongs to no design system. This is
   the house treatment, applied to the core table block and to any hand-authored
   table that opts in, so the two never diverge. */

.wp-block-table table,
.bb-table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--wp--preset--font-size--small);
}

.wp-block-table :is( th, td ),
.bb-table :is( th, td ) {
	border: 0;
	border-block-end: 1px solid rgba( 143, 69, 41, 0.18 );
	padding: 0.7rem 0.85rem;
	text-align: start;
	vertical-align: baseline;
}

.wp-block-table thead :is( th, td ),
.bb-table thead :is( th, td ) {
	font-family: var(--wp--preset--font-family--body);
	font-weight: 600;
	font-size: var(--wp--preset--font-size--x-small);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--forest);
	border-block-end-width: 2px;
	border-block-end-color: rgba( 143, 69, 41, 0.35 );
}

.wp-block-table tbody th,
.bb-table tbody th {
	font-weight: 600;
	color: var(--wp--preset--color--forest);
}

.wp-block-table tbody tr:last-child :is( th, td ),
.bb-table tbody tr:last-child :is( th, td ) {
	border-block-end: 0;
}

.wp-block-table figcaption,
.bb-table caption {
	font-size: var(--wp--preset--font-size--x-small);
	color: var(--wp--preset--color--contrast);
	opacity: 0.8;
	text-align: start;
	margin-block-end: 0.6rem;
}

/* A table wider than its container scrolls itself rather than the page. */
.wp-block-table,
.bb-table-scroll {
	overflow-x: auto;
}

/* --------------------------------------------------------------------------
   Data bars
   --------------------------------------------------------------------------
   A data table whose rows carry a proportional bar behind them.

   THE MAINTENANCE CONTRACT, which is the reason this is built the way it is:
   the row carries the RAW NUMBER and the table carries the MAXIMUM, so whoever
   updates this once a year types the figure from the committee's report and
   nothing else. No percentages, no arithmetic, and a record year means changing
   --max once rather than recomputing every row.

       <table class="bb-bars" style="--max:86900">
         <tr style="--v:86900"> ... </tr>

   The bar is a background on the row, so there is no extra markup per row, no
   empty cell for a screen reader to announce, and the table stays a plain
   readable table if the styles never arrive. */

.bb-bars {
	--bb-bar-fill: rgba( 182, 99, 66, 0.3 );
	--bb-bar-fill-strong: rgba( 143, 69, 41, 0.42 );
}

.bb-bars tbody tr {
	background-image: linear-gradient(
		to right,
		var(--bb-bar-fill) 0 calc( 100% * var(--v, 0) / var(--max, 1) ),
		transparent calc( 100% * var(--v, 0) / var(--max, 1) )
	);
	background-repeat: no-repeat;
}

/* The most recent year, or any row worth pointing at. Deliberately NOT gold:
   gold on cream is 1.95:1, which would make the row this is meant to emphasize
   the hardest one on the page to see. */
.bb-bars tbody tr.is-highlight {
	--bb-bar-fill: var(--bb-bar-fill-strong);
	font-weight: 600;
}

.bb-bars :is( th, td ) {
	position: relative;
	white-space: nowrap;
}

/* Numeric columns read as a column when they share an edge. */
.bb-bars :is( th, td ) + :is( th, td ) {
	text-align: end;
}

.bb-bars thead :is( th, td ) + :is( th, td ) {
	text-align: end;
}

@media ( max-width: 34rem ) {

	.bb-bars {
		font-size: var(--wp--preset--font-size--x-small);
	}

	.bb-bars :is( th, td ) {
		padding: 0.45rem 0.5rem;
	}
}

/* --------------------------------------------------------------------------
   Milestones
   --------------------------------------------------------------------------
   A sequence read left to right: a marker, a name, and a line of explanation,
   with a rule running through the markers to say "these belong in this order."

   Applied to a core/columns block, so each milestone is an ordinary column a
   staff member can edit, duplicate or reorder in the dashboard. The connecting
   rule is drawn across the whole row by CSS, so adding a fourth milestone needs
   no adjustment anywhere.

   Distinct from .bb-timeline (sections.css), which runs VERTICALLY and needs
   hand-authored year and text spans, and from .bb-steps above, which numbers
   itself. This one is for named points in time. */

.bb-milestones.wp-block-columns {
	position: relative;
	gap: 0;
	margin-block-start: 2rem;
}

/* The rule sits behind the markers and stops short of both ends, so the
   sequence reads as bounded rather than running off the page. */
.bb-milestones.wp-block-columns::before {
	content: "";
	position: absolute;
	inset-inline: 12%;
	inset-block-start: 1.05rem;
	height: 2px;
	background-color: var(--wp--preset--color--terracotta);
	opacity: 0.45;
}

.bb-milestones.wp-block-columns > .wp-block-column {
	position: relative;
	text-align: center;
	padding-inline: clamp( 0.5rem, 1.6vw, 1.25rem );
}

/* The marker: a year in a filled disc, which also masks the rule behind it. */
.bb-milestone-year {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 4.6rem;
	padding: 0.3rem 0.9rem;
	border-radius: 999px;
	background-color: var(--wp--preset--color--terracotta-text);
	color: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	line-height: 1.4;
	margin-block: 0 0.9rem;
	font-variant-numeric: tabular-nums;
}

.has-forest-background-color .bb-milestone-year,
.has-forest-deep-background-color .bb-milestone-year {
	background-color: var(--wp--preset--color--terracotta-on-dark);
	color: var(--wp--preset--color--forest-deep);
}

.bb-milestones .wp-block-heading {
	font-size: var(--wp--preset--font-size--large);
	margin-block: 0 0.4rem;
	text-wrap: balance;
}

.bb-milestones p:not( .bb-milestone-year ) {
	font-size: var(--wp--preset--font-size--small);
	margin-block: 0 0.5rem;
}

/* An acronym spelled out with the letters that make it emphasized — the device
   BASIC's own materials use. */
.bb-initials strong {
	color: var(--wp--preset--color--terracotta-text);
	font-weight: 700;
}

.has-forest-background-color .bb-initials strong,
.has-forest-deep-background-color .bb-initials strong {
	color: var(--wp--preset--color--terracotta-on-dark);
}

@media ( max-width: 781px ) {

	/* Core stacks columns at this width, where a horizontal rule would be
	   nonsense. The sequence becomes vertical with the markers still aligned. */
	.bb-milestones.wp-block-columns::before {
		inset-inline: auto;
		inset-block: 1.05rem 1.05rem;
		left: calc( 50% - 1px );
		width: 2px;
		height: auto;
	}

	.bb-milestones.wp-block-columns > .wp-block-column + .wp-block-column {
		margin-block-start: 1.75rem;
	}
}

/* --------------------------------------------------------------------------
   Segments
   --------------------------------------------------------------------------
   One bar divided into parts, for a total made up of groups — the part-to-whole
   counterpart to .bb-bars above, which compares separate rows.

   Same maintenance contract as .bb-bars, for the same reason: each segment
   carries its RAW COUNT and the bar carries the TOTAL, so whoever updates this
   types the numbers from the report and nothing else.

       <div class="bb-segments" style="--total:45">
         <span style="--v:14"> ... </span>

   The key below it is a real list, so every figure is readable as text whether
   or not the bar renders. */

.bb-segments {
	display: flex;
	width: 100%;
	height: 2.6rem;
	border-radius: 6px;
	overflow: hidden;
	margin-block: 1.5rem 0;
	background-color: var(--wp--preset--color--base-alt);
}

.bb-segments > * {
	flex: 0 0 calc( 100% * var(--v, 0) / var(--total, 1) );
	min-width: 2px;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--base);
	overflow: hidden;
	white-space: nowrap;
}

/* Four tones stepping from terracotta to forest. They are distinguishable by
   lightness as well as hue, and each carries cream text above 4.5:1. */
.bb-segments > :nth-child( 1 ) { background-color: #8F4529; }
.bb-segments > :nth-child( 2 ) { background-color: #A15A38; }
.bb-segments > :nth-child( 3 ) { background-color: #5C5A38; }
.bb-segments > :nth-child( 4 ) { background-color: #393E2E; }

.bb-segments-key {
	list-style: none;
	margin-block: 1rem 0;
	padding-inline-start: 0;
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 15rem, 1fr ) );
	gap: 0.6rem 1.5rem;
}

.bb-segments-key > li {
	position: relative;
	padding-inline-start: 1.5rem;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.45;
}

.bb-segments-key > li::before {
	content: "";
	position: absolute;
	inset-inline-start: 0;
	inset-block-start: 0.42em;
	width: 0.75rem;
	height: 0.75rem;
	border-radius: 3px;
}

.bb-segments-key > :nth-child( 1 )::before { background-color: #8F4529; }
.bb-segments-key > :nth-child( 2 )::before { background-color: #A15A38; }
.bb-segments-key > :nth-child( 3 )::before { background-color: #5C5A38; }
.bb-segments-key > :nth-child( 4 )::before { background-color: #393E2E; }

.bb-segments-key strong {
	font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Section sub-navigation
   --------------------------------------------------------------------------
   A row of pill links that says "this section has more than one page," placed
   directly under a hero so it is visible before anything has been scrolled.

   Applied to an ordinary core/list block, so the links are list items a staff
   member adds, removes and reorders in the dashboard — the same way they would
   edit any other list.

   Deliberately light: small pills on a quiet strip, so it reads as navigation
   chrome rather than as content competing with the section below it. */

.bb-subnav {
	list-style: none;
	margin-block: 0;
	padding-inline-start: 0;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 0.55rem;
}

.bb-subnav > li {
	margin: 0;
}

.bb-subnav > li > a {
	display: inline-block;
	padding: 0.32em 0.9em;
	border-radius: 999px;
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--terracotta-text);
	border: 1px solid rgba( 143, 69, 41, 0.28 );
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	text-decoration: none;
	line-height: 1.4;
	transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
}

/* The page you are on. Marked with aria-current in the markup, so the styling
   and the announcement come from one source rather than two. */
.bb-subnav > li > a[aria-current="page"] {
	background-color: var(--wp--preset--color--forest);
	border-color: var(--wp--preset--color--forest);
	color: var(--wp--preset--color--base);
	cursor: default;
}

.bb-subnav > li > a:hover,
.bb-subnav > li > a:focus-visible {
	background-color: var(--wp--preset--color--forest);
	border-color: var(--wp--preset--color--forest);
	color: var(--wp--preset--color--base);
}

/* The label that introduces the row, when there is one. */
.bb-subnav-label {
	text-align: center;
	margin-block: 0;
	opacity: 0.75;
	white-space: nowrap;
}

/* The bar itself: deliberately shallow. It is navigation chrome sitting
   between a hero and the page's first real section, and every pixel it takes
   is a pixel of the section below pushed under the fold. */
.bb-subnav-bar {
	padding-block: 0.7rem;

	/*
	 * The horizontal padding has to be declared here, and that is easy to miss.
	 *
	 * Core adds `has-global-padding` — the class that carries the page gutter —
	 * only to CONSTRAINED layout blocks. This bar is a FLEX layout block,
	 * because its label and its pills share one row, so it gets no gutter at all
	 * and its contents run to the very edge of the display. On a width where the
	 * three pills only just fit, the outer two touch the screen edges.
	 */
	padding-inline: var(--wp--preset--spacing--40);
}

/* Keep the row aligned with the page's own measure on wide displays rather than
   letting it drift out toward the edges. */
.bb-subnav-bar > .wp-block-list,
.bb-subnav-bar > .bb-subnav-label {
	max-width: 100%;
}

.bb-subnav-bar .wp-block-list {
	margin-block: 0;
}

.has-forest-background-color .bb-subnav > li > a,
.has-forest-deep-background-color .bb-subnav > li > a {
	background-color: transparent;
	border-color: rgba( 239, 231, 219, 0.4 );
	color: var(--wp--preset--color--base);
}

.has-forest-background-color .bb-subnav > li > a:hover,
.has-forest-deep-background-color .bb-subnav > li > a:hover {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--terracotta-text);
}

@media ( prefers-reduced-motion: reduce ) {

	.bb-subnav > li > a {
		transition: none;
	}
}

/* --------------------------------------------------------------------------
   Icon badges
   --------------------------------------------------------------------------
   The small round icon that sits above a panel heading, matching the gold
   glyphs in the home page's impact band.

   The icon is a MASK, not an <img> or inline SVG, for two reasons: it takes
   currentColor so it inherits whatever the panel is doing, and it keeps the
   markup free of SVG so a staff member editing the panel sees only text.

   To use: add one of the bb-icon-* classes alongside .bb-panel.
   To add an icon: define one more class setting --bb-icon to a data URI.

   Safari still wants the -webkit- prefixed mask properties, which is why the
   theme's other mask rules carry them too. */

.bb-icon-cap,
.bb-icon-doc,
.bb-icon-calendar,
.bb-icon-gift,
.bb-icon-compass {
	--bb-icon-size: 1.9rem;
}

/*
 * The glyph is the mask and nothing else — no enclosing disc. That matches the
 * gold line icons in the home page's impact band, and it means the icon takes
 * whatever color is set here, so the on-dark variant is one extra rule rather
 * than a second set of artwork.
 *
 * A mask made from an SVG uses the image's ALPHA channel, so the artwork must
 * be an opaque glyph on a TRANSPARENT ground. An opaque background of any color
 * would make the whole box paint — which is exactly the solid blob you get if
 * you draw a filled circle behind the glyph and expect it to punch through.
 */
.bb-icon-cap::before,
.bb-icon-doc::before,
.bb-icon-calendar::before,
.bb-icon-gift::before,
.bb-icon-compass::before {
	content: "";
	display: block;
	width: var(--bb-icon-size);
	height: var(--bb-icon-size);
	margin-block-end: 0.75rem;
	background-color: var(--wp--preset--color--terracotta-text);
	-webkit-mask-image: var(--bb-icon);
	mask-image: var(--bb-icon);
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	isolation: isolate;
}

.has-forest-background-color :is( .bb-icon-cap, .bb-icon-doc, .bb-icon-calendar, .bb-icon-gift, .bb-icon-compass )::before,
.has-forest-deep-background-color :is( .bb-icon-cap, .bb-icon-doc, .bb-icon-calendar, .bb-icon-gift, .bb-icon-compass )::before {
	background-color: var(--wp--preset--color--terracotta-on-dark);
}

/* A mortarboard, for starting or finishing school. */
.bb-icon-cap {
	--bb-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3 1 9l11 6 9-4.91V17h2V9z'/%3E%3Cpath d='M5 13.18v4L12 21l7-3.82v-4L12 17z'/%3E%3C/svg%3E");
}

/* A clipboard with a tick, for proof and paperwork. */
.bb-icon-doc {
	--bb-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 3h-4.18C14.4 1.84 13.3 1 12 1s-2.4.84-2.82 2H5a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2m-7 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2m-2 15-4-4 1.41-1.41L10 15.17l6.59-6.59L18 10z'/%3E%3C/svg%3E");
}

/* A calendar, for dates and events. */
.bb-icon-calendar {
	--bb-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 12h-5v5h5zM16 1v2H8V1H6v2H5a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2h-1V1zm3 20H5V8h14z'/%3E%3C/svg%3E");
}

/* A heart, for giving. */
.bb-icon-gift {
	--bb-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m12 21.35-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54z'/%3E%3C/svg%3E");
}

/* A compass needle, for finding the way to another page. */
.bb-icon-compass {
	--bb-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20m2.19 12.19L6 18l3.81-8.19L18 6z'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   Photo treatments
   --------------------------------------------------------------------------
   The site's own organic image shapes are already defined site-wide in
   style.css as .bb-shape-blob, .bb-shape-blob-soft, .bb-shape-blob-card and
   .bb-shape-lozenge, and a staff member can put those straight onto a core
   image block. All that is missing is making the photograph FILL the shape,
   because an image inside a rounded figure still ends up letterboxed unless
   something gives it an aspect ratio.

   .bb-photo-fill does that and nothing else, so it composes with whichever
   shape class is chosen rather than duplicating any of them. */

.bb-photo-fill img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.bb-photo-portrait {
	aspect-ratio: 4 / 5;
}

.bb-photo-landscape {
	aspect-ratio: 3 / 2;
}

.bb-photo-portrait img,
.bb-photo-landscape img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Core centers a constrained image block; a shaped hero photo should fill its
   column instead. */
.wp-block-image.bb-photo-fill,
.wp-block-image.bb-photo-portrait,
.wp-block-image.bb-photo-landscape {
	margin-inline: 0;
}

/* --------------------------------------------------------------------------
   The masthead photograph on narrow screens
   --------------------------------------------------------------------------
   It is dropped, not shrunk, below the width where core stacks a columns block.

   This is the theme's own precedent rather than a new idea: art-direction.css
   hides .bb-hero__art below 900px on the home page, and records that the
   resulting loss of a view-transition capture "is correct, not a bug."

   The reasoning is the same here and worth stating. Once the columns stack, the
   photograph stops being half of a composition and becomes a tall block sitting
   between the headline and the first thing a student actually needs — which on
   this page is the row of actions. A smaller photograph would still cost that
   vertical space without earning it. The headline carries the message on its
   own; the photographs further down the page carry the feeling.

   Keyed to a class on the column rather than to :has() or :last-child, so it
   survives a staff member reordering the columns and needs no modern selector.

   781px is core's own columns stacking breakpoint. Matching it exactly means
   the photograph disappears on the same resize step that changes the layout,
   rather than leaving an empty column behind for a range of widths. */

@media ( max-width: 781px ) {

	.bb-hero-split .bb-hero-media {
		display: none;
	}
}

/* --------------------------------------------------------------------------
   Section continuity
   --------------------------------------------------------------------------
   A group of pages that belong together should not feel like separate
   documents. This theme already runs cross-document view transitions on every
   page (motion.css declares `@view-transition`), so naming the parts that are
   COMMON to every page in a section makes the browser morph them instead of
   redrawing them: the toolbar stays put, the eyebrow holds, and the photograph
   cross-fades to the new one.

   THE HARD RULE, documented at art-direction.css's motion section and worth
   repeating because breaking it is silent: a view-transition-name must match
   EXACTLY ONE rendered element per document. Two elements sharing a name makes
   ViewTransition.ready reject, and the browser then skips transitions on every
   page of the site — not just this one. Every selector below is scoped to a
   wrapper that appears once.

   `view-transition-name` also forms a stacking context at all times, which is
   why these are on layout wrappers rather than on anything that needs to
   escape its parent. */

.bb-subnav-bar {
	view-transition-name: bb-section-nav;
}

.bb-hero-split .bb-eyebrow {
	view-transition-name: bb-section-eyebrow;
}

/* The one image inside the section masthead. Scoped to .bb-hero-split because
   .wp-block-image appears many times on a page with a gallery on it. */
.bb-hero-split .wp-block-image img {
	view-transition-name: bb-section-hero-media;
	/*
	 * THE NAME IS ON THE <img>, NOT ON THE FIGURE AROUND IT, and that is what
	 * makes a clean slide possible. The figure carries .bb-shape-blob-soft, so
	 * naming the figure would capture an already-rounded snapshot; sliding that
	 * drags its curved edge through the frame. Naming the image captures a
	 * plain rectangle, and motion.css gives the WINDOW the organic shape, so
	 * two rectangular photographs slide inside a fixed blob.
	 *
	 * Deliberately NOT bb-section-swap. That class sequences its fades, which
	 * is right for text and wrong here — see motion.css.
	 */
	view-transition-class: bb-media;
}

/* The headline. The eyebrow above it holds still and the toolbar below it holds
   still; this is the part that visibly changes, so it is the part that moves.
   There is exactly one heading inside the masthead, and it is not an ancestor
   or a descendant of any other named element — names must never nest. */
.bb-hero-split .wp-block-heading {
	view-transition-name: bb-section-headline;
	view-transition-class: bb-section-swap;
}

/* --------------------------------------------------------------------------
   Onward links
   --------------------------------------------------------------------------
   Cards that carry the reader to a related page. Built on .bb-panel, so the
   surface is already right; this adds the affordance that says the card leads
   somewhere. */

.bb-onward .wp-block-column {
	transition: transform 160ms ease, box-shadow 160ms ease;
}

.bb-onward .wp-block-column:hover {
	transform: translateY( -2px );
	box-shadow: 0 6px 20px rgba( 42, 42, 36, 0.12 );
}

.bb-onward-link {
	font-weight: 600;
	text-decoration: none;
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
}

.bb-onward-link::after {
	content: "\2192";
	transition: transform 160ms ease;
}

.bb-onward .wp-block-column:hover .bb-onward-link::after {
	transform: translateX( 3px );
}

@media ( prefers-reduced-motion: reduce ) {

	.bb-onward .wp-block-column,
	.bb-onward-link::after {
		transition: none;
	}
}

/* --------------------------------------------------------------------------
   Brush stroke
   --------------------------------------------------------------------------
   The tapered rule that sits under section titles across this site.

   basic_borrego_brush() emits it as inline SVG for pattern files. Page content
   authored in the dashboard cannot call a PHP function, so the same stroke is
   available here as a class on any heading — same path, same proportions, no
   markup. */

.bb-title-brush::after {
	content: "";
	display: block;
	width: 7.5rem;
	height: 0.55rem;
	margin-block-start: 0.7rem;
	background-color: var(--wp--preset--color--terracotta);
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 12' preserveAspectRatio='none'%3E%3Cpath d='M2 8.2c22-3.4 52-5.4 84-5.8 30-.4 68 .8 112 3.4-40 3-78 4.2-112 4-32-.2-62-.6-84-1.6Z' fill='%23000'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 12' preserveAspectRatio='none'%3E%3Cpath d='M2 8.2c22-3.4 52-5.4 84-5.8 30-.4 68 .8 112 3.4-40 3-78 4.2-112 4-32-.2-62-.6-84-1.6Z' fill='%23000'/%3E%3C/svg%3E");
	-webkit-mask-size: 100% 100%;
	mask-size: 100% 100%;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
}

.has-forest-background-color .bb-title-brush::after,
.has-forest-deep-background-color .bb-title-brush::after {
	background-color: var(--wp--preset--color--terracotta-on-dark);
}

/* Centerd headings want a centered stroke. */
.bb-title-brush.has-text-align-center::after {
	margin-inline: auto;
}

/* --------------------------------------------------------------------------
   Collage
   --------------------------------------------------------------------------
   A core/gallery that reads as a scrapbook rather than a grid: images take
   alternating heights and a slight rotation, the way photographs pinned to a
   board do.

   Built for galleries that GROW. New photographs are dropped in through the
   media library and land in the rhythm automatically, because the variation
   comes from :nth-child rather than from per-image markup. */

.bb-collage.wp-block-gallery {
	gap: clamp( 0.6rem, 1.6vw, 1.1rem );
}

/* The same asymmetric card shape the home page's program cards use, so a wall
   of graduate photographs reads as part of this site rather than as a gallery
   dropped into it. */
.bb-collage.wp-block-gallery .wp-block-image {
	border-radius: 26% 26% 22% 22% / 7% 7% 5% 5%;
	overflow: hidden;
	isolation: isolate;
	aspect-ratio: 4 / 5;
	box-shadow: 0 3px 14px rgba( 42, 42, 36, 0.16 );
}

.bb-collage.wp-block-gallery .wp-block-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.bb-collage.wp-block-gallery .wp-block-image:nth-child( 3n + 1 ) {
	transform: rotate( -1.2deg );
}

.bb-collage.wp-block-gallery .wp-block-image:nth-child( 3n + 2 ) {
	transform: rotate( 0.8deg );
}

.bb-collage.wp-block-gallery .wp-block-image:nth-child( 3n ) {
	transform: rotate( -0.5deg );
}

@media ( prefers-reduced-motion: reduce ) {

	.bb-collage.wp-block-gallery .wp-block-image {
		transform: none;
	}
}

/* --------------------------------------------------------------------------
   Photographs at phone widths
   --------------------------------------------------------------------------
   The same rule the home and About sections follow in art-direction.css: below
   900px a photograph is shown whole, at its own proportions, rather than trimmed
   to a designed shape. In a two-column wall of graduate photographs the trimming
   was severe — a landscape shot of a student beside a plane lost 40% of its
   width to a portrait card, which is most of the plane and one edge of the
   student.

   Cards now hug their photograph instead of stretching to the tallest one in the
   row, so the wall is ragged where the photographs are. That is the honest
   result: these are snapshots people sent in, not a shoot with one crop.

   `:not( #individual-image )` is load-bearing, not decoration. Core's gallery
   stylesheet uses that ID-specificity hack on both the figure and the image, so
   a plain `.bb-collage figure.wp-block-image img` selector loses to it and these
   rules silently do nothing. */

@media ( max-width: 899px ) {

	.bb-photo-fill,
	.bb-photo-portrait,
	.bb-photo-landscape {
		aspect-ratio: auto;
	}

	.bb-photo-fill img,
	.bb-photo-portrait img,
	.bb-photo-landscape img {
		height: auto;
	}

	.bb-collage.wp-block-gallery.has-nested-images {
		align-items: flex-start;
	}

	.bb-collage.wp-block-gallery.has-nested-images
		figure.wp-block-image:not( #individual-image ) {
		aspect-ratio: auto;
		align-self: flex-start;
	}

	/* `fill` is safe here, and only here, because the box above has just been
	   made the image's own ratio — there is nothing left to distort. */
	.bb-collage.wp-block-gallery.has-nested-images
		figure.wp-block-image:not( #individual-image ) img {
		flex: 0 0 auto;
		width: 100%;
		height: auto;
		object-fit: fill;
	}
}

/* --------------------------------------------------------------------------
   Media and text
   --------------------------------------------------------------------------
   Core's media-text block arrives unstyled in this theme. Rounding the image
   and giving the text column a little air is the whole treatment — the block
   already handles the two-column mechanics. */

.wp-block-media-text .wp-block-media-text__media img {
	border-radius: 10px;
}

.wp-block-media-text .wp-block-media-text__content {
	padding-inline: clamp( 1rem, 3vw, 2.5rem );
}

/* --------------------------------------------------------------------------
   Eyebrow on dark
   --------------------------------------------------------------------------
   .bb-eyebrow (style.css) inherits its color. Over a photograph or a dark
   band, inheriting is not good enough to promise a contrast ratio, so the
   on-dark case is named. */

.has-forest-background-color .bb-eyebrow,
.has-forest-deep-background-color .bb-eyebrow,
.wp-block-cover .bb-eyebrow {
	color: var(--wp--preset--color--terracotta-on-dark);
}

/* --------------------------------------------------------------------------
   Section rhythm
   --------------------------------------------------------------------------
   A composed page has no vertical rhythm of its own — .bb-main--flush zeroes
   the article padding. Sections that are not bands need to declare their own,
   and doing it with a class keeps every page's rhythm identical instead of
   depending on whoever typed the padding values into the sidebar that day. */

.bb-section {
	padding-block: clamp( 3rem, 6vw, 5rem );
}

.bb-section--tight {
	padding-block: clamp( 2rem, 4vw, 3rem );
}

/* A section whose ground is the SAME as the one above it does not need its own
   top padding — the section above has already separated them, and paying twice
   turns a run of plain sections into a row of holes. Only where the ground
   actually changes (a band, a tinted section) does the join need both halves,
   so this is opt-in per section rather than a rule about adjacency. */
.bb-section--joined {
	padding-block-start: 0;
}

/* --------------------------------------------------------------------------
   Subnav bar, seated
   --------------------------------------------------------------------------
   The bar's own padding is shallow on purpose (see .bb-subnav-bar above), but
   it was still floating in ~100px of space on each side: the section rhythm
   above adds clamp(3rem, 6vw, 5rem) of padding, and core's flow layout adds a
   1.5rem blockGap margin, on BOTH sides of it. The result read as the end of
   the page — a visitor could see the three pills and not realize content
   followed. Seat it against the hero above and the section below instead.

   Specificity does the work: core's flow rule is `:where(.is-layout-flow) > *`
   at (0,0,0), so these plain class selectors win without !important, and
   `.bb-subnav-bar + .bb-section` at (0,2,0) also beats .bb-section--tight. */

.bb-subnav-bar {
	margin-block-start: 0;
}

.bb-subnav-bar + * {
	margin-block-start: 0;
}

.bb-subnav-bar + .bb-section {
	padding-block-start: clamp( 1.25rem, 2.5vw, 1.75rem );
}

/* `~`, not `+`: a wp:html block of prefetch <link>s sits between the masthead
   and the bar. The links have no box, so they cost nothing visually, but they
   do break adjacency. The masthead is the only section preceding the bar on
   every page that has one.

   Kept as its own rule rather than merged into the list above: an unsupported
   selector invalidates the ENTIRE list it appears in, and the space below the
   bar is the part that matters most. */
.bb-section:has( ~ .bb-subnav-bar ) {
	padding-block-end: clamp( 1.25rem, 2.5vw, 1.75rem );
}

/* --------------------------------------------------------------------------
   Volunteer participation form
   --------------------------------------------------------------------------
   [basic_borrego_participate_form], rendered by inc/participate.php.

   IT LIVES HERE RATHER THAN IN A PAGE-SCOPED FILE because it is a component,
   not a composition: staff can put the shortcode on any page, and a stylesheet
   gated on one slug would stop applying the moment they did. components.css is
   already on every page, so the form is styled wherever it lands.

   Everything below is layout and affordance only. The palette is theme.json's,
   and the type is inherited — a form that invents its own typography is how a
   page ends up looking like two sites stapled together. */

.bb-participate {
	margin-block: clamp( 1.5rem, 3vw, 2.5rem );
}

.bb-participate__form {
	max-width: 46rem;
}

/* THE PANEL. `.bb-donate-form` (sections.css) is the precedent and the values
   are its values — the two are the only full-width interactive cards on the
   site and they should read as the same object. */
.bb-participate__panel {
	display: flex;
	flex-direction: column;
	gap: clamp( 1.25rem, 2.5vw, 1.75rem );
	padding: clamp( 1rem, 2.5vw, 1.5rem );
	border: 1px solid rgba( 57, 62, 46, 0.14 );
	border-radius: 14px;
	background-color: var(--wp--preset--color--base-alt);
	box-sizing: border-box;
}

/* A fieldset is a grid/flex item with `min-inline-size: min-content` baked in by
   the UA, which is what makes a long option name push a form wider than its
   container. Zeroing it is not cosmetic. */
.bb-participate__section {
	min-inline-size: 0;
	margin: 0;
	padding: 0;
	border: 0;
}

/* `.bb-eyebrow`'s treatment (style.css), applied rather than reused: a <legend>
   cannot carry the class through PHP without the class also having to exist in
   the editor's stylesheet, and the four declarations are the whole of it. */
.bb-participate__legend {
	padding: 0;
	margin-block-end: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	color: var(--wp--preset--color--forest);
}

/* Two columns where there is room, one where there is not. `auto-fit` with a
   min track rather than a media query, so the breakpoint follows the form's own
   width — it is as correct inside a narrow column as at full width. */
.bb-participate__grid {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 15rem, 1fr ) );
	gap: clamp( 1rem, 2vw, 1.5rem );
}

/* THE GROUP BOX.

   `.bb-panel`'s radius, but OUTLINED rather than filled. The panel around it is
   already `base-alt` and the inputs inside it are already `base`, so a third
   `base-alt` surface would be invisible against the second and a `base` one
   would swallow the inputs. An outline is the only move left that separates the
   group from its surroundings without competing with the controls in it. */
.bb-participate__details {
	padding: clamp( 0.9rem, 2vw, 1.25rem );
	border: 1px solid rgba( 57, 62, 46, 0.18 );
	border-radius: 10px;
	display: flex;
	flex-direction: column;
	gap: clamp( 1rem, 2vw, 1.25rem );
}

/* Hidden, not dimmed, when the visitor only wants email updates. Dimming would
   leave the questionnaire in the scroll path, which is the exact complaint this
   redesign exists to answer. JavaScript sets the attribute; the form is never
   rendered with it, so a browser without JavaScript always sees the questions. */
.bb-participate__details[disabled] {
	display: none;
}

/* THE INTENT CARDS. `.bb-fund` (sections.css) is the precedent — same radius,
   same hairline, same terracotta selected ring. The fill is inverted against it
   because the surface behind these is `base-alt` rather than `base`. */
.bb-participate__choices {
	display: grid;
	gap: 0.75rem;
	grid-template-columns: repeat( auto-fit, minmax( 16rem, 1fr ) );
}

.bb-intent {
	display: flex;
	align-items: flex-start;
	gap: 0.7rem;
	min-height: 44px;
	padding: 0.9rem 1rem;
	border: 1px solid rgba( 57, 62, 46, 0.18 );
	border-radius: 10px;
	background-color: var(--wp--preset--color--base);
	cursor: pointer;
}

.bb-intent:hover {
	border-color: var(--wp--preset--color--terracotta-text);
}

.bb-intent input {
	/* Left visible on purpose. The card highlight below needs `:has()`; the
	   native radio does not, so the chosen option is still unmistakable in a
	   browser that has neither `:has()` nor colour — WCAG 1.4.1, without
	   depending on a selector to satisfy it. */
	margin: 0.2rem 0 0;
	flex: none;
	accent-color: var(--wp--preset--color--terracotta-text);
}

.bb-intent__body {
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
}

.bb-intent__title {
	font-weight: 600;
	line-height: 1.3;
}

.bb-intent__hint {
	font-size: 0.875em;
	opacity: 0.75;
	line-height: 1.45;
}

/* Its own rule, never merged into a list: an unsupported selector invalidates
   every selector it is grouped with, and this is pure enhancement — losing it
   must cost nothing else. Same reasoning as `.bb-section:has(…)` above. */
.bb-intent:has( input:checked ) {
	border-color: var(--wp--preset--color--terracotta-text);
	box-shadow: inset 0 0 0 1px var(--wp--preset--color--terracotta-text);
}

.bb-intent:has( input:focus-visible ) {
	outline: 2px solid var(--wp--preset--color--terracotta-text);
	outline-offset: 2px;
}

.bb-field {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	margin-block: 0;
	/* The header is fixed, so a field scrolled to by the browser — native
	   validation, or the script moving focus to a rejected input — otherwise
	   lands underneath it. The fallback is not decoration: --bb-header-h is
	   declared in art-direction.css, which the block editor never loads, and
	   without it this resolves to nothing at all there. */
	scroll-margin-block: var( --bb-header-h, 6rem );
}

.bb-field--wide {
	grid-column: 1 / -1;
}

.bb-field > label,
.bb-field > legend {
	font-weight: 600;
	line-height: 1.3;
}

.bb-field__required {
	color: var(--wp--preset--color--terracotta-text);
}

.bb-field__hint {
	font-size: 0.875em;
	opacity: 0.75;
}

.bb-field :is( input, select, textarea ) {
	width: 100%;
	/* 44px minimum, the same floor the board directory uses. `min-height` rather
	   than taller padding so a textarea's rows still decide its height. */
	min-height: 44px;
	padding: 0.6rem 0.75rem;
	border: 1px solid rgba( 57, 62, 46, 0.28 );
	border-radius: 6px;
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	/* `inherit`, not a size of its own: iOS Safari zooms the viewport on focus
	   for anything under 16px, and the resulting jump reads as a bug. */
	font: inherit;
	box-sizing: border-box;
}

/* The select is the one control a UA insists on drawing itself. Stripped back
   and given the theme's own chevron, so it sits in the same family as the
   inputs beside it instead of looking like a system widget dropped in. The
   colour in the SVG is `forest` (#393e2e) written literally — a data URI cannot
   read a custom property. */
.bb-field select {
	appearance: none;
	background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%23393e2e' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E" );
	background-repeat: no-repeat;
	background-position: right 0.9rem center;
	background-size: 0.7rem auto;
	padding-inline-end: 2.4rem;
}

.bb-field textarea {
	resize: vertical;
}

/* A visible focus ring that does not rely on the UA's, which is invisible
   against this palette in several browsers. */
.bb-field :is( input, select, textarea ):focus-visible {
	outline: 2px solid var(--wp--preset--color--terracotta-text);
	outline-offset: 2px;
}

/* aria-invalid is the single source of truth for "this field is wrong": the
   server sets it, the script clears it, and the styling follows rather than
   needing a class of its own that could disagree. */
.bb-field [aria-invalid="true"] {
	border-color: var(--wp--preset--color--terracotta-text);
	border-width: 2px;
}

.bb-field--group {
	border: 0;
	padding: 0;
	display: flex;
	/* EXPLICIT, because `.bb-field` above sets `column` and this rule inherited
	   it — which stacked three short options down the page when `flex-wrap: wrap`
	   and a two-axis `gap` plainly meant them to sit in a row. Harmless while the
	   options were a line tall; three times the height once they became 44px
	   touch targets. */
	flex-direction: row;
	flex-wrap: wrap;
	gap: 0.35rem 1.25rem;
}

/* The legend is a flex item here, and it belongs on its own line above the
   options rather than sharing the row with the first one. */
.bb-field--group > legend {
	flex: 1 0 100%;
}

.bb-field--group > legend {
	padding: 0;
	margin-block-end: 0.35rem;
}

.bb-field__choice {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	/* The touch target is the whole row, including the label; the radio itself
	   is far smaller than 44px and cannot usefully be grown. */
	min-height: 44px;
}

.bb-field__choice input {
	width: auto;
	min-height: 0;
	accent-color: var(--wp--preset--color--terracotta-text);
}

.bb-field__choice label {
	font-weight: 400;
	cursor: pointer;
}

/* THE ACTION BAR. Last in the DOM, because it submits what is above it. */
.bb-participate__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem 1rem;
	margin-block: 0;
	padding-block-start: clamp( 1rem, 2vw, 1.25rem );
	border-block-start: 1px solid rgba( 57, 62, 46, 0.14 );
}

.bb-participate__required-note {
	margin: 0;
	font-size: var(--wp--preset--font-size--x-small);
	opacity: 0.75;
}

/* theme.json's canonical button (styles.elements.button), matched value for
   value. A form's primary action looking unlike every other button on the site
   is the kind of drift that is invisible in review and obvious on the page. */
.bb-participate__submit {
	min-height: 44px;
	padding: 0.85em 1.6em;
	border: 0;
	border-radius: 6px;
	background-color: var(--wp--preset--color--terracotta-text);
	color: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.01em;
	cursor: pointer;
}

.bb-participate__submit:hover {
	background-color: var(--wp--preset--color--forest);
}

.bb-participate__submit:focus-visible {
	outline: 2px solid var(--wp--preset--color--terracotta-text);
	outline-offset: 2px;
}

.bb-participate__submit:disabled {
	opacity: 0.6;
	cursor: progress;
}

/* The live region. Empty by default and it must STAY in the DOM when empty —
   a region inserted at the moment it gets text is frequently not announced,
   because assistive technology has to be observing it beforehand. Hence no
   `display:none` here and `:empty` collapsing the box instead. */
.bb-participate__result {
	margin-block: 0;
	padding: 0.75rem 1rem;
	border-inline-start: 4px solid var(--wp--preset--color--sage);
	background-color: var(--wp--preset--color--base-alt);
}

.bb-participate__result:empty {
	padding: 0;
	border: 0;
	background: none;
}

.bb-participate__result--error {
	border-inline-start-color: var(--wp--preset--color--terracotta-text);
}

.bb-participate__result:focus-visible {
	outline: 2px solid var(--wp--preset--color--terracotta-text);
	outline-offset: 2px;
}

/* Editor-only. Visitors never receive this element at all — see
   basic_borrego_participate_render_editor_notice(). Dashed, because the one
   thing it must never be mistaken for is part of the page. */
.bb-participate__notice {
	max-width: 46rem;
	margin-block: 0 1rem;
	padding: 0.75rem 1rem;
	border: 1px dashed rgba( 57, 62, 46, 0.4 );
	border-radius: 6px;
	font-size: 0.875em;
	line-height: 1.5;
}

.bb-participate__notice--warn {
	border-style: solid;
	border-color: var(--wp--preset--color--terracotta-text);
}

.bb-participate__notice > :first-child {
	margin-block-start: 0;
}

.bb-participate__notice > :last-child {
	margin-block-end: 0;
}

.bb-participate__notice p {
	margin-block: 0.5em;
}

.bb-participate__notice ul {
	margin-block: 0.5em;
	padding-inline-start: 1.25rem;
}

.bb-participate__notice li {
	margin-block: 0.35em;
}

.bb-participate__notice code {
	/* Wraps rather than overflowing: these are long shortcode examples and the
	   box is often inside a narrow column. */
	overflow-wrap: anywhere;
	font-size: 0.95em;
}

/* The honeypot. Moved off-screen rather than display:none or hidden: a form
   filler that honours `display:none` still fills what it can read in the DOM,
   and the ones worth catching read the markup, not the stylesheet. */
.bb-participate__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* After a successful submission the fields are hidden but the form stays in the
   document, so the result region keeps its identity and focus is not lost to a
   removed node.

   The sections go as a whole rather than field by field: hiding `.bb-field` and
   leaving its fieldset would leave three empty legends and a border behind. */
.bb-participate__form.is-sent :is(
	.bb-participate__section,
	.bb-participate__hp,
	.bb-participate__required-note
) {
	display: none;
}

.bb-participate__form.is-sent .bb-participate__actions {
	border-block-start: 0;
	padding-block-start: 0;
}

/* --------------------------------------------------------------------------
   The narrow-screen action bar.

   781px is core's own columns stacking breakpoint, matched here for the reason
   given at the top of this file: the form should reflow with the page around it
   rather than at a width nothing else cares about.

   STICKY, NOT MOVED. The submit belongs after the questions it submits — in the
   DOM, in the reading order and in the tab order — and pulling it above them to
   keep it on screen would trade a scroll for a worse structure. `sticky` keeps
   both. It also cannot trap anything: the bar is the last child, so at the
   bottom of the panel it simply comes to rest.
   -------------------------------------------------------------------------- */
@media ( max-width: 781px ) {
	.bb-participate__actions {
		position: sticky;
		/* Sticks to the bottom of the viewport, then to the bottom of the panel. */
		bottom: 0;
		/* Out to the panel's edges, so the backdrop covers the full width rather
		   than leaving the padding transparent for fields to show through. */
		margin-inline: calc( -1 * clamp( 1rem, 2.5vw, 1.5rem ) );
		padding-inline: clamp( 1rem, 2.5vw, 1.5rem );
		/* The iOS home indicator sits over the last few points of the viewport;
		   without this the button is under it. Resolves to 0 everywhere else. */
		padding-block-end: calc( 0.75rem + env( safe-area-inset-bottom, 0px ) );
		background-color: var(--wp--preset--color--base-alt);
		/* Opaque, because content scrolls underneath it. */
		border-block-start: 1px solid rgba( 57, 62, 46, 0.14 );
	}

	/* Nothing to stick to once the fields are gone. */
	.bb-participate__form.is-sent .bb-participate__actions {
		position: static;
		background: none;
	}
}

/* --------------------------------------------------------------------------
   Release stamp
   --------------------------------------------------------------------------
   Two pieces with opposite jobs. See inc/release-stamp.php for what the
   timestamps mean.

   .bb-release-inline is what everybody sees: one short date riding along at the
   end of the copyright line. It must cost ZERO extra vertical space and must
   not look like a control — no marker, no pointer cursor, no focus ring. A
   reader who does not care about release dates should look straight past it.

   .bb-release is the diagnostic breakdown, hidden on every page until someone
   asks for it via #showver, ?showver, or three quick clicks on the line above.

   CONTRAST. Cream on forest-deep, and the alpha is the whole question. At 12px
   this is not "large text", so WCAG 1.4.3 wants 4.5:1 — .72 over #2F3527 lands
   comfortably past that. Do not push it below ~0.6 chasing subtlety; the point
   is a detail that recedes, not one that cannot be read. The obvious
   alternative — a "muted" palette token — does not exist: theme.json has base,
   base-alt, contrast, forest, forest-deep, terracotta*, sage and gold, and
   nothing between them. */

.bb-release-inline {
	color: rgba( 239, 231, 219, 0.72 );
	/* Keeps the date from breaking across two lines when the copyright wraps on
	   a phone. The line as a whole may wrap; the timestamp may not. */
	white-space: nowrap;
}

/* The separator is generated rather than typed into the PHP string, so it
   cannot end up alone at the start of a wrapped line. */
.bb-release-inline::before {
	content: " · ";
	white-space: normal;
}

/* BOTH the attribute and this rule, on purpose. This codebase already carries
   the opposite bug at page-scholarship-awardees.php:532 against
   awardees.css:1006, where an author-origin `display:flex` outranks the user
   agent's [hidden] rule and the element shows until script strips the
   attribute. A footer panel flashing open on every page load would be a
   conspicuous way to repeat it. */
.bb-release[hidden] {
	display: none;
}

.bb-release {
	margin-block-start: 0.75rem;
	font-size: var(--wp--preset--font-size--x-small);
	color: rgba( 239, 231, 219, 0.72 );
}

.bb-release__panel {
	margin: 0 auto;
	display: grid;
	gap: 0.2rem 0.9rem;
	text-align: start;
	max-width: 34rem;
}

.bb-release__row {
	display: grid;
	grid-template-columns: 6.5rem 1fr;
	gap: 0.9rem;
}

.bb-release__row dt {
	font-weight: 600;
	opacity: 0.85;
}

.bb-release__row dd {
	margin: 0;
	/* Timestamps in a column read as a table; proportional digits make them
	   jitter, and the "Now" row rewrites itself once a second. */
	font-variant-numeric: tabular-nums;
}

.bb-release__note {
	opacity: 0.7;
}

@media ( max-width: 480px ) {
	.bb-release__row {
		grid-template-columns: 1fr;
		gap: 0;
	}

	.bb-release__row + .bb-release__row {
		margin-block-start: 0.45rem;
	}
}

/* ---------------------------------------------------------------------------
   AWARD RECORD — what shows when the figures are not available.
   ---------------------------------------------------------------------------
   Deliberately quiet. These sentences replace numbers on four pages when the
   hub cannot be reached, and they are meant to read as a calm aside rather
   than an error: the site is fine, the figures are simply not to hand. There
   is no fallback number by design — a stale figure is indistinguishable from a
   current one, and publishing one would be worse than saying nothing.

   The band variant sits on the dark forest ground, so it inherits its colour
   rather than setting one.
*/
.bb-award-note {
	margin: 0;
	padding-block: 1.25rem;
	text-align: center;
	font-size: 0.95rem;
	opacity: 0.85;
}

/* Admin-only, and it carries an API error string that can run long.
 *
 * NOT DIMMER THAN THE VISITOR NOTE, which it used to be — 0.7 opacity at 0.8rem
 * made the one message written for the person who can fix the problem the
 * least visible thing on the page. It is a diagnostic, so it is allowed to look
 * like one. */
.bb-award-note--admin {
	padding-block: 0.5rem;
	font-size: 0.85rem;
	font-weight: 600;
	color: #8f2d21;
	overflow-wrap: anywhere;
}

/* The shared apology, inline inside a sentence rather than its own block. */
.bb-award-note--inline {
	display: inline;
	padding-block: 0;
	opacity: 0.85;
}

/* Keep the About and home slots from collapsing to nothing when the numbers
   are replaced by one sentence — the surrounding sections are laid out around
   a block of that approximate height. */
.bb-about-community__figures--note,
.bb-home-impact__stats--note {
	display: block;
	min-block-size: 3.5rem;
}

/* The home band's apology when only its two DERIVED figures are missing: it
   sits inside the page's own <dl> beside two hand-written ones that are still
   showing, so it spans the columns they left rather than replacing the list. */
.bb-home-impact__item--note {
	grid-column: 1 / -1;
}
