/*
Theme Name: Auchencairn
Theme URI: https://auchencairnmatters.org/
Author: Auchencairn Community Council
Author URI: https://auchencairnmatters.org/
Description: Custom block theme for Auchencairn Community Council. All design values live in theme.json as design tokens — colour, spacing, type scale, radii and shadows are defined once and consumed everywhere.
Requires at least: 6.7
Tested up to: 6.8
Requires PHP: 8.1
Version: 0.23.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: auchencairn
Tags: block-templates, full-site-editing, accessibility-ready, community
*/

/**
 * IMPORTANT — design SSOT.
 *
 * Do not add ad-hoc colour, spacing or type values to this file. Every design
 * value belongs in theme.json, where it becomes a CSS custom property that
 * blocks, patterns and templates consume. This stylesheet exists only for the
 * few things theme.json cannot express (e.g. the skip link, focus behaviour),
 * and even those must reference the generated `--wp--preset--*` /
 * `--wp--custom--*` variables rather than literal values.
 */

/* -------------------------------------------------------------------------
 * The root canvas.
 *
 * theme.json paints `body`, which is everything a browser tab needs — but
 * anything outside the body's box takes the background of the ROOT element,
 * and nothing was painting that. In an ordinary tab you never see it. Installed
 * on a phone's home screen you do: the strips the operating system keeps for
 * itself, and the bar it draws with the back button, fell back to the system
 * default, which is black. A black band under the site is not a design; it is
 * the absence of one.
 *
 * So the root carries the page colour. `background-color` only, and from the
 * token — the design SSOT rule above still applies, and this is the one
 * declaration theme.json has no way to make.
 *
 * That fixed iOS and did NOT fix Android, which is worth recording because it
 * looked like the same bug. On iOS the strip under the footer is the page's own
 * canvas, so painting the root paints it. On Android the black bar is the
 * system navigation bar — not part of the document at all, and unreachable by
 * any background declaration. What Chrome themes it from is the page's colour
 * scheme and `theme-color`, and this site had never declared a scheme: an
 * undeclared page on a phone in dark mode is one the browser may treat as
 * scheme-agnostic, so it themed its own furniture dark. Hence the line below,
 * and the matching metas in `inc/web-app.php` which arrive before first paint.
 *
 * One scheme, because there is one palette. Every contrast pair in this site was
 * computed against it; `light dark` would be a claim the browser acts on and the
 * design cannot honour.
 * ---------------------------------------------------------------------- */

html {
	background-color: var( --wp--preset--color--base, #faf8f6 );
	color-scheme: light;
}

/* -------------------------------------------------------------------------
 * Comments on village news.
 *
 * Only news posts take them, only from somebody with a village login, and only
 * for a while — the policy is in `AC\Core\Discussion\Comments`. This is the
 * little that theme.json cannot say: a rule above the section, a card per
 * comment so a thread reads as separate voices, and no avatars (there is no
 * Gravatar request to make, deliberately).
 * ---------------------------------------------------------------------- */

.ac-comments {
	border-top: 1px solid var( --wp--preset--color--border );
	padding-top: var( --wp--preset--spacing--40 );
}

/*
 * The card goes on the comment's own group, NOT on the `li`.
 *
 * A threaded reply is rendered *inside* its parent's `li`, as a sibling of the
 * parent's content — so styling the `li` drew one box around the whole
 * conversation and the replies inside it. Two people talking looked like one
 * long grey panel. The direct group child is exactly one comment.
 */
.ac-comments .wp-block-comment-template li {
	list-style: none;
	margin: 0 0 var( --wp--preset--spacing--20 );
}

.ac-comments .wp-block-comment-template li > .wp-block-group {
	background-color: var( --wp--preset--color--surface );
	border-radius: var( --wp--custom--radius--md );
	padding: var( --wp--preset--spacing--20 ) var( --wp--preset--spacing--30 );
}

/*
 * A reply is marked by a rule down its left rather than by a deep indent.
 * Indentation alone runs out of page by the third level on a phone, and the
 * thread depth WordPress allows is five.
 */
.ac-comments .wp-block-comment-template ol {
	border-left: 2px solid var( --wp--preset--color--border );
	margin: var( --wp--preset--spacing--20 ) 0 0;
	padding-left: var( --wp--preset--spacing--20 );
}

/*
 * Whoever started the thread, marked wherever they appear in it.
 *
 * The shape of a village thread is usually ask → answer → "that worked, thanks",
 * and the third one is the same person as the first. Without a mark a reader has
 * to compare names to see that, which is work.
 *
 * `AC\Core\Discussion\Comments` adds the classes, because WordPress has no idea
 * who began a thread — it offers `comment-author-jean`, which groups a person,
 * and `bypostauthor`, which is about the council.
 *
 * Two cues, never colour alone (the same rule the notice severities follow): the
 * border's *presence* is a non-colour difference, and the reply carries a few
 * words saying what it is. A tint would not do this job — `sand` sits 1.06:1
 * from `surface`, so a second background would be a join nobody could see.
 */
.ac-comments .wp-block-comment-template li.ac-comment--originator > .wp-block-group {
	border-left: 3px solid var( --wp--preset--color--primary );
}

.ac-comments li.ac-comment--originator-reply .wp-block-comment-author-name::after {
	color: var( --wp--preset--color--muted );
	content: " · who asked";
	font-weight: 400;
}

/*
 * Where a withdrawn comment used to be.
 *
 * Quieter than a comment and visibly not one: no card of its own colour, italic,
 * and muted. It has to be legible — it is the site accounting for a removal —
 * without inviting the eye the way the surrounding conversation does.
 */
.ac-comments .ac-comment-withdrawn {
	color: var( --wp--preset--color--muted );
	font-size: var( --wp--preset--font-size--small );
	font-style: italic;
	margin: 0;
}

.ac-comments .ac-comment-withdrawn a {
	color: var( --wp--preset--color--primary );
}

/*
 * A withdrawn comment carries no name and takes no replies.
 *
 * The name is removed in PHP; these two suppress what is left. There is nothing
 * to answer, and the "who asked" marker would sit after an empty name.
 */
.ac-comments li.ac-comment--withdrawn .wp-block-comment-reply-link,
.ac-comments li.ac-comment--withdrawn .wp-block-comment-author-name::after {
	display: none;
}

/*
 * Report it, and — if you can — remove it, from the page itself.
 *
 * A councillor who has just read the comment should not have to go to wp-admin,
 * find the post and identify the comment again. Both are POST forms rather than
 * links: this site sends speculation rules, so a browser prefetches links it
 * thinks you might follow, and a report behind a GET would fire with nobody
 * having clicked anything.
 */
.ac-comments .ac-comment-tools {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: var( --wp--preset--spacing--20 );
	margin: var( --wp--preset--spacing--10 ) 0 0;
}

.ac-comments .ac-comment-tools__form {
	margin: 0;
}

/*
 * Quiet by default. Reporting a neighbour's comment should be possible and not
 * inviting — a button styled like a call to action would get pressed for sport.
 */
.ac-comments .ac-comment-tools button {
	background: none;
	border: 0;
	border-radius: var( --wp--custom--radius--sm );
	color: var( --wp--preset--color--muted );
	cursor: pointer;
	font-family: inherit;
	font-size: var( --wp--preset--font-size--x-small );

	/*
	 * Quiet, but not so quiet a thumb misses it. At this font size the padding
	 * alone gave a 23px-tall target; 32px is comfortable on a phone and still
	 * reads as a footnote rather than a call to action.
	 */
	min-height: 32px;
	padding: 0.2rem 0.5rem;
	text-decoration: underline;
}

.ac-comments .ac-comment-tools button:hover {
	color: var( --wp--preset--color--primary-dark );
}

/* Removing is the consequential one, so it does not look like the others. */
.ac-comments .ac-comment-tools button.ac-comment-tools__remove,
.ac-comments .ac-comment-tools button.ac-comment-tools__restore {
	border: 1px solid var( --wp--preset--color--border-strong );
	color: var( --wp--preset--color--danger );
	font-weight: 600;
	text-decoration: none;
}

.ac-comments .ac-comment-tools button.ac-comment-tools__restore {
	color: var( --wp--preset--color--primary-dark );
}

/*
 * What a moderator sees when somebody has reported it.
 *
 * Both the badge and the card's left edge, so a reported comment is findable by
 * scrolling rather than by reading every one. Neither is rendered for an ordinary
 * reader — see Comments::classes(): the report button must not become a way of
 * publicly marking a neighbour.
 */
.ac-comments .ac-comment-tools__flag {
	background-color: var( --wp--custom--notice--warning-bg );
	border-radius: var( --wp--custom--radius--sm );
	color: var( --wp--custom--notice--warning-accent );
	font-size: var( --wp--preset--font-size--x-small );
	padding: 0.2rem 0.5rem;
}

.ac-comments li.ac-comment--reported > .wp-block-group {
	border-left: 3px solid var( --wp--custom--notice--warning-accent );
}

/*
 * "Delete mine" is not the moderator's "Remove" and must not look like it.
 *
 * A comment somebody takes back leaves no note, because changing your mind about
 * something you said is not a breach of anything — so the button that does it
 * reads as an ordinary tidy-up rather than as an enforcement action.
 */
.ac-comments .ac-comment-tools button.ac-comment-tools__unsay {
	color: var( --wp--preset--color--muted );
	text-decoration: underline;
}

/*
 * Where the comment used to be, there is nothing to hang a message on — so the
 * notice goes at the top of the comments block. Both messages that live there
 * ("taken down", "already posted") share the class, which is also what stops a
 * second copy appearing: see Comments::confirm_unsaid(), where core fires the
 * block filter twice.
 */
.ac-comment-notice {
	background-color: var( --wp--custom--notice--cleared-bg );
	border-radius: var( --wp--custom--radius--md );
	color: var( --wp--custom--notice--cleared-accent );
	margin-block-end: var( --wp--preset--spacing--30 );
	padding: var( --wp--preset--spacing--20 ) var( --wp--preset--spacing--30 );
}

.ac-comments .ac-comment-tools__said {
	color: var( --wp--preset--color--primary-dark );
	font-size: var( --wp--preset--font-size--small );
	font-weight: 600;
}

/* Who said it, then when — one loud, one quiet. */
.ac-comments .wp-block-comment-author-name {
	color: var( --wp--preset--color--primary-dark );
}

.ac-comments .wp-block-comment-author-name a {
	text-decoration: none;
}

.ac-comments .wp-block-comment-date,
.ac-comments .wp-block-comment-date a,
.ac-comments .wp-block-comment-edit-link a {
	color: var( --wp--preset--color--muted );
	text-decoration: none;
}

.ac-comments .wp-block-comment-date a:hover,
.ac-comments .wp-block-comment-edit-link a:hover {
	text-decoration: underline;
}

/* The reply link is an action, so it reads as one rather than as body text. */
.ac-comments .wp-block-comment-reply-link {
	margin-top: var( --wp--preset--spacing--10 );
}

.ac-comments .wp-block-comment-reply-link a {
	font-weight: 600;
	text-decoration: none;
}

.ac-comments .wp-block-comment-reply-link a:hover {
	text-decoration: underline;
}

/* The form's heading is a step down from the section's, not a rival to it. */
.ac-comments .comment-reply-title {
	font-size: var( --wp--preset--font-size--large );
	margin-bottom: var( --wp--preset--spacing--20 );
}

@media ( max-width: 30rem ) {

	/* On a narrow screen the rule stays and the indent nearly goes. */
	.ac-comments .wp-block-comment-template ol {
		padding-left: var( --wp--preset--spacing--10 );
	}
}

/*
 * What somebody not logged in is told, and the invitation to get a login. It is
 * a panel rather than a line of small print because it is the only thing in the
 * section for that reader, and a reader who cannot comment should still be able
 * to see why at a glance.
 */
.ac-comments__login,
.ac-comments__as {
	background-color: var( --wp--preset--color--surface );
	border-left: 4px solid var( --wp--preset--color--primary );
	border-radius: var( --wp--custom--radius--sm );
	margin-bottom: var( --wp--preset--spacing--30 );
	padding: var( --wp--preset--spacing--20 ) var( --wp--preset--spacing--30 );
}

.ac-comments__as {
	font-size: var( --wp--preset--font-size--small );
}

/* -------------------------------------------------------------------------
 * Accessibility: skip link (WCAG 2.4.1 Bypass Blocks).
 * Visually hidden until focused, then pinned to the top-left.
 * ---------------------------------------------------------------------- */

.skip-link.screen-reader-text {
	background-color: var( --wp--preset--color--base );
	border-radius: var( --wp--custom--radius--sm );
	box-shadow: var( --wp--custom--shadow--md );
	color: var( --wp--preset--color--primary-dark );
	display: block;
	font-family: var( --wp--preset--font-family--sans );
	font-size: var( --wp--preset--font-size--small );
	font-weight: 600;
	left: var( --wp--preset--spacing--30 );
	line-height: normal;
	padding: var( --wp--preset--spacing--20 ) var( --wp--preset--spacing--30 );
	text-decoration: none;
	top: var( --wp--preset--spacing--30 );
	z-index: 100000;
}

/* -------------------------------------------------------------------------
 * Accessibility: a visible focus ring everywhere, not just on links.
 * Uses :focus-visible so mouse users are not shouted at.
 * ---------------------------------------------------------------------- */

:where( a, button, input, select, textarea, summary, [tabindex] ):focus-visible {
	outline: var( --wp--custom--focus--width ) solid var( --wp--custom--focus--color );
	outline-offset: var( --wp--custom--focus--offset );
}

/* -------------------------------------------------------------------------
 * Typography: underlines that sit off the baseline rather than through the
 * descenders. theme.json can turn an underline on; it cannot say where it
 * goes.
 * ---------------------------------------------------------------------- */

:where( main, footer ) a:where( :not( .wp-element-button ) ) {
	text-decoration-thickness: from-font;
	text-underline-offset: 0.16em;
}

/* -------------------------------------------------------------------------
 * Section headings: a short accent rule beneath.
 *
 * The one piece of decoration on the site, and it earns its place by doing a
 * job — it marks where a section starts, so a long page reads as parts rather
 * than as one column of text. Excluded from the small uppercase headings the
 * footer uses as labels, where a rule would be noise.
 * ---------------------------------------------------------------------- */

main h2.wp-block-heading:not( .has-small-font-size ):not( .has-x-small-font-size )::after {
	background: var( --wp--custom--rule--accent );
	border-radius: var( --wp--custom--radius--pill );
	content: "";
	display: block;
	height: var( --wp--custom--rule--height );
	margin-top: var( --wp--preset--spacing--20 );
	width: var( --wp--custom--rule--width );
}

/*
 * Not inside a box that is already shouting. An error summary and an urgent
 * notice each have a heading, but they are panels rather than sections of the
 * page, and a decorative rule under "Your booking could not be sent" reads as
 * ornament on bad news.
 */
main :is( .ac-form__errors, .ac-notice ) h2.wp-block-heading::after {
	content: none;
}

/* -------------------------------------------------------------------------
 * Media never wider than the page.
 *
 * WordPress makes its own image blocks responsive, but content imported from
 * the old site carries raw `<img>` inside `.gallery` markup at a fixed 720px,
 * which pushed the whole events page 350px sideways on a phone. `:where()`
 * keeps the specificity at zero, so anything that genuinely wants to be wider
 * — a chart, a deliberately full-bleed figure — still wins.
 * ---------------------------------------------------------------------- */

:where( main img, main video, main iframe, main embed, main object ) {
	height: auto;
	max-width: 100%;
}

/* -------------------------------------------------------------------------
 * Tables.
 *
 * A browser's default table has no cell borders, centres its headers, and
 * leaves the columns to run into each other — which on a phone turns a rate
 * card into a paragraph of numbers. What makes a table readable is the row,
 * so the rows are what get the treatment: a tinted, ruled header, hairlines
 * between rows, and enough padding that two columns cannot be mistaken for
 * one.
 * ---------------------------------------------------------------------- */

.wp-block-table table,
table.wp-block-table {
	border-collapse: collapse;
	width: 100%;
}

.wp-block-table :is( th, td ),
table.wp-block-table :is( th, td ) {
	border: 0;
	border-bottom: 1px solid var( --wp--preset--color--border );
	padding: 0.6rem 0.85rem;
	text-align: left;
	vertical-align: top;
}

/*
 * The header wraps. Holding it on one line pushed a three-column rate card
 * into a sideways scroll on a phone, which is a worse answer than two short
 * lines of "Per day".
 */
.wp-block-table thead th,
table.wp-block-table thead th {
	background-color: var( --wp--preset--color--surface );
	border-bottom: 2px solid var( --wp--preset--color--border-strong );
	font-size: var( --wp--preset--font-size--x-small );
	letter-spacing: var( --wp--custom--tracking--caps );
	text-transform: uppercase;
}

/*
 * Striping as well as rules. Reading across a row on a narrow screen is where
 * tables fail, and a band is easier to follow than a line.
 */
.wp-block-table tbody tr:nth-child( even ),
table.wp-block-table tbody tr:nth-child( even ) {
	background-color: color-mix( in srgb, var( --wp--preset--color--surface ) 55%, transparent );
}

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

/*
 * Money lines up on its right edge, where the digits that matter are. The row
 * header — what is being hired — stays on the left with the reading.
 */
.ac-rates td {
	font-variant-numeric: tabular-nums;
	text-align: right;
	white-space: nowrap;
}

.ac-rates thead th:not( :first-child ) {
	text-align: right;
}

/*
 * A wide table scrolls inside its own box rather than pushing the page
 * sideways, and says so to a screen reader by being focusable — otherwise a
 * keyboard user cannot reach the part that is off-screen.
 */
.ac-rates__scroll {
	overflow-x: auto;
}

.ac-rates__scroll:focus-visible {
	outline: var( --wp--custom--focus--width ) solid var( --wp--custom--focus--color );
	outline-offset: var( --wp--custom--focus--offset );
}

/*
 * The village directory.
 *
 * One long page on purpose — "everything a newcomer needs in one place" and "two
 * pages that half-answer it" are not the same offer. What makes length work is
 * the contents list at the top and a heading per section, so the page can be
 * skimmed to the one fact somebody came for.
 *
 * Entries are a list, not cards. A card grid looks better and reads worse here:
 * the question is "is the joiner on this page", which is answered by scanning
 * names down a single column, not by looking at eight boxes.
 * ---------------------------------------------------------------------- */

.ac-directory__contents {
	background-color: var( --wp--preset--color--surface );
	border-radius: var( --wp--custom--radius--md );
	list-style: none;
	padding: var( --wp--preset--spacing--30 );
}

.ac-directory__section {
	margin-block-start: var( --wp--preset--spacing--50 );
}

.ac-directory__about {
	color: var( --wp--preset--color--muted );
	font-size: var( --wp--preset--font-size--small );
	margin-block: 0 var( --wp--preset--spacing--20 );
}

.ac-directory__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

/*
 * A rule between entries rather than a box round each. Twenty boxed entries is a
 * page of boxes; twenty separated lines is a list somebody can run their eye down.
 */
.ac-directory__entry {
	border-block-start: var( --wp--custom--border--width ) solid var( --wp--preset--color--border );
	padding-block: var( --wp--preset--spacing--20 );
}

.ac-directory__entry > p {
	margin-block: 0;
}

.ac-directory__name {
	font-size: var( --wp--preset--font-size--medium );
}

.ac-directory__where,
.ac-directory__how {
	color: var( --wp--preset--color--muted );
	font-size: var( --wp--preset--font-size--small );
}

.ac-directory__how a {
	color: var( --wp--preset--color--primary-dark );
}

/*
 * "No public number — ask the council" is a real answer, not a missing value, so
 * it is not greyed out any further than the rest of the line.
 */
.ac-directory__how--ask {
	font-style: italic;
}

/* -------------------------------------------------------------------------
 * The venues overview: one card per hall, written by the booking registry.
 *
 * Two columns where there is room, because the point of the page is comparing
 * them — a villager deciding between the Murray Hall and the Church Hall should
 * see both without scrolling one past the other.
 */
.ac-venues {
	display: grid;
	gap: var( --wp--preset--spacing--40 );
	grid-template-columns: repeat( auto-fit, minmax( 18rem, 1fr ) );
	margin-block: var( --wp--preset--spacing--40 );
}

.ac-venue {
	background-color: var( --wp--preset--color--surface );
	border-radius: var( --wp--custom--radius--md );
	padding: var( --wp--preset--spacing--30 );
}

.ac-venue__name {
	margin-block: 0 var( --wp--preset--spacing--10 );
}

.ac-venue :is( .ac-venue__status, .ac-venue__rooms, .ac-venue__label, .ac-venue__more ) {
	margin-block: 0 var( --wp--preset--spacing--10 );
}

/*
 * Whether a hall takes bookings is said in words — see VenueList — so these two
 * only change the emphasis. Never colour alone.
 */
.ac-venue__status {
	font-size: var( --wp--preset--font-size--small );
}

.ac-venue__status--open {
	color: var( --wp--preset--color--primary-dark );
}

.ac-venue__status--waiting {
	color: var( --wp--preset--color--muted );
}

.ac-venue__hire {
	margin-block: 0 var( --wp--preset--spacing--20 );
	padding-inline-start: 1.1rem;
}

/* Narrow screens buy their columns back from the padding first. */
@media ( max-width: 30rem ) {

	.wp-block-table :is( th, td ),
	table.wp-block-table :is( th, td ) {
		padding: 0.55rem 0.5rem;
	}
}

/*
 * Below the width where three money columns fit, the rate card stops being a
 * grid and becomes a short list per row:
 *
 *     Main Hall
 *     Per hour            £10.00
 *     Per day             £60.00
 *
 * Measured in `em`, not `px`, so the breakpoint moves with the reader's text
 * size. That is the whole point: at the default size the table fits a phone
 * comfortably, and somebody who has turned their text up — exactly the reader
 * this village has most of — was the one getting "£60.0" and a clipped column.
 * A width query would not have caught them.
 *
 * The column headers are hidden visually but stay in the accessibility tree,
 * so the association between "£60.00" and "Per day" is never broken. Sighted
 * readers get the same association back through `data-label`.
 */
@media ( max-width: 34em ) {

	.ac-rates thead {
		clip-path: inset( 50% );
		height: 1px;
		overflow: hidden;
		position: absolute;
		white-space: nowrap;
		width: 1px;
	}

	.ac-rates,
	.ac-rates tbody,
	.ac-rates tr,
	.ac-rates th,
	.ac-rates td {
		display: block;
	}

	.ac-rates tr {
		border-bottom: 1px solid var( --wp--preset--color--border );
		padding: 0.5rem 0;
	}

	.ac-rates tbody tr:last-child {
		border-bottom: 0;
	}

	.ac-rates th[ scope="row" ] {
		border: 0;
		font-weight: 600;
		padding: 0.25rem 0;
	}

	.ac-rates td {
		border: 0;
		display: flex;
		gap: 1rem;
		justify-content: space-between;
		padding: 0.2rem 0;
		white-space: normal;
	}

	.ac-rates td::before {
		color: var( --wp--preset--color--muted );
		content: attr( data-label );
		font-size: var( --wp--preset--font-size--small );
	}
}

/* -------------------------------------------------------------------------
 * The footer, as an anchor.
 *
 * A pale footer separated from a white page by one hairline does not end the
 * page so much as stop mid-sentence. Dark, it bookends the hero at the top and
 * gives the whole thing a bottom edge — the reader can see the document is
 * finished without reading anything.
 *
 * The type has to be re-coloured to match. theme.json colours links with the
 * sea green, which is a good link colour on white and nearly invisible on
 * `deep`, so this restates the few elements that carry their own colour rather
 * than inheriting.
 *
 * Contrast, measured: white on deep is 16.3:1, the muted line 8.1:1 — both
 * well past AA, which matters here because the footer carries the accessibility
 * statement and the privacy notice, and those are exactly the pages somebody
 * with a visual impairment is most likely to be looking for.
 * ---------------------------------------------------------------------- */

/*
 * `.ac-footer` twice, and the block class named as well.
 *
 * theme.json colours headings and links through `:root :where(…)` selectors
 * that are printed after the theme's stylesheet, and a single class ties with
 * them rather than beating them — which left the footer's "CONTACT" and "THIS
 * SITE" labels in the dark sea green they inherit, on a dark ground, all but
 * invisible. Doubling the class is the cheapest way past a tie.
 */
.ac-footer.ac-footer :is( h2, h3, h4, p, li, .wp-block-heading ) {
	color: var( --wp--preset--color--base );
}

.ac-footer.ac-footer a {
	color: var( --wp--preset--color--base );
	text-decoration-color: color-mix( in srgb, var( --wp--preset--color--base ) 55%, transparent );
}

.ac-footer.ac-footer a:hover,
.ac-footer.ac-footer a:focus {
	color: var( --wp--preset--color--base );
	text-decoration-color: currentColor;
	text-decoration-thickness: 2px;
}

/* The small print stays quieter than the links, without going dim. */
.ac-footer.ac-footer .has-x-small-font-size {
	color: color-mix( in srgb, var( --wp--preset--color--base ) 78%, var( --wp--preset--color--footer ) );
}

.ac-footer .wp-block-separator {
	border-color: color-mix( in srgb, var( --wp--preset--color--base ) 22%, transparent );
	color: color-mix( in srgb, var( --wp--preset--color--base ) 22%, transparent );
	opacity: 1;
}

/* The focus ring has to be visible on a dark ground, not the dark ring. */
.ac-footer.ac-footer :is( a, button ):focus-visible {
	outline-color: var( --wp--preset--color--base );
}

/* -------------------------------------------------------------------------
 * The masthead.
 * ---------------------------------------------------------------------- */

.ac-masthead .wp-block-site-title {
	letter-spacing: var( --wp--custom--tracking--heading );
}

/*
 * The masthead, set tight.
 *
 * Body line-height is generous because it is meant for reading paragraphs; the
 * name of the village and one line under it are not a paragraph, and at 1.6 the
 * leading was buying two lines of white space above the fold for nothing. Every
 * pixel here is a pixel of "Coming up" that a phone does not show.
 */
.ac-masthead .wp-block-site-title,
.ac-masthead .wp-block-site-tagline {
	line-height: var( --wp--custom--line-height--tight );
}

/*
 * The search spyglass.
 *
 * Core styles the button-only search as a filled button, which put a solid dark
 * green block beside the menu — heavier than the navigation it sits next to, so
 * the eye went to search before it went to the sections. It is a way in, not
 * the main way in, so it reads at the same weight as a menu item and earns its
 * emphasis only on hover and focus.
 *
 * The 44px box is the touch target, not the icon: a control that is only as big
 * as its glyph is one somebody misses on a phone.
 */
.ac-masthead .ac-search .wp-block-search__button {
	align-items: center;
	background: transparent;
	border: 0;
	border-radius: var( --wp--custom--radius--md );
	color: var( --wp--preset--color--primary-dark );
	display: flex;
	justify-content: center;
	min-height: 44px;
	min-width: 44px;
	padding: 0;
	transition: background-color var( --wp--custom--motion--quick ) var( --wp--custom--motion--ease );
}

.ac-masthead .ac-search .wp-block-search__button:hover,
.ac-masthead .ac-search .wp-block-search__button:focus-visible {
	background: var( --wp--preset--color--surface );
}

/*
 * The field that slides out sits on the site's own border and radius rather
 * than the browser default, so an opened search does not look like a
 * different application.
 */
.ac-masthead .ac-search .wp-block-search__input {
	border: var( --wp--custom--border--width ) solid var( --wp--preset--color--border-strong );
	border-radius: var( --wp--custom--radius--md );
	font-size: var( --wp--preset--font-size--small );
	padding: 0.4rem 0.6rem;
}

/*
 * A closed search field is still a field.
 *
 * Core collapses it by animating the width to nothing, which leaves a 27x24 box
 * that is `visible`, enabled, and **still in the tab order** — so a keyboard user
 * on any page of this site tabs into a text box they cannot see, type in, or find
 * their way out of by looking. The battery measured it at 27x24 on every page it
 * judged.
 *
 * Hidden means hidden. The class comes off when the spyglass is pressed, so this
 * costs the opened search nothing.
 */
.ac-masthead .ac-search.wp-block-search__searchfield-hidden .wp-block-search__input {
	visibility: hidden;
}

/*
 * An open search is laid over the header, not inserted into it.
 *
 * In flow it had to find its width somewhere, and there was none to find: on a
 * desktop the field pushed the navigation onto a second line, so pressing the
 * spyglass made the header grow by half its own height and shoved the page
 * down; on a phone it opened as a short box starting halfway across, with the
 * tagline showing through beside it, which read as a rendering fault rather
 * than a search field.
 *
 * Laid over, it can be as wide as it needs to be, it starts where the text
 * starts, and opening it moves nothing.
 *
 * The gap is the second half of the same idea. Core butts the button against
 * the input's border, so the two read as one control with a seam down it and
 * the magnifier looks like something inside the box. A gap says plainly that
 * the box is where you type and the glass is the thing you press.
 */
.ac-masthead .ac-search:not( .wp-block-search__searchfield-hidden ) {
	inset-block: 0;
	inset-inline: 0;
	position: absolute;
	z-index: 3;
}

.ac-masthead .ac-search:not( .wp-block-search__searchfield-hidden ) .wp-block-search__inside-wrapper {
	align-items: center;
	background: var( --wp--preset--color--base );

	/*
	 * `float: right` is core's, and with the form now spanning the header it
	 * would leave the field floating off to one side of its own container.
	 */
	float: none;
	gap: var( --wp--preset--spacing--20 );
	height: 100%;
	width: 100%;
}

/* On a wide screen it covers the navigation and leaves the title alone. */
.ac-masthead__end {
	position: relative;
}

/*
 * A closed search leaves nothing behind.
 *
 * Core collapses the field by taking its width to zero and removing only its
 * left and right borders, so the top and bottom edges stayed — a thin ghost
 * box hanging next to the spyglass that looked like a rendering fault.
 */
.ac-masthead .ac-search.wp-block-search__searchfield-hidden .wp-block-search__input {
	border-width: 0;
}

/*
 * Title left, controls right, on one line.
 *
 * The masthead wraps, and on a phone the title is large enough that the menu
 * and the spyglass dropped to a second row — which pushed the hero down and
 * left the header looking like two headers. Letting the title shrink instead
 * keeps it to one.
 */
@media ( max-width: 781px ) {

	.ac-masthead {
		flex-wrap: nowrap;
	}

	.ac-masthead > .wp-block-group:first-child {
		min-width: 0;
	}

	/*
	 * The menu is the last thing on the row.
	 *
	 * On a phone the navigation collapses to a hamburger, and that is the
	 * control people reach for — so it belongs at the outside edge, under the
	 * thumb, with search beside it rather than beyond it. The order is set here
	 * rather than in the markup because on a wide screen the navigation is a row
	 * of links and the spyglass reads correctly at the end of them; only the
	 * collapsed layout wants them the other way round.
	 */
	.ac-masthead__end .ac-search {
		order: 1;
	}

	.ac-masthead__end .wp-block-navigation {
		order: 2;
	}

	/*
	 * On a phone it covers the whole header line instead, starting exactly
	 * where the title starts — there is no navigation to cover, only a title
	 * and a tagline, and a field that began beside them would be too narrow to
	 * type a place name into.
	 *
	 * The menu keeps its place at the outside edge: somebody who opened search
	 * by accident should not have lost the way out of it.
	 */
	.ac-masthead {
		position: relative;
	}

	.ac-masthead__end {
		position: static;
	}

	.ac-masthead .ac-search:not( .wp-block-search__searchfield-hidden ) {
		inset-inline-end: 3.25rem;
	}
}

/*
 * Where you are, marked with a rule rather than a colour alone — colour is
 * never the only carrier of meaning (WCAG 1.4.1).
 */
.wp-block-navigation a[ aria-current="page" ] {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 0.35em;
}

/*
 * The top-level menu items, at a size a finger can find.
 *
 * Core lays these out at the line height of the text, which came to 26px — that
 * is the *word*, not the target, exactly as the hamburger below is the icon
 * rather than the target. It reads as fine on a desk with a mouse and is not:
 * the same bar is what somebody uses on a tablet, or a touchscreen laptop, and
 * "Community Council" opening a submenu is the most-pressed control on the site.
 *
 * Found by measuring every control on every page of a drill rather than by
 * looking, because 26px looks perfectly reasonable in a screenshot.
 *
 * The padding does the work rather than a fixed height, so a menu item that
 * wraps to two lines grows instead of overflowing.
 */
.wp-block-navigation__container > .wp-block-navigation-item > :is( a, button, .wp-block-navigation-item__content ) {
	align-items: center;
	display: flex;
	min-height: 44px;
	padding-block: 0.5rem;
}

/*
 * The hamburger, at a size a thumb can find.
 *
 * Core draws it at 24px, which is the icon rather than the target — and on a
 * phone it is the only way into the site at all, so it is worth more room than
 * the minimum anything else gets.
 */
.wp-block-navigation__responsive-container-open {
	align-items: center;
	display: flex;
	justify-content: center;
	min-height: 48px;
	min-width: 48px;
}

.wp-block-navigation__responsive-container-open svg {
	height: 30px;
	width: 30px;
}

/* -------------------------------------------------------------------------
 * The menu on a phone.
 *
 * This is the whole navigation of the site on one screen, and it was arriving
 * as a flat list of twenty-odd items with no padding — the first word started
 * at the very edge of the glass — no separation between sections, and no
 * difference in weight between "Venues" and the four pages under it. Correct
 * markup, no shape.
 *
 * The padding has to be restated because something in the header's own layout
 * is zeroing the block's; the rest is hierarchy. A section heading is heavier
 * and sits on a hairline; its children are lighter, smaller, and held by a
 * rule down the left so the eye can see where the group starts and stops
 * without counting indents.
 * ---------------------------------------------------------------------- */

/*
 * Three classes deep on purpose. The block's own stylesheet is printed after
 * the theme's and sets this padding itself, so a two-class selector loses the
 * cascade silently — which is how the menu came to start at the very edge of
 * the screen despite core shipping a sensible default.
 */
.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open {
	background-color: var( --wp--preset--color--base );
	padding:
		var( --wp--preset--spacing--20 )
		var( --wp--preset--spacing--30 )
		var( --wp--preset--spacing--40 );
}

/* Clear of the close button, which core pins to the top-right corner. */
.is-menu-open .wp-block-navigation__responsive-container-content {
	padding-top: var( --wp--preset--spacing--10 );
}

/*
 * A 24px icon is not a target. The button keeps its size but gains the room
 * around it that makes it hittable with a thumb (WCAG 2.5.5).
 */
.is-menu-open .wp-block-navigation__responsive-container-close {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: var( --wp--custom--field--target, 44px );
	min-width: var( --wp--custom--field--target, 44px );
}

/* The list runs on dividers instead of gaps. */
.is-menu-open .wp-block-navigation__container {
	gap: 0;
	width: 100%;
}

.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item {
	border-top: 1px solid var( --wp--preset--color--border );
	display: block;
	width: 100%;
}

.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:first-child {
	border-top: 0;
}

/*
 * Both `a` and `button`: a top-level item with children is rendered as a
 * button, not a link, so styling only the links would leave "Venues" and
 * "Community Council" looking like stray text — which is exactly how they
 * looked.
 */
.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item > :is( a, button, .wp-block-navigation-item__content ) {
	align-items: center;
	color: var( --wp--preset--color--primary-dark );
	display: flex;
	font-size: var( --wp--preset--font-size--large );
	font-weight: 600;

	/*
	 * The target is 44px, and the padding is what is left over rather than
	 * something added on top of it. Twenty-six items each carrying an extra
	 * 24px of air is a menu three screens long, and a menu you have to scroll
	 * to the bottom of is not navigation, it is a list.
	 */
	min-height: var( --wp--custom--field--target, 44px );
	padding: 0;
	text-decoration: none;
	width: 100%;
}

/*
 * The children of a section, gathered under one rule.
 *
 * The selector is long because core's is. The rule being overridden is
 *
 *   .wp-block-navigation__responsive-container.is-menu-open:where(:not(.disable-default-overlay))
 *     .wp-block-navigation__responsive-container-content
 *     .has-child
 *     .wp-block-navigation__submenu-container { border: none; padding-left: 2rem }
 *
 * — five classes, since `:where()` contributes nothing. Anything shorter loses
 * silently and looks like the border colour is wrong rather than the rule
 * never applying. This one matches that path and adds the `.wp-block-navigation`
 * ancestor, so it wins on specificity rather than on luck about load order.
 */
.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .has-child .wp-block-navigation__submenu-container {
	background-color: transparent;
	border: 0;
	border-left: 2px solid var( --wp--preset--color--border );
	margin: 0 0 var( --wp--preset--spacing--20 );
	min-width: 0;
	padding: 0 0 0 var( --wp--preset--spacing--30 );
	position: static;
	width: 100%;
}

.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	align-items: center;
	color: var( --wp--preset--color--contrast );
	display: flex;
	font-size: var( --wp--preset--font-size--medium );
	font-weight: 400;
	min-height: var( --wp--custom--field--target, 44px );
	padding: 0;
	text-decoration: none;
	width: 100%;
}

.is-menu-open .wp-block-navigation-item__content:hover {
	text-decoration: underline;
}

/* The page you are on, in the overlay too. */
.is-menu-open [ aria-current="page" ] {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 0.3em;
}

/* -------------------------------------------------------------------------
 * The hero.
 *
 * A gradient rather than a flat panel, with a hairline along the bottom so it
 * ends on a line instead of a smudge. Forced-colours mode discards both and
 * gets a plain band, which is the correct outcome.
 * ---------------------------------------------------------------------- */

/*
 * Tall enough to be a photograph, short enough that the diary shows underneath.
 *
 * The height is here rather than in the block's own inline style so it can
 * answer to the screen. A hero that fills the phone is a hero somebody has to
 * scroll past on faith; leaving the first "Coming up" row peeking over the
 * bottom edge is what tells them there is a village diary down there at all.
 *
 * `svh` is the small viewport height — the window as it is when the browser's
 * address bar is showing — so the hero does not grow and shrink as the bar
 * hides and reappears on scroll. `vh` first for anything that has not heard of
 * it. Clamped at both ends so a short laptop window cannot squash it and a
 * tall desktop cannot turn it into a poster.
 */
.ac-hero {
	border-bottom: var( --wp--custom--border--width ) solid var( --wp--preset--color--primary-dark );
	min-height: clamp( 9rem, 24vh, 15rem );
	min-height: clamp( 9rem, 24svh, 15rem );
}

@media ( min-width: 48rem ) {

	.ac-hero {
		min-height: clamp( 12rem, 32vh, 20rem );
		min-height: clamp( 12rem, 32svh, 20rem );
	}
}

/*
 * And the diary starts sooner on a phone, so the tease is a tease rather than
 * a rumour below a screen of white.
 *
 * `!important` because the section's padding is an inline style written by the
 * block editor, and inline styles cannot be outbid by specificity. The
 * alternative is hard-coding a second padding into the template where the
 * editor cannot see it, which is worse: it would silently ignore anybody who
 * later changed the spacing in the editor.
 */
@media ( max-width: 48rem ) {

	.ac-hero + .wp-block-group {
		padding-top: var( --wp--preset--spacing--40 ) !important;
	}
}

.ac-hero .wp-block-heading {
	text-wrap: balance;
}

/*
 * A scrim that is dark where the words are and clear where the picture is.
 *
 * A flat dim has to be set for the brightest pixel anywhere in the frame — the
 * white wheelhouse of the boat — which meant 70% across the whole photograph
 * to keep white text at 4.5:1, and at 70% the bay is a grey-green smudge. This
 * puts the darkness where it is needed instead: heavy on the left behind the
 * heading, gone by the right-hand side where the boat is. The block's own dim
 * drops to 40%, so the picture is a picture again.
 *
 * Measured: 0.4 + 0.6 x 0.6 = 0.76 effective behind the text, which is 6.9:1
 * for white over the worst case; 0.4 over the boat, where nothing is written.
 */
.ac-hero::before {
	background: linear-gradient(
		90deg,
		color-mix( in srgb, var( --wp--preset--color--deep ) 60%, transparent ) 0%,
		color-mix( in srgb, var( --wp--preset--color--deep ) 42%, transparent ) 42%,
		transparent 72%
	);
	content: "";
	inset: 0;
	pointer-events: none;
	position: absolute;
	z-index: 1;
}

/* The words sit above the scrim, not under it. */
.ac-hero > .wp-block-cover__inner-container {
	position: relative;
	z-index: 2;
}

/*
 * On a phone the text runs the full width, so there is no clear side to fade
 * towards. A single even veil, and the photograph gives up a little more of
 * itself — which is the correct trade when the alternative is text nobody can
 * read in daylight.
 */
@media ( max-width: 48rem ) {

	.ac-hero::before {
		background: color-mix( in srgb, var( --wp--preset--color--deep ) 45%, transparent );
	}
}

/*
 * A small line above the title. It says where this is, which a village site
 * cannot assume its reader knows, and it gives the heading something to sit
 * against so it does not start cold at the top of a photograph.
 */
.ac-eyebrow {
	font-size: var( --wp--preset--font-size--small );
	font-weight: 600;
	letter-spacing: var( --wp--custom--tracking--caps );
	margin-bottom: 0;
	opacity: 0.85;
	text-transform: uppercase;
}

/* -------------------------------------------------------------------------
 * Picture cards.
 *
 * The picture is the top of the card, edge to edge, with the card's corners
 * cutting it — which is what stops three photographs of different subjects
 * looking like three loose images with captions.
 * ---------------------------------------------------------------------- */

.ac-card {
	background-color: var( --wp--preset--color--base );
	border: var( --wp--custom--border--width ) solid var( --wp--preset--color--border );
	border-radius: var( --wp--custom--radius--lg );
	box-shadow: var( --wp--custom--shadow--sm );
	overflow: hidden;
	transition:
		box-shadow var( --wp--custom--motion--settle ) var( --wp--custom--motion--ease ),
		transform var( --wp--custom--motion--settle ) var( --wp--custom--motion--ease );
}

.ac-card:hover,
.ac-card:focus-within {
	box-shadow: var( --wp--custom--shadow--lg );
	transform: translateY( -3px );
}

/*
 * Every card's picture is the same shape whatever the photograph is. A 3:1
 * panorama beside a 4:3 painting makes a row of cards look like a mistake, and
 * the fix belongs here rather than in a crop of somebody's original.
 */
.ac-card .ac-card__image {
	margin: 0;
}

.ac-card .ac-card__image img {
	aspect-ratio: 3 / 2;
	border-radius: 0;
	display: block;
	object-fit: cover;
	transition: transform var( --wp--custom--motion--settle ) var( --wp--custom--motion--ease );
	width: 100%;
}

/*
 * The lift moves the card; this moves the picture inside it, which is the
 * cheapest way to make a card feel like a thing rather than a box. Contained
 * by `overflow: hidden` on the card, and removed entirely under
 * prefers-reduced-motion below.
 */
.ac-card:hover .ac-card__image img,
.ac-card:focus-within .ac-card__image img {
	transform: scale( 1.04 );
}

.ac-card :is( h3, h4 ) a {
	text-decoration: none;
}

.ac-card :is( h3, h4 ) a:hover {
	text-decoration: underline;
}

/*
 * The whole card is the target, not just the four words of the heading. The
 * link keeps its own focus ring — the overlay is `::after` on the anchor, so
 * focus and hit area stay attached to the real control rather than being faked
 * on the container.
 */
.ac-card {
	position: relative;
}

.ac-card :is( h3, h4 ) a::after {
	content: "";
	inset: 0;
	position: absolute;
}

/* -------------------------------------------------------------------------
 * Cards: news posts, and the card-grid pattern.
 *
 * The lift on hover is 2px and 220ms — enough to say "this is one thing you
 * can click", not enough to be a performance. It is a `transform`, so it
 * cannot reflow the page, and the reduced-motion block below turns it off.
 * ---------------------------------------------------------------------- */

.ac-news .wp-block-post,
.wp-block-columns .wp-block-column.has-background {
	transition:
		box-shadow var( --wp--custom--motion--settle ) var( --wp--custom--motion--ease ),
		transform var( --wp--custom--motion--settle ) var( --wp--custom--motion--ease );
}

.ac-news .wp-block-post {
	background: var( --wp--preset--color--base );
	border: var( --wp--custom--border--width ) solid var( --wp--preset--color--border );
	border-radius: var( --wp--custom--radius--lg );
	box-shadow: var( --wp--custom--shadow--sm );
	padding: var( --wp--preset--spacing--30 );
}

.ac-news .wp-block-post > :first-child {
	margin-block-start: 0;
}

.ac-news .wp-block-post > :last-child {
	margin-block-end: 0;
}

/*
 * Cards in a row all reach the bottom of the row. Grid already stretches its
 * items, so nothing here sets a height — an earlier `height: 100%` did, and it
 * pushed the first card past the end of its own row, which put the "All news"
 * link underneath it rather than below the grid.
 */
.ac-news .wp-block-post {
	display: flex;
	flex-direction: column;
}

/*
 * The date leads, as a small label rather than a line of grey text above the
 * headline. It is the same accent the section rules use, so a reader who has
 * already learned that colour means "this is the site talking" reads it
 * without having to work anything out.
 */
.ac-news__date {
	color: var( --wp--preset--color--accent );
	font-family: var( --wp--preset--font-family--sans );
	font-weight: 600;
	letter-spacing: var( --wp--custom--tracking--caps );
	text-transform: uppercase;
}

/*
 * The excerpt sits under the title rather than being pushed to the foot of the
 * card. Pinning it to the bottom lined the excerpts up with each other, which
 * sounds tidy and reads as a mistake: a two-line item ended up with a hand's
 * width of blank card between its headline and its text.
 */
.ac-news .wp-block-post-excerpt {
	margin-block-end: 0;
	margin-block-start: var( --wp--preset--spacing--20 );
}

.ac-news .wp-block-post-title {
	text-wrap: balance;
}

/*
 * The "All news" link clears the grid. Without this it rode up over the foot of
 * the first card, because the post template is a grid and the paragraph after
 * it had nothing to sit below.
 */
.ac-news + p,
.ac-news ~ p:first-of-type {
	margin-block-start: var( --wp--preset--spacing--30 );
}

/* -------------------------------------------------------------------------
 * Search results: what each one is.
 *
 * A search here returns pages, news, events, meeting papers and newsletters
 * together, so the kind is not decoration — it is the difference between a
 * permanent page and something happening on Tuesday. Same accent as the news
 * dates, because it does the same job: the site telling you how to read what
 * follows.
 * ---------------------------------------------------------------------- */

.ac-result__kind {
	color: var( --wp--preset--color--accent );
	font-family: var( --wp--preset--font-family--sans );
	font-weight: 600;
	letter-spacing: var( --wp--custom--tracking--caps );
	margin-block: 0.15rem 0.35rem;
	text-transform: uppercase;
}

.ac-news .wp-block-post:hover,
.wp-block-columns .wp-block-column.has-background:hover {
	box-shadow: var( --wp--custom--shadow--md );
	transform: translateY( -2px );
}

/*
 * The whole card reacts when the link inside it is keyboard-focused, so a
 * keyboard user gets the same signal a mouse user does.
 */
.ac-news .wp-block-post:focus-within,
.wp-block-columns .wp-block-column.has-background:focus-within {
	box-shadow: var( --wp--custom--shadow--md );
}

/* -------------------------------------------------------------------------
 * Notes: the aside that says what is still missing, or what to be careful of.
 *
 * This existed on four pages before it existed here, as roughly 700 characters
 * of inline padding and border-radius repeated on each — which meant a
 * councillor who wanted another one had to copy raw block markup out of a
 * different page, and a change of style meant editing every page that had one.
 *
 * One class, one definition, and a block pattern that inserts it.
 *
 * The left rule rather than a full border: it reads as an aside on a page of
 * running text without shouting, and it survives forced-colours mode, where a
 * background tint would be repainted and the box would vanish.
 * ---------------------------------------------------------------------- */

.ac-note {
	background-color: var( --wp--preset--color--surface );
	border-left: 3px solid var( --wp--preset--color--border-strong );
	border-radius: var( --wp--custom--radius--md );
	padding: var( --wp--preset--spacing--30 );
}

.ac-note > :first-child {
	margin-block-start: 0;
}

.ac-note > :last-child {
	margin-block-end: 0;
}

/*
 * Forced colours repaints the tint away, so the rule has to be a real border
 * in a system colour rather than a decorative one.
 */
@media ( forced-colors: active ) {

	.ac-note {
		border: 1px solid CanvasText;
		border-left-width: 3px;
	}
}

/* -------------------------------------------------------------------------
 * Page headers.
 *
 * These were a filled grey band running the width of the screen with a very
 * large title and a very large paragraph inside it — the same slab on News, on
 * the archives and on search results. It read as a heavy lid clamped over the
 * page rather than as an introduction to it, and because the standfirst ran the
 * full measure it was a wall of muted text before anything useful began.
 *
 * The tint is gone. What is left does the same job with the site's own
 * vocabulary: the accent rule that already marks the start of every section, a
 * standfirst held to a readable measure, and a hairline to separate the
 * introduction from the content rather than a block of colour.
 * ---------------------------------------------------------------------- */

.ac-page-header {
	border-bottom: var( --wp--custom--border--width ) solid var( --wp--preset--color--border );
	padding-block: var( --wp--preset--spacing--30 ) var( --wp--preset--spacing--40 );
}

.ac-page-header > * {
	margin-block: 0;
}

/*
 * The same rule the section headings carry, so a reader who has learned what it
 * means on an h2 reads it the same way here.
 */
.ac-page-header h1::after {
	background: var( --wp--custom--rule--accent );
	border-radius: var( --wp--custom--radius--pill );
	content: "";
	display: block;
	height: var( --wp--custom--rule--height );
	margin-top: var( --wp--preset--spacing--20 );
	width: var( --wp--custom--rule--width );
}

/*
 * A standfirst is read, not scanned, so it gets a line length you can read —
 * about 60 characters — rather than the full width of a laptop.
 */
/*
 * No `max-width` here, deliberately.
 *
 * Capping the measure looked right and was not: a constrained layout centres
 * any child narrower than itself, using `margin: auto !important`, so the
 * standfirst quietly indented away from the heading it belongs to and no
 * override could win. The page's own content width is already about forty
 * characters wide, which is the measure the cap was reaching for.
 */
.ac-page-header__lead {
	margin-block-start: var( --wp--preset--spacing--30 );
}

/* -------------------------------------------------------------------------
 * Buttons: a little weight on hover.
 * ---------------------------------------------------------------------- */

.wp-element-button,
.wp-block-button__link {
	transition:
		background-color var( --wp--custom--motion--quick ) var( --wp--custom--motion--ease ),
		box-shadow var( --wp--custom--motion--quick ) var( --wp--custom--motion--ease ),
		transform var( --wp--custom--motion--quick ) var( --wp--custom--motion--ease );
}

.wp-block-button__link:hover {
	box-shadow: var( --wp--custom--shadow--md );
	transform: translateY( -1px );
}

/* -------------------------------------------------------------------------
 * Motion: respect the user's reduced-motion preference.
 * ---------------------------------------------------------------------- */

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

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
		transition-duration: 0.01ms !important;
	}

	/*
	 * Duration alone is not enough: a transform that snaps into place is still
	 * movement. The lift is removed outright, and the shadow does the work.
	 */
	.ac-news .wp-block-post:hover,
	.wp-block-columns .wp-block-column.has-background:hover,
	.wp-block-button__link:hover,
	.ac-card:hover,
	.ac-card:focus-within,
	.ac-card:hover .ac-card__image img,
	.ac-card:focus-within .ac-card__image img {
		transform: none;
	}
}
