/*
Theme Name:   Purple Pushpin Chapter
Theme URI:    https://purplepushpin.com
Description:  The chapter site theme for Purple Pushpin. A child of Kadence: the parent does the heavy lifting, and this holds the handful of things that are ours — the front-end styling for registration and directory blocks, the footer credit, and a safe place for a chapter's own CSS that survives a Kadence update. Designed once and cloned per chapter, so nothing chapter-specific is ever typed into it.
Author:       Purple Wave Creative
Author URI:   https://purplewavecreative.com
Template:     kadence
Version:      1.10.1
License:      GNU General Public License v2 or later
License URI:  https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  purple-pushpin-chapter
Tags:         blog, one-column, custom-colors, custom-menu, editor-style, full-site-editing
*/

/*
 * WHY THIS FILE IS NEARLY EMPTY, and should stay that way.
 *
 * Kadence's own settings do layout, colour, type and spacing far better than
 * hand-written CSS in a child theme, and they survive being changed by a person
 * who is not a developer. Anything set here instead is invisible to the
 * customiser, so the next person to touch the site cannot find it and cannot
 * change it without us.
 *
 * The rule: if Kadence can do it, do it in Kadence. This file is only for the
 * things it cannot — our own blocks, and genuine one-off fixes.
 */

/* -------------------------------------------------------------------------
 * The chapter's brand colour, borrowed from Chapter settings.
 *
 * Set as variables rather than applied directly, so a chapter that later wants
 * a different accent on one element can override a single variable instead of
 * fighting a selector. Values come from functions.php; these are the fallbacks
 * for a site where the plugin is switched off.
 * ---------------------------------------------------------------------- */

:root {
	--pushpin-brand: #4632c9;
	--pushpin-brand-dark: #251a72;
	--pushpin-ink: #101030;
	--pushpin-line: rgba(16, 12, 48, .12);
}

/* -------------------------------------------------------------------------
 * Our own front-end blocks.
 *
 * The plugin ships its own styles for these and prints them only on pages that
 * use them. What is here is the small amount of theme-side polish that depends
 * on Kadence's type scale, which the plugin cannot know about.
 * ---------------------------------------------------------------------- */

.pushpin-register,
.pushpin-directory {
	margin-block: clamp(28px, 5vw, 48px);
}

/* Give the registration panel the same rhythm as Kadence's own content blocks. */
.pushpin-register-heading {
	font-size: var(--global-kb-font-size-lg, 1.35rem);
}

/*
 * The seats-left warning. Deliberately a warm red rather than the brand colour:
 * it is the one piece of text on the page whose job is to be read before
 * anything else, and brand purple on a purple site is not that.
 */
.pushpin-register-left {
	color: #9a3412;
}

/* -------------------------------------------------------------------------
 * The footer credit.
 *
 * Small, quiet, and not a link farm — one branded anchor, no keyword text.
 * ---------------------------------------------------------------------- */

.pushpin-credit {
	margin: 0;
	font-size: 13px;
	opacity: .7;
}

.pushpin-credit a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* -------------------------------------------------------------------------
 * Print.
 *
 * A chapter secretary printing an event page for a board packet should not get
 * the navigation, the footer or a registration form with empty boxes in it.
 * Costs nothing and comes up more often than you would think.
 * ---------------------------------------------------------------------- */

@media print {
	.site-header,
	.site-footer,
	.pushpin-register-form,
	.pushpin-notify-form {
		display: none !important;
	}

	body {
		font-size: 12pt;
	}
}

/* -------------------------------------------------------------------------
 * The public site: events, board, directory, and the home page sections.
 *
 * WHY THIS IS HERE AND NOT IN THE PLUGIN. The plugin prints this markup but
 * ships no front-end CSS at all, which means [pushpin_events] renders as a
 * stack of unstyled links on any site that has not been designed by hand.
 * That is fine for a bespoke build and wrong for everybody else, so the
 * theme carries a decent default: a chapter that never hires a designer
 * still gets something that looks deliberate.
 *
 * Everything below is written against the plugin's own class names and uses
 * --pushpin-brand, which the board can change from Chapter settings.
 * ---------------------------------------------------------------------- */

:root {
	--pushpin-brand: #2f1c56;
	--pushpin-ink: #1e1633;
	--pushpin-soft: #5f5478;
	--pushpin-line: #e6e1f0;
	--pushpin-paper: #faf9fd;
	--pushpin-radius: 10px;
}

/* ---- Event wall ------------------------------------------------------- */

/*
 * A STATED NUMBER OF COLUMNS, not auto-fill.
 *
 * auto-fill packs in as many tiles as the width allows, so the same page came
 * out four across on a wide monitor and two on a laptop — and a chapter that
 * laid their page out on one never saw what the other looked like. Three by
 * default, set with [pushpin_events columns="3"], and it steps down on smaller
 * screens by values PHP works out rather than media queries, because a custom
 * property set inline cannot be overridden by a later rule.
 *
 * minmax(0, 1fr) rather than 1fr: a grid track defaults to a minimum of auto,
 * so a long event title would push its column past its share.
 */
.am-wall {
	display: grid;
	gap: 1.5rem;
	grid-template-columns: repeat(var(--am-wall-cols, 3), minmax(0, 1fr));
	margin: 2rem 0;
	align-items: start;
}

@media (max-width: 900px) {
	.am-wall { grid-template-columns: repeat(var(--am-wall-cols-md, 2), minmax(0, 1fr)); }
}

@media (max-width: 600px) {
	.am-wall { grid-template-columns: 1fr; }
}

/* A quiet inline link — "See past events", "Back to what is coming up".
   Deliberately not a button: it is a side door, and a second button beside the
   Register buttons would compete with the thing the page is actually for. */
.pushpin-morelink {
	margin: 1.5rem 0 0;
	font-size: .95rem;
}

.pushpin-morelink a {
	color: var(--pushpin-brand);
	font-weight: 600;
	text-decoration: none;
}

.pushpin-morelink a:hover,
.pushpin-morelink a:focus-visible { text-decoration: underline; }

/* ---- The list layout ---------------------------------------------------
 *
 * For a chapter with no artwork and a monthly lunch, one readable line per
 * event beats a wall of generated posters. Same markup, different shape: the
 * poster is dropped and the card becomes a row.
 */
.am-wall--list {
	grid-template-columns: 1fr;
	gap: 0;
	border-top: 1px solid var(--pushpin-line);
}

.am-wall--list .am-ev {
	flex-direction: row;
	align-items: center;
	gap: 1.25rem;
	border: 0;
	border-bottom: 1px solid var(--pushpin-line);
	border-radius: 0;
	padding: 1.1rem .25rem;
}

.am-wall--list .am-ev:hover { transform: none; box-shadow: none; }

/* The generated poster is decoration. In a list it would be a thumbnail
   competing with the date, so it goes entirely. */
.am-wall--list .am-ev__poster { display: none; }

/*
 * FOUR columns, not three: when, what, where, and the button.
 *
 * Three was the first attempt and the row came out 113px tall — .am-ev__foot
 * is a fourth child of this element, so it wrapped onto a second line and put
 * the Register button under the date. The count has to match the children, and
 * the children are the four things a person scanning a list of dates wants.
 */
.am-wall--list .am-ev__meta {
	margin: 0;
	flex: 1 1 auto;
	display: grid;
	grid-template-columns: minmax(10rem, 13rem) minmax(0, 1fr) minmax(0, auto) auto;
	align-items: center;
	gap: 1.25rem;
}

.am-wall--list .am-ev__when { margin: 0; }
.am-wall--list .am-ev__title { margin: 0; font-size: 1.05rem; }
.am-wall--list .am-ev__where { margin: 0; }

.am-wall--list .am-ev__foot {
	margin: 0;
	padding: 0;
	justify-content: flex-end;
	gap: 1rem;
}

@media (max-width: 980px) {
	/* The venue is the first thing to go — it is the least useful of the four
	   when the row is tight, and it is still on the event's own page. */
	.am-wall--list .am-ev__meta { grid-template-columns: minmax(9rem, 12rem) minmax(0, 1fr) auto; }
	.am-wall--list .am-ev__where { display: none; }
}

@media (max-width: 780px) {
	.am-wall--list .am-ev { flex-direction: column; align-items: stretch; }
	.am-wall--list .am-ev__meta { grid-template-columns: 1fr; gap: .3rem; }
	.am-wall--list .am-ev__where { display: block; }
	.am-wall--list .am-ev__foot { justify-content: flex-start; margin-top: .6rem; }
}

.am-ev {
	/* position: relative is what lets the Register link stretch over the whole
	   tile — see .am-ev__cta::after. */
	position: relative;
	display: flex;
	flex-direction: column;
	background: #fff;
	border: 1px solid var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	overflow: hidden;
	transition: transform .15s ease, box-shadow .15s ease;
}

.am-ev:hover {
	transform: translateY(-2px);
	box-shadow: 0 8px 24px rgba(31, 22, 51, .10);
}

.am-ev__poster {
	position: relative;
	display: block;
	aspect-ratio: 3 / 2;
	background: var(--pushpin-paper);
}

.am-ev__poster img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* The generated poster shown when a chapter has not uploaded a flyer. Most
   events never get one, so this is the common case, not the fallback. */
.am-ev__auto {
	display: flex;
	flex-direction: column;
	justify-content: center;
	height: 100%;
	padding: 1.4rem;
	background: linear-gradient(150deg, var(--pushpin-brand), #6b3fd4);
	color: #fff;
}

.am-ev__auto-date { font-size: .8rem; letter-spacing: .1em; text-transform: uppercase; opacity: .85; }
.am-ev__auto-name { font-size: 1.3rem; font-weight: 700; line-height: 1.2; margin: .35rem 0; }
.am-ev__auto-org  { font-size: .85rem; opacity: .85; }
.am-ev__auto-wave { position: absolute; inset: auto 0 0 0; height: 40%; opacity: .18; }

.am-ev__flag {
	position: absolute;
	top: .75rem;
	left: .75rem;
	background: rgba(255, 255, 255, .92);
	color: var(--pushpin-ink);
	font-size: .72rem;
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	padding: .3em .6em;
	border-radius: 999px;
}

.am-ev__title {
	font-size: 1.1rem;
	line-height: 1.3;
	margin: 1rem 1.1rem .4rem;
}

.am-ev__title { color: var(--pushpin-ink); }

/* The title follows the tile's hover rather than carrying its own, because the
   whole tile is one link now and only one thing should look interactive. */
.am-ev:hover .am-ev__title { color: var(--pushpin-brand); }

.am-ev__meta {
	margin: 0 1.1rem;
	color: var(--pushpin-soft);
	font-size: .9rem;
	line-height: 1.5;
}

.am-ev__when { display: block; font-weight: 600; color: var(--pushpin-ink); }
.am-ev__where { display: block; }

.am-ev__foot {
	display: flex;
	align-items: center;
	gap: .6rem;
	flex-wrap: wrap;
	margin: auto 1.1rem 1.1rem;
	padding-top: 1rem;
}

.am-ev__price {
	font-weight: 700;
	color: var(--pushpin-ink);
}

.am-ev__types {
	font-size: .8rem;
	color: var(--pushpin-soft);
}

.am-ev__cta {
	margin-left: auto;
	background: var(--pushpin-brand);
	color: #fff;
	text-decoration: none;
	font-size: .85rem;
	font-weight: 600;
	padding: .55em 1.1em;
	border-radius: 6px;
}

.am-ev__cta:hover { background: #6b3fd4; color: #fff; }

/*
 * A past event is not something you register for, so its control does not
 * dress like one.
 *
 * Placed AFTER the rule it overrides on purpose. The first version sat higher
 * up the file, and since both selectors score the same the base rule won on
 * order alone — the class was on the element, the declaration was in the
 * stylesheet, and the button was still brand purple.
 */
.am-ev__cta--quiet {
	background: var(--pushpin-paper);
	color: var(--pushpin-ink);
}

.am-ev__cta--quiet:hover,
.am-ev__cta--quiet:focus { background: #e6e0f6; color: var(--pushpin-ink); }

/*
 * The whole tile is the link.
 *
 * This CTA used to be a <span> — it looked exactly like a button and did
 * nothing when clicked, which is the first thing anybody tries on this page.
 * It is a real anchor now, and this pseudo-element extends its hit area over
 * the entire card so a click anywhere works, without nesting anchors or
 * wrapping the card in one.
 */
.am-ev__cta::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* The focus ring belongs around the tile, not the small button, because the
   tile is what the link actually covers. */
.am-ev__cta:focus-visible { outline: none; }
.am-ev:has(.am-ev__cta:focus-visible) {
	outline: 2px solid var(--pushpin-brand);
	outline-offset: 3px;
}

.am-wall__empty,
.am-board__empty {
	color: var(--pushpin-soft);
	font-style: italic;
}

/* ---- Month headings on the events page --------------------------------
 *
 * The grid closes and reopens around each of these rather than the heading
 * being a grid item, because a heading inside the grid takes one cell — it
 * would sit beside a tile instead of above the row, and the tiles either side
 * would stop lining up.
 */
.am-wall__month {
	margin: 2.5rem 0 1rem;
	font-size: .82rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .09em;
	color: var(--pushpin-soft);
	display: flex;
	align-items: center;
	gap: 1rem;
}

/* A rule running out from the label to the edge, so the eye can see where one
   month stops without the label having to shout. */
.am-wall__month::after {
	content: "";
	flex: 1 1 auto;
	height: 1px;
	background: var(--pushpin-line);
}

.am-wall__month:first-child { margin-top: .5rem; }

/* ---- The page title banner --------------------------------------------
 *
 * The theme opens every page with a full-width tinted band carrying nothing
 * but the title — around 200px of empty colour before a visitor reads a word.
 * Off by default, per page, from the checkbox in the editor.
 *
 * QUIETENED, NOT HIDDEN. `display: none` on the section was the first
 * instinct and it is wrong: the band and the page's <h1> are the same piece of
 * markup, so hiding one hides the other, and a page with no h1 is a page a
 * search engine cannot summarise. A chamber that wants to be found for its own
 * board needs those words in a heading. So the band loses its tint and its
 * reserved height and the title stays, as an ordinary heading above the
 * content.
 */
.pushpin-banner-off .entry-hero-container-inner {
	background: none;
	background-color: transparent;
}

.pushpin-banner-off .entry-hero .entry-header,
.pushpin-banner-off .entry-header.page-title {
	min-height: 0;
	padding-top: clamp(1.5rem, 4vw, 2.5rem);
	padding-bottom: 0;
	text-align: left;
	/*
	 * ALIGN-ITEMS is what moves it. Three attempts on this one element, so the
	 * reasoning is worth keeping:
	 *
	 *   text-align: left      — no effect. The h1 is a flex ITEM, so its own box
	 *                           is what is positioned, not the text inside it.
	 *   justify-content: start — no effect either, and this is the subtle one.
	 *                           The theme sets flex-direction: column on this
	 *                           header, which makes justify-content the VERTICAL
	 *                           axis. It applied cleanly and moved nothing.
	 *   align-items: start    — correct. On a column flex container the cross
	 *                           axis is the horizontal one.
	 *
	 * All three were measured on the deployed page rather than reasoned about,
	 * which is the only reason the second one was caught: it computed exactly as
	 * written and still looked broken.
	 */
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: flex-start;
}

.pushpin-banner-off .entry-hero .entry-title {
	font-size: clamp(1.9rem, 4vw, 2.5rem);
	line-height: 1.15;
	margin: 0;
}

/* The theme puts breathing room under the hero for the band that is no longer
   there. */
.pushpin-banner-off .entry-hero-container-inner { padding-bottom: 0; }

/* ---- Board ------------------------------------------------------------ */

/*
 * A FIXED NUMBER OF COLUMNS, WORKED OUT IN PHP.
 *
 * This used to be auto-fill with a 200px minimum, which is the responsive
 * default everybody reaches for and it is wrong for a roster: it fits as many
 * as it can and leaves whatever is left over on the last row. Eight board
 * members came out as five and three, and it read as a mistake rather than a
 * layout.
 *
 * The count now comes from pushpin_board_columns(), which picks whichever
 * number fills the last row — 4 + 4 for eight people, 3 + 3 + 3 for nine — and
 * a chapter can override it with [pushpin_board columns="4"].
 *
 * The three custom properties are set inline by the shortcode rather than the
 * narrow ones being hardcoded here, and that is deliberate: a custom property
 * set in a style attribute cannot be overridden by a later stylesheet rule, so
 * a media query saying "three across on a tablet" would win over a chapter that
 * had chosen two. PHP works out all three and each only ever steps down.
 *
 * minmax(0, 1fr) rather than 1fr, because a grid track defaults to a minimum of
 * auto — a long company name would push its column wider than its share and
 * knock the row out of alignment.
 */
.am-board {
	display: grid;
	gap: 1.4rem;
	grid-template-columns: repeat(var(--am-board-cols, 4), minmax(0, 1fr));
	margin: 2rem 0;
	/* start, not the default stretch: without it, opening one person's bio
	   stretches every other card in that row to match. */
	align-items: start;
}

@media (max-width: 900px) {
	.am-board { grid-template-columns: repeat(var(--am-board-cols-md, 3), minmax(0, 1fr)); }
}

@media (max-width: 600px) {
	.am-board { grid-template-columns: repeat(var(--am-board-cols-sm, 2), minmax(0, 1fr)); }
}

.am-bm { text-align: center; }

.am-bm__photo img {
	width: 108px;
	height: 108px;
	border-radius: 50%;
	object-fit: cover;
}

/* Initials rather than a grey silhouette. Most board members never send a
   photograph, and a page of identical placeholder heads looks abandoned. */
.am-bm__initials {
	width: 108px;
	height: 108px;
	margin: 0 auto;
	border-radius: 50%;
	display: grid;
	place-items: center;
	background: var(--pushpin-brand);
	color: #fff;
	font-size: 2rem;
	font-weight: 600;
	letter-spacing: .02em;
}

.am-bm__name { margin: .8rem 0 .1rem; font-size: 1rem; font-weight: 700; }

/*
 * THREE LINES, ONE FACT EACH: name, then position, then company.
 *
 * These were already separate elements and both were inline, so they flowed
 * into one paragraph and wrapped wherever the column happened to end —
 * "President Kestrel Marketing" on one line and "Group" on the next. Reading
 * it, you could not tell where the job title stopped and the employer started.
 * display: block is the whole fix.
 */
.am-bm__role {
	display: block;
	color: var(--pushpin-brand);
	font-size: .85rem;
	font-weight: 600;
	line-height: 1.4;
}

.am-bm__org {
	display: block;
	color: var(--pushpin-soft);
	font-size: .85rem;
	line-height: 1.4;
}

/* ---- Board contact icons ---------------------------------------------- */

/*
 * Only rendered for the links a person actually supplied — the markup prints
 * nothing when there are none, rather than a row of greyed-out placeholders.
 */
.am-bm__links {
	display: flex;
	justify-content: center;
	gap: .35rem;
	margin-top: .55rem;
}

.am-bm__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* 34px, comfortably over the 24px minimum for a touch target that sits
	   beside two others. */
	width: 34px;
	height: 34px;
	border-radius: 50%;
	color: var(--pushpin-soft);
	background: transparent;
	text-decoration: none;
	transition: background .15s ease, color .15s ease;
}

.am-bm__link:hover,
.am-bm__link:focus-visible {
	background: var(--pushpin-paper);
	color: var(--pushpin-brand);
}

.am-bm__link:focus-visible {
	outline: 2px solid var(--pushpin-brand);
	outline-offset: 2px;
}

.am-bm__icon { display: block; }

/* ---- Board bio --------------------------------------------------------- */

/*
 * A disclosure rather than a paragraph on the card.
 *
 * One board member with three sentences and seven with none turns an even grid
 * into a ragged one, and a roster people scan becomes a page people read.
 * <details> keeps every card the same height until somebody asks for more, and
 * costs no JavaScript.
 */
.am-bm__bio {
	margin-top: .5rem;
	font-size: .85rem;
	text-align: left;
}

.am-bm__bio summary {
	list-style: none;
	cursor: pointer;
	text-align: center;
	color: var(--pushpin-brand);
	font-weight: 600;
}

.am-bm__bio summary::-webkit-details-marker { display: none; }

.am-bm__bio summary::after {
	content: " \203A";
	display: inline-block;
	transition: transform .15s ease;
}

.am-bm__bio[open] summary::after { transform: rotate(90deg); }

.am-bm__bio summary:focus-visible {
	outline: 2px solid var(--pushpin-brand);
	outline-offset: 2px;
	border-radius: 4px;
}

.am-bm__bio p {
	margin: .5rem 0 0;
	color: var(--pushpin-soft);
	line-height: 1.55;
}

/* ---- Directory -------------------------------------------------------- */

.pushpin-directory-list {
	list-style: none;
	margin: 1.5rem 0;
	padding: 0;
	display: grid;
	gap: 1px;
	background: var(--pushpin-line);
	border: 1px solid var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	overflow: hidden;
}

.pushpin-directory-person {
	background: #fff;
	padding: 1rem 1.2rem;
}

.pushpin-directory-name { font-weight: 700; }
.pushpin-directory-company,
.pushpin-directory-where { color: var(--pushpin-soft); font-size: .9rem; }

.pushpin-directory-search {
	display: flex;
	gap: .6rem;
	flex-wrap: wrap;
	margin: 1.5rem 0;
}

.pushpin-directory-search input[type="search"],
.pushpin-directory-search input[type="text"] {
	flex: 1 1 240px;
	padding: .6em .8em;
	border: 1px solid var(--pushpin-line);
	border-radius: 6px;
}

.pushpin-directory-count { color: var(--pushpin-soft); font-size: .9rem; }

.pushpin-directory-gate {
	background: var(--pushpin-paper);
	border: 1px dashed var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	padding: 2rem;
	text-align: center;
	color: var(--pushpin-soft);
}

.pushpin-directory-tag {
	display: inline-block;
	background: var(--pushpin-paper);
	border: 1px solid var(--pushpin-line);
	border-radius: 999px;
	padding: .2em .7em;
	font-size: .78rem;
	color: var(--pushpin-soft);
}

/* ---- Home page sections ----------------------------------------------- */

.pushpin-hero {
	background: linear-gradient(150deg, var(--pushpin-brand), #6b3fd4);
	color: #fff;
	border-radius: var(--pushpin-radius);
	padding: clamp(2rem, 6vw, 4.5rem);
	margin-bottom: 3rem;
}

.pushpin-hero h1 {
	color: #fff;
	font-size: clamp(1.9rem, 5vw, 3rem);
	line-height: 1.1;
	margin: 0 0 .6rem;
}

.pushpin-hero p {
	font-size: 1.1rem;
	max-width: 34em;
	opacity: .92;
	margin: 0 0 1.6rem;
}

.pushpin-hero .pushpin-btn {
	background: #fff;
	color: var(--pushpin-brand);
}

.pushpin-hero .pushpin-btn:hover { background: #efe9fb; color: var(--pushpin-brand); }

.pushpin-hero .pushpin-btn--ghost {
	background: transparent;
	color: #fff;
	box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .6);
}

.pushpin-hero .pushpin-btn--ghost:hover { background: rgba(255, 255, 255, .12); color: #fff; }

.pushpin-btn {
	display: inline-block;
	background: var(--pushpin-brand);
	color: #fff;
	text-decoration: none;
	font-weight: 600;
	padding: .8em 1.6em;
	border-radius: 6px;
	margin-right: .6rem;
}

.pushpin-btn:hover { background: #6b3fd4; color: #fff; }

.pushpin-section { margin: 3.5rem 0; }

.pushpin-section > h2 {
	font-size: 1.6rem;
	margin: 0 0 .3rem;
}

.pushpin-section > .pushpin-section__lede {
	color: var(--pushpin-soft);
	margin: 0 0 1.5rem;
	max-width: 42em;
}

.pushpin-cols {
	display: grid;
	gap: 1.6rem;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.pushpin-col h3 { font-size: 1.05rem; margin: 0 0 .3rem; }
.pushpin-col p  { color: var(--pushpin-soft); margin: 0; }

.pushpin-callout {
	background: var(--pushpin-paper);
	border: 1px solid var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	padding: 2rem;
}

.pushpin-callout h2 { margin-top: 0; }

@media print {
	.am-ev__cta,
	.pushpin-hero .pushpin-btn {
		display: none !important;
	}
}

/* -------------------------------------------------------------------------
 * No page title on the front page.
 *
 * Kadence prints a title banner above the content on every page, which on a
 * home page means the word "Home" in large type directly above the hero that
 * already says who the chapter is. Everywhere else the banner is useful, so
 * this is scoped to the front page only.
 * ---------------------------------------------------------------------- */

body.home .entry-hero,
body.home .entry-hero-container-inner,
body.home .page-title,
body.home .entry-hero-section {
	display: none !important;
}

/* -------------------------------------------------------------------------
 * Split hero, with the next event beside the pitch.
 *
 * The panel is optional by design: [pushpin_next_event] prints nothing when
 * the calendar is empty, and because this is a grid with auto columns the
 * hero simply closes up around the gap rather than leaving a hole.
 * ---------------------------------------------------------------------- */

/*
 * The single-card hero, used on the events page.
 *
 * Same block as the home page, minus the pitch beside it — anybody on the
 * events page has already been sold on the idea of events. Padding is trimmed
 * so the card is the hero rather than sitting in the middle of a large empty
 * gradient.
 */
.pushpin-hero--single {
	display: flex;
	padding: clamp(1.25rem, 3vw, 2rem);
	margin-bottom: 2.5rem;
}

.pushpin-hero--single .pushpin-next {
	flex: 1 1 auto;
	max-width: none;
}

.pushpin-hero--split {
	display: grid;
	grid-template-columns: 1.35fr minmax(260px, .9fr);
	gap: clamp(1.5rem, 4vw, 3rem);
	align-items: center;
}

.pushpin-hero__words h1 { margin-top: 0; }
.pushpin-hero__words p  { margin-bottom: 1.6rem; }

@media (max-width: 860px) {
	.pushpin-hero--split { grid-template-columns: 1fr; }
}

.pushpin-next {
	background: #fff;
	color: var(--pushpin-ink);
	border-radius: var(--pushpin-radius);
	padding: 1.6rem;
	box-shadow: 0 12px 32px rgba(20, 12, 40, .22);
}

.pushpin-next__label {
	display: block;
	font-size: .72rem;
	font-weight: 700;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--pushpin-soft);
}

.pushpin-next__date {
	display: flex;
	align-items: baseline;
	gap: .4rem;
	margin: .6rem 0 .2rem;
	color: var(--pushpin-brand);
}

.pushpin-next__month { font-size: .95rem; font-weight: 700; letter-spacing: .08em; }
.pushpin-next__day   { font-size: 2.4rem; font-weight: 800; line-height: 1; }

.pushpin-next__title {
	font-size: 1.15rem;
	line-height: 1.25;
	margin: .3rem 0 .5rem;
	color: var(--pushpin-ink);
}

.pushpin-next__meta {
	margin: 0 0 1.2rem;
	color: var(--pushpin-soft);
	font-size: .9rem;
	line-height: 1.6;
}

.pushpin-next__meta span { display: block; }
.pushpin-next__price { font-weight: 700; color: var(--pushpin-ink); }

.pushpin-hero .pushpin-next__cta {
	display: block;
	text-align: center;
	background: var(--pushpin-brand);
	color: #fff;
	margin: 0;
}

.pushpin-hero .pushpin-next__cta:hover { background: #6b3fd4; color: #fff; }

/* -------------------------------------------------------------------------
 * Membership tiers.
 * ---------------------------------------------------------------------- */

.pushpin-lede { font-size: 1.1rem; color: var(--pushpin-soft); max-width: 46em; }

.pushpin-tiers {
	display: grid;
	gap: 1.5rem;
	grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
	align-items: start;
}

.pushpin-tier {
	position: relative;
	background: #fff;
	border: 1px solid var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	padding: 1.8rem 1.6rem;
	display: flex;
	flex-direction: column;
}

/* The middle option carries a flag rather than being made bigger. Scaling one
   card breaks the row's alignment and makes the other two look like mistakes. */
.pushpin-tier.is-featured {
	border-color: var(--pushpin-brand);
	box-shadow: 0 0 0 1px var(--pushpin-brand);
}

.pushpin-tier__flag {
	position: absolute;
	top: -.75rem;
	left: 1.6rem;
	background: var(--pushpin-brand);
	color: #fff;
	font-size: .7rem;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	padding: .35em .8em;
	border-radius: 999px;
}

.pushpin-tier h3 { margin: 0 0 .4rem; font-size: 1.15rem; }

.pushpin-tier__price {
	font-size: 2rem;
	font-weight: 800;
	line-height: 1;
	margin: 0 0 .5rem;
	color: var(--pushpin-ink);
}

.pushpin-tier__price span {
	font-size: .85rem;
	font-weight: 500;
	color: var(--pushpin-soft);
}

.pushpin-tier__who { color: var(--pushpin-soft); margin: 0 0 1rem; }

.pushpin-tier__gets {
	list-style: none;
	margin: 0 0 1.5rem;
	padding: 0;
	display: grid;
	gap: .5rem;
}

.pushpin-tier__gets li {
	position: relative;
	padding-left: 1.5rem;
	color: var(--pushpin-ink);
	font-size: .93rem;
}

.pushpin-tier__gets li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .45em;
	width: .5rem;
	height: .28rem;
	border-left: 2px solid var(--pushpin-brand);
	border-bottom: 2px solid var(--pushpin-brand);
	transform: rotate(-45deg);
}

.pushpin-tier .pushpin-btn { margin: auto 0 0; text-align: center; }

.pushpin-tiers__note {
	margin-top: 1.5rem;
	color: var(--pushpin-soft);
}

/* -------------------------------------------------------------------------
 * Newsletter sign-up.
 * ---------------------------------------------------------------------- */

/*
 * THE SIGN-UP STRIP, WHICH NOBODY COULD SEE.
 *
 * It was a near-white panel on a near-white page with a one-line heading, and
 * it read as another paragraph — easy to scroll straight past, which is what
 * Mike did. Growing the mailing list is one of the few things a chapter website
 * is actually for, so this is the one block on the page allowed to raise its
 * voice.
 *
 * Brand-coloured rather than merely bigger: on a page of white cards, the thing
 * that stops a scroll is a change of colour, not a change of font size. The
 * left border is a second, quieter signal for anyone who has the page in high
 * contrast or with backgrounds off.
 */
.pushpin-newsletter {
	display: grid;
	grid-template-columns: 1fr minmax(280px, .8fr);
	gap: clamp(1.2rem, 4vw, 2.5rem);
	align-items: center;
	background: linear-gradient(135deg, #efeafc 0%, #f7f4fe 100%);
	border: 1px solid #d9cffa;
	border-left: 4px solid var(--pushpin-brand);
	border-radius: var(--pushpin-radius);
	padding: clamp(1.6rem, 4vw, 2.6rem);
	margin: clamp(2rem, 5vw, 3rem) 0;
}

/*
 * An envelope in the corner. Decorative and aria-hidden — it is there to catch
 * a scrolling eye, and it carries no information the heading does not.
 */
.pushpin-newsletter__words h2::before {
	content: "";
	display: inline-block;
	width: 22px;
	height: 22px;
	margin-right: .5rem;
	vertical-align: -3px;
	background: var(--pushpin-brand);
	-webkit-mask: var(--pushpin-mail-icon) center / contain no-repeat;
	mask: var(--pushpin-mail-icon) center / contain no-repeat;
}

:root {
	--pushpin-mail-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='6' width='18' height='12' rx='2'/%3E%3Cpath d='m3.5 7 8.5 6.5L20.5 7'/%3E%3C/svg%3E");
}

@media (max-width: 780px) {
	.pushpin-newsletter { grid-template-columns: 1fr; }
}

.pushpin-newsletter__words h2 {
	margin: 0 0 .4rem;
	font-size: clamp(1.4rem, 3vw, 1.75rem);
	line-height: 1.25;
	color: var(--pushpin-ink);
}

/* Darker than the usual muted grey. This paragraph is doing persuasion, and
   the old colour on the old background was 3.9:1 — under the line. */
.pushpin-newsletter__words p {
	margin: 0;
	color: #4a3f66;
	font-size: 1.02rem;
	line-height: 1.55;
}

.pushpin-newsletter__form {
	display: flex;
	gap: .6rem;
	flex-wrap: wrap;
}

.pushpin-newsletter__form input[type="email"] {
	flex: 1 1 200px;
	padding: .8em 1em;
	border: 1px solid var(--pushpin-line);
	border-radius: 6px;
	background: #fff;
	font-size: 1rem;
}

.pushpin-newsletter__form .pushpin-btn { margin: 0; border: 0; cursor: pointer; }

.pushpin-newsletter__said {
	background: #fff;
	border: 1px solid var(--pushpin-brand);
	border-radius: var(--pushpin-radius);
	padding: 1.2rem 1.5rem;
	margin-bottom: 1.5rem;
	color: var(--pushpin-ink);
}

/* =========================================================================
 * 1.3.0 — SPONSORSHIPS, THE BASKET, CHECKOUT, AND THE SINGLE EVENT PAGE.
 *
 * WHY ALL OF THIS ARRIVED AT ONCE. The plugin grew a basket, and a basket is
 * the first thing on a chapter site that a company's finance department will
 * look at. Everything up to now could get away with looking plain; a page that
 * asks somebody to commit five thousand pounds of somebody else's money cannot.
 *
 * Same rules as everything above it: no framework, no imports, no web fonts,
 * every accent taken from --pushpin-brand so a chapter that changes its colour
 * in Chapter settings changes this too, and nothing here assumes a screen
 * width. Kadence still owns type, page width and the palette outside our own
 * blocks.
 * ====================================================================== */

/* -------------------------------------------------------------------------
 * Focus.
 *
 * Stated once, up front, for everything this file adds. Kadence's own focus
 * ring is tuned for Kadence's own controls and does not reliably reach a link
 * that we have turned into a card or a button we have recoloured, and a
 * keyboard user who loses the caret on a checkout form has no way to find it
 * again. :focus-visible rather than :focus so a mouse user clicking a card is
 * not left with a ring around it afterwards.
 * ---------------------------------------------------------------------- */

.pushpin-sponsorships a:focus-visible,
.pushpin-sponsorships button:focus-visible,
.pushpin-sponsorships input:focus-visible,
.pushpin-cross__card:focus-visible,
.pushpin-basket a:focus-visible,
.pushpin-basket button:focus-visible,
.pushpin-basket input:focus-visible,
.pushpin-basket select:focus-visible,
.pushpin-basket textarea:focus-visible,
.pushpin-basket-link:focus-visible,
.pushpin-add button:focus-visible,
.pushpin-register a:focus-visible,
.pushpin-register button:focus-visible,
.pushpin-register input:focus-visible,
.pushpin-register select:focus-visible,
.pushpin-register textarea:focus-visible,
.pushpin-register-done a:focus-visible,
.pushpin-edition-notice a:focus-visible,
.pushpin-edition-previous a:focus-visible {
	outline: 3px solid var(--pushpin-brand);
	outline-offset: 2px;
	border-radius: 3px;
}

/*
 * The same ring, in white, wherever it would otherwise be brand-on-brand and
 * therefore invisible. This is the same answer the hero already gives for text:
 * on the brand colour, go white and say so explicitly rather than inheriting.
 */
.pushpin-sponsor-tier--headline .pushpin-btn:focus-visible,
.pushpin-checkout__go .pushpin-btn:focus-visible,
.pushpin-add .pushpin-btn:focus-visible,
.pushpin-basket-link:focus-visible .pushpin-basket-link__n {
	outline-color: #fff;
	box-shadow: 0 0 0 6px var(--pushpin-brand);
}

/* -------------------------------------------------------------------------
 * Sponsorship tiers.
 *
 * Written fresh rather than sharing selectors with .pushpin-tier above. They
 * look like cousins on purpose — same card, same radius, same tick list — but
 * membership tiers and event sponsorships change independently, and the day a
 * chapter wants its sponsorship ladder to look different from its membership
 * page, a shared class would mean choosing between them.
 * ---------------------------------------------------------------------- */

.pushpin-sponsorships {
	margin-block: clamp(28px, 5vw, 48px);
}

.pushpin-sponsorships__title {
	font-size: var(--global-kb-font-size-lg, 1.6rem);
	margin: 0 0 .3rem;
}

.pushpin-sponsorships__lede {
	color: var(--pushpin-soft);
	margin: 0 0 1.5rem;
	max-width: 46em;
}

/*
 * auto-fit rather than auto-fill, so three tiers fill the row instead of
 * huddling at the left with a gap where a fourth would go. A chapter with two
 * levels is the common case and looks deliberate this way.
 */
.pushpin-sponsorships__grid {
	display: grid;
	gap: 1.5rem;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	align-items: stretch;
}

.pushpin-sponsor-tier {
	display: flex;
	flex-direction: column;
	background: #fff;
	border: 1px solid var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	padding: 1.7rem 1.5rem;
}

/*
 * The ladder. The top level carries the weight, because a sponsorship list is
 * read from the top and the whole point of the top one is that it is the top
 * one — a row of identical cards makes the expensive option look like a
 * mistake rather than an aspiration.
 *
 * Weight is a brand-coloured cap, a ring and a lift, NOT a larger card:
 * scaling one card in a grid breaks the row's baseline and drags the others
 * out of line, which is the same reason .pushpin-tier flags its featured
 * option instead of growing it.
 *
 * KNOWN COMPROMISE: this is positional. The markup gives us no "this is the
 * headline tier" class, so we lean on source order, which is the order the
 * chapter typed the tiers into the event editor — top-down, expensive first,
 * which is how everybody writes them. If the plugin ever prints a modifier for
 * it, move this rule onto that instead and delete the :first-child.
 */
.pushpin-sponsor-tier:first-child:not(.is-gone) {
	position: relative;
	border-color: var(--pushpin-brand);
	box-shadow: 0 0 0 1px var(--pushpin-brand), 0 14px 30px rgba(20, 12, 40, .10);
}

.pushpin-sponsor-tier:first-child:not(.is-gone)::before {
	content: "";
	position: absolute;
	inset: 0 0 auto 0;
	height: 5px;
	background: var(--pushpin-brand);
	border-radius: var(--pushpin-radius) var(--pushpin-radius) 0 0;
}

.pushpin-sponsor-tier__name {
	margin: 0 0 .3rem;
	font-size: 1.1rem;
	line-height: 1.25;
}

.pushpin-sponsor-tier__price {
	margin: 0 0 .6rem;
	font-size: 1.9rem;
	font-weight: 800;
	line-height: 1;
	color: var(--pushpin-ink);
	/* Tabular figures so a column of prices lines up at the decimal point
	   instead of drifting, which is what makes a price list read as a ladder. */
	font-variant-numeric: tabular-nums;
}

.pushpin-sponsor-tier__seats {
	margin: 0 0 .8rem;
	color: var(--pushpin-soft);
	font-size: .9rem;
}

.pushpin-sponsor-tier__perks {
	list-style: none;
	margin: 0 0 1.3rem;
	padding: 0;
	display: grid;
	gap: .45rem;
}

.pushpin-sponsor-tier__perks li {
	position: relative;
	padding-left: 1.5rem;
	font-size: .93rem;
	color: var(--pushpin-ink);
	/* The list-style on the <ul> alone was not enough: the theme sets its own
	   on `.entry-content li`, so every perk rendered with a bullet AND the drawn
	   tick beside it. Cleared on the item, and the marker cleared with it. */
	list-style: none;
}

.pushpin-sponsor-tier__perks li::marker {
	content: "";
}

/* The same drawn tick as the membership tiers, rather than a character from a
   font we do not control the rendering of. */
.pushpin-sponsor-tier__perks li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .45em;
	width: .5rem;
	height: .28rem;
	border-left: 2px solid var(--pushpin-brand);
	border-bottom: 2px solid var(--pushpin-brand);
	transform: rotate(-45deg);
}

/* Warm red and not the brand colour, for the reason .pushpin-register-left
   already gives: scarcity has to out-shout the page it is printed on. */
.pushpin-sponsor-tier__left {
	margin: 0 0 .8rem;
	font-size: .85rem;
	font-weight: 600;
	color: #9a3412;
}

/* The button sits on the floor of the card whatever the perk list did, so a
   row of tiers has one line of buttons rather than a staircase of them. */
.pushpin-sponsor-tier .pushpin-add {
	margin-top: auto;
}

/*
 * A taken tier stays on the page.
 *
 * Removing it would be tidier and would also lose the argument: seeing that
 * Gold has gone is what makes Silver feel like a decision rather than a price.
 * So it reads as spent — flat, dimmed, no shadow — and never as decoration.
 *
 * Colour is not carrying this on its own. The border goes dashed and the card
 * says "Taken" in words, so it survives greyscale, a projector and colour
 * blindness alike.
 */
.pushpin-sponsor-tier.is-gone {
	background: var(--pushpin-paper);
	border-style: dashed;
	box-shadow: none;
}

/* Dimmed enough to recede, not so far that the perks stop being legible —
   this is still the sentence that explains what the next level down is worth. */
.pushpin-sponsor-tier.is-gone .pushpin-sponsor-tier__name,
.pushpin-sponsor-tier.is-gone .pushpin-sponsor-tier__price {
	color: var(--pushpin-soft);
}

.pushpin-sponsor-tier.is-gone .pushpin-sponsor-tier__price {
	text-decoration: line-through;
	text-decoration-thickness: 2px;
}

.pushpin-sponsor-tier.is-gone .pushpin-sponsor-tier__perks li::before {
	border-color: var(--pushpin-soft);
}

.pushpin-sponsor-tier__gone {
	margin: auto 0 0;
	align-self: flex-start;
	border: 1px solid var(--pushpin-line);
	border-radius: 999px;
	padding: .3em .9em;
	background: #fff;
	color: var(--pushpin-soft);
	font-size: .78rem;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
}

/* -------------------------------------------------------------------------
 * The add-to-basket form.
 *
 * A <form> around a single button, which browsers give a default margin and
 * which every card in this file then has to work around. Zeroed here rather
 * than in each card, and given `display: grid` so the button's own margins
 * cannot collapse through the form and push the card's floor out of line with
 * its neighbours.
 * ---------------------------------------------------------------------- */

.pushpin-add {
	display: grid;
	margin: 0;
}

.pushpin-add .pushpin-btn {
	margin: 0;
	border: 0;
	cursor: pointer;
	text-align: center;
	font: inherit;
	font-weight: 600;
}

/* -------------------------------------------------------------------------
 * "Often taken together".
 *
 * Deliberately the quietest block on the page. It appears directly under a
 * sponsorship ladder and directly under a basket, and in both places it is an
 * aside — a strip of small linked cards, no buttons, nothing that competes
 * with the thing the visitor came to do.
 * ---------------------------------------------------------------------- */

.pushpin-cross {
	margin-block: clamp(24px, 4vw, 40px);
}

.pushpin-cross__title {
	font-size: 1.05rem;
	margin: 0 0 .8rem;
	color: var(--pushpin-soft);
	font-weight: 700;
	letter-spacing: .02em;
}

.pushpin-cross__grid {
	display: grid;
	gap: .8rem;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

/* The whole card is the anchor, so the target is the card rather than four
   words inside it — which on a phone is the difference between tapping it and
   tapping near it. */
.pushpin-cross__card {
	display: grid;
	gap: .2rem;
	align-content: start;
	padding: .9rem 1rem;
	background: var(--pushpin-paper);
	border: 1px solid var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	text-decoration: none;
	color: var(--pushpin-ink);
	transition: border-color .15s ease, transform .15s ease;
}

.pushpin-cross__card:hover {
	border-color: var(--pushpin-brand);
	transform: translateY(-1px);
	color: var(--pushpin-ink);
}

.pushpin-cross__when {
	font-size: .72rem;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--pushpin-brand);
}

.pushpin-cross__name {
	font-weight: 600;
	line-height: 1.3;
}

.pushpin-cross__from {
	font-size: .85rem;
	color: var(--pushpin-soft);
	font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------------------------
 * The basket.
 * ---------------------------------------------------------------------- */

.pushpin-basket {
	margin-block: clamp(24px, 4vw, 40px);
}

/*
 * Anything that went wrong, in one shape.
 *
 * Matched to .pushpin-register-error rather than invented, because the two
 * appear on different pages of the same journey and a person who has just been
 * refused once should recognise the second refusal as the same kind of thing.
 */
.pushpin-basket__error {
	border-left: 4px solid #b91c1c;
	background: rgba(185, 28, 28, .06);
	padding: 12px 16px;
	margin: 0 0 18px;
}

.pushpin-basket__empty {
	background: var(--pushpin-paper);
	border: 1px dashed var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	padding: 2rem;
	text-align: center;
	color: var(--pushpin-soft);
}

/*
 * The lines.
 *
 * MOBILE FIRST, AND THE TABLE SCROLLS ITSELF. There is no wrapper div around
 * this table in the markup, so the table element is made its own scroll
 * container: as a block box it sizes to its content and clips the overflow,
 * while the rows inside still form one anonymous table and therefore keep
 * their columns aligned. The page never scrolls sideways; the prices do.
 *
 * Above 40em there is room for all four columns, so it goes back to being an
 * ordinary full-width table.
 */
.pushpin-basket__lines {
	display: block;
	overflow-x: auto;
	max-width: 100%;
	margin: 0 0 1.5rem;
	border-collapse: collapse;
	/* Momentum scrolling, and a hint that there is more to the right. */
	overscroll-behavior-x: contain;
}

@media (min-width: 40em) {
	.pushpin-basket__lines {
		display: table;
		width: 100%;
	}
}

.pushpin-basket__lines th,
.pushpin-basket__lines td {
	padding: .8rem .7rem;
	text-align: left;
	vertical-align: top;
	border-bottom: 1px solid var(--pushpin-line);
}

.pushpin-basket__lines thead th {
	font-size: .72rem;
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--pushpin-soft);
	border-bottom-width: 2px;
	white-space: nowrap;
}

/*
 * Money and counts, right-aligned with tabular figures.
 *
 * Proportional digits in a column of prices put the pounds in a different
 * place on every row, which is the single fastest way to make a total look
 * like it might be wrong.
 */
.pushpin-basket__lines .num {
	text-align: right;
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

.pushpin-basket__tag {
	display: inline-block;
	margin-left: .4rem;
	padding: .15em .6em;
	border-radius: 999px;
	background: var(--pushpin-brand);
	color: #fff;
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	vertical-align: .1em;
}

.pushpin-basket__for {
	display: block;
	margin-top: .15rem;
	font-size: .9rem;
	color: var(--pushpin-soft);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.pushpin-basket__for:hover {
	color: var(--pushpin-brand);
}

.pushpin-basket__seats {
	display: block;
	font-size: .85rem;
	color: var(--pushpin-soft);
}

/*
 * A line that cannot go through.
 *
 * The row is tinted, but the tint is the least of it: the row carries a solid
 * left edge, and the problem is spelled out in words with a warning mark in
 * front of it. Somebody printing the basket in black and white, or reading it
 * with a colour vision deficiency, still gets told which line is the problem —
 * which matters here more than most places, because the checkout button is
 * disabled until they fix it and nothing else on the page explains why.
 */
.pushpin-basket__lines tr.has-problem td {
	background: rgba(185, 28, 28, .05);
}

.pushpin-basket__lines tr.has-problem td:first-child {
	box-shadow: inset 4px 0 0 0 #b91c1c;
}

.pushpin-basket__problem {
	display: block;
	margin-top: .3rem;
	font-size: .87rem;
	font-weight: 600;
	color: #9a1c1c;
}

.pushpin-basket__problem::before {
	content: "\26A0\FE0E ";
	font-weight: 700;
}

.pushpin-basket__lines tfoot th,
.pushpin-basket__lines tfoot td {
	border-bottom: 0;
	border-top: 2px solid var(--pushpin-line);
	padding-top: 1rem;
}

.pushpin-basket__total {
	font-size: 1.2rem;
	font-weight: 800;
	color: var(--pushpin-ink);
}

/*
 * Remove is a link, not a button.
 *
 * It is a destructive action sitting in the same row as a price, and giving it
 * the brand button would make it the loudest thing in the basket. Underlined
 * rather than colour-only so it is still obviously clickable when the colour
 * is not available.
 */
.pushpin-basket__remove {
	background: none;
	border: 0;
	padding: 0;
	font: inherit;
	font-size: .87rem;
	color: var(--pushpin-soft);
	text-decoration: underline;
	text-underline-offset: 2px;
	cursor: pointer;
}

.pushpin-basket__remove:hover {
	color: #9a1c1c;
}

/* -------------------------------------------------------------------------
 * Checkout.
 *
 * Held to a single readable column at the same 34em the registration form
 * uses. A form field the full width of a desktop content area is harder to
 * fill in, not easier — the eye has to travel back across the page to find the
 * start of the next label.
 * ---------------------------------------------------------------------- */

.pushpin-checkout {
	max-width: 34em;
	margin-top: clamp(24px, 4vw, 40px);
	padding-top: clamp(20px, 3vw, 28px);
	border-top: 1px solid var(--pushpin-line);
}

.pushpin-checkout__title {
	font-size: var(--global-kb-font-size-lg, 1.35rem);
	margin: 0 0 .3rem;
}

.pushpin-checkout__lede {
	margin: 0 0 1.5rem;
	color: var(--pushpin-soft);
}

.pushpin-checkout .pushpin-field {
	display: flex;
	flex-direction: column;
	gap: 4px;
	margin: 0 0 14px;
}

.pushpin-checkout .pushpin-field > label,
.pushpin-checkout legend {
	font-weight: 600;
	font-size: 14px;
}

.pushpin-checkout input[type="text"],
.pushpin-checkout input[type="email"],
.pushpin-checkout input[type="tel"],
.pushpin-checkout textarea {
	width: 100%;
	padding: .65em .8em;
	border: 1px solid var(--pushpin-line);
	border-radius: 6px;
	background: #fff;
	font: inherit;
}

.pushpin-checkout textarea {
	resize: vertical;
}

.pushpin-help {
	font-size: 13px;
	color: var(--pushpin-soft);
}

/* "optional" is a qualifier on the label, so it must not read as part of it. */
.pushpin-optional {
	font-weight: 400;
	color: var(--pushpin-soft);
}

/*
 * The payment methods.
 *
 * A fieldset with its default border removed and replaced by our own, because
 * the browser's is drawn through the legend and looks like a mistake next to
 * the rounded boxes above it.
 */
.pushpin-methods {
	border: 1px solid var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	padding: .9rem 1.1rem 1rem;
	margin: 0 0 18px;
}

.pushpin-methods legend {
	padding: 0 .4rem;
}

/* Each option is a whole row, so the label is the target rather than the
   eight-pixel circle in front of it. */
.pushpin-method {
	display: flex;
	align-items: center;
	gap: .6rem;
	padding: .45rem 0;
	cursor: pointer;
}

.pushpin-method input[type="radio"] {
	flex: none;
	margin: 0;
	accent-color: var(--pushpin-brand);
}

.pushpin-method:has(input:checked) {
	font-weight: 600;
}

.pushpin-checkout__go {
	margin: 1.5rem 0 0;
}

.pushpin-checkout__go .pushpin-btn {
	margin: 0;
	border: 0;
	cursor: pointer;
	font: inherit;
	font-weight: 600;
	color: #fff;
}

/*
 * A checkout button that cannot be pressed still has to look pressable enough
 * to be found — it is what the visitor is looking for, and the reason it is
 * off is a sentence directly above it.
 */
.pushpin-checkout__go .pushpin-btn:disabled {
	opacity: .45;
	cursor: not-allowed;
}

/* -------------------------------------------------------------------------
 * The honeypot.
 *
 * NOT display:none, and not `.screen-reader-text` either. Both are patterns a
 * bot can recognise and skip, and the whole value of this field is that a bot
 * fills it in. Pushed off the side of the viewport instead: no human sees it,
 * nothing reflows around it, and it looks like an ordinary field to anything
 * reading the markup rather than rendering it.
 *
 * The markup already carries aria-hidden and tabindex="-1", so a screen reader
 * and the tab order both skip it without any help from here.
 *
 * Scoped to nothing in particular on purpose: this must apply to the copy in
 * the checkout form as well as the ones inside .pushpin-register, and the
 * plugin's own inline rule only covers the latter.
 * ---------------------------------------------------------------------- */

.pushpin-hp {
	position: absolute !important;
	left: -9999px !important;
	top: auto;
	width: 1px;
	height: 1px;
	overflow: hidden;
	margin: 0;
}

/* -------------------------------------------------------------------------
 * The basket link.
 *
 * Small by design. It is a header or menu item, not a call to action, and it
 * only exists at all when there is something in the basket.
 * ---------------------------------------------------------------------- */

.pushpin-basket-link {
	display: inline-flex;
	align-items: center;
	gap: .45rem;
	font-size: .9rem;
	font-weight: 600;
	color: inherit;
	text-decoration: none;
}

.pushpin-basket-link:hover {
	color: var(--pushpin-brand);
}

/* min-width rather than a fixed width, so a chapter with eleven things in the
   basket gets a slightly wider pill instead of a clipped number. */
.pushpin-basket-link__n {
	display: inline-grid;
	place-items: center;
	min-width: 1.5em;
	height: 1.5em;
	padding: 0 .35em;
	border-radius: 999px;
	background: var(--pushpin-brand);
	color: #fff;
	font-size: .75rem;
	font-weight: 700;
	line-height: 1;
	font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------------------------
 * Edition notices.
 *
 * The "there is a newer one of these" banner. Quiet, because it appears above
 * an event somebody has deliberately opened and its job is to offer, not to
 * interrupt.
 * ---------------------------------------------------------------------- */

.pushpin-edition-notice {
	background: var(--pushpin-paper);
	border: 1px solid var(--pushpin-line);
	border-left: 4px solid var(--pushpin-brand);
	border-radius: var(--pushpin-radius);
	padding: .9rem 1.1rem;
	margin: 0 0 1.5rem;
	font-size: .95rem;
}

.pushpin-edition-notice a,
.pushpin-edition-previous a {
	color: var(--pushpin-brand);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.pushpin-edition-previous {
	margin-top: 2rem;
	font-size: .95rem;
	color: var(--pushpin-soft);
}

/* -------------------------------------------------------------------------
 * The registration panel.
 *
 * WHY EVERY SELECTOR BELOW STARTS WITH `body`. The plugin already prints a
 * small stylesheet for this panel, inline, in wp_footer — which is to say
 * after this file in the document, so at equal specificity the plugin wins and
 * anything written here would silently do nothing. One element in front of the
 * class buys a point of specificity and settles it.
 *
 * What follows is polish on top of what the plugin does, not a replacement for
 * it: the plugin's rules still lay the panel out if this theme is swapped, and
 * a chapter that never touches the theme still gets a working form.
 * ---------------------------------------------------------------------- */

body .pushpin-register {
	max-width: 34em;
	padding: clamp(1.2rem, 4vw, 1.8rem);
	background: #fff;
	border: 1px solid var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	box-shadow: 0 10px 30px rgba(20, 12, 40, .06);
}

body .pushpin-register-heading {
	margin-top: 0;
}

/* The form is already the width of the panel; a second max-width inside it
   would leave a strip of empty card down the right-hand side. */
body .pushpin-register .pushpin-register-form {
	max-width: none;
}

body .pushpin-register .pushpin-field input[type="text"],
body .pushpin-register .pushpin-field input[type="email"],
body .pushpin-register .pushpin-field input[type="tel"],
body .pushpin-register .pushpin-field select,
body .pushpin-register .pushpin-field textarea {
	padding: .65em .8em;
	border: 1px solid var(--pushpin-line);
	border-radius: 6px;
	background: #fff;
	font: inherit;
}

body .pushpin-register .pushpin-field textarea {
	resize: vertical;
}

/* A checkbox and its sentence, on one line, with the box not stretched to the
   width of the column by the flex column the plugin puts them in. */
body .pushpin-register .pushpin-field .pushpin-inline {
	display: flex;
	align-items: center;
	gap: .5rem;
	font-weight: 500;
}

body .pushpin-register .pushpin-inline input[type="checkbox"] {
	flex: none;
	width: auto;
	margin: 0;
	accent-color: var(--pushpin-brand);
}

/*
 * The ticket list.
 *
 * The row is the target, and the chosen one is marked by a brand-coloured edge
 * and a tinted background rather than colour alone — the radio itself is still
 * the primary signal, and it is a shape, not a hue.
 */
body .pushpin-register .pushpin-register-ticket {
	gap: .7rem;
	padding: .7rem .8rem;
	border: 1px solid transparent;
	border-radius: 8px;
	cursor: pointer;
}

body .pushpin-register .pushpin-register-ticket:hover {
	background: var(--pushpin-paper);
}

body .pushpin-register .pushpin-register-ticket input[type="radio"] {
	accent-color: var(--pushpin-brand);
}

body .pushpin-register .pushpin-register-ticket:has(input:checked) {
	background: var(--pushpin-paper);
	border-color: var(--pushpin-brand);
	box-shadow: inset 3px 0 0 0 var(--pushpin-brand);
}

body .pushpin-register .pushpin-register-ticket-price {
	font-variant-numeric: tabular-nums;
	font-weight: 600;
}

body .pushpin-register .pushpin-register-tickets,
body .pushpin-register .pushpin-guests {
	border-color: var(--pushpin-line);
}

body .pushpin-register .pushpin-guest-row {
	border-color: var(--pushpin-line);
	background: var(--pushpin-paper);
}

/* The guest count is a single short number in a column of full-width boxes,
   and stretching it to match them makes it look like it wants a sentence. */
body .pushpin-register .pushpin-guest-count-field select {
	width: auto;
	min-width: 8em;
}

body .pushpin-register .pushpin-register-submit {
	margin-top: 1.5rem;
	margin-bottom: 0;
}

/*
 * The receipt.
 *
 * Rendered OUTSIDE .pushpin-register — the panel returns the receipt before it
 * opens its wrapper — so it has to be styled on its own and cannot inherit any
 * of the above. Given the brand edge because it is the one screen in this
 * journey that is unambiguously good news.
 */
body .pushpin-register-done {
	max-width: 34em;
	border: 1px solid var(--pushpin-line);
	border-top: 4px solid var(--pushpin-brand);
	border-radius: var(--pushpin-radius);
	padding: clamp(1.2rem, 4vw, 1.8rem);
	background: #fff;
}

body .pushpin-register-done h3 {
	margin-top: 0;
}

body .pushpin-register-done .pushpin-button {
	display: inline-block;
	background: var(--pushpin-brand);
	color: #fff;
	border: 0;
	border-radius: 8px;
	padding: 11px 22px;
	font-weight: 600;
	text-decoration: none;
}

body .pushpin-register-done .pushpin-register-actions {
	display: flex;
	align-items: center;
	gap: .8rem;
	flex-wrap: wrap;
}

/* The closed notices and the countdown, matched to the panel so the page looks
   the same whether registration is open or not. */
body .pushpin-register .pushpin-register-closed,
body .pushpin-register .pushpin-register-soon {
	border: 0;
	padding: 0;
}

body .pushpin-register .pushpin-register-soon h3 {
	margin-top: 0;
}

body .pushpin-register .pushpin-countdown strong {
	color: var(--pushpin-brand);
	font-variant-numeric: tabular-nums;
}

body .pushpin-register .pushpin-notify-form input[type="email"] {
	padding: .65em .8em;
	border: 1px solid var(--pushpin-line);
	border-radius: 6px;
	font: inherit;
}

/* -------------------------------------------------------------------------
 * The Events Calendar's single event page.
 *
 * WHY THIS IS RESTRAINED. The default TEC single template is not ours and its
 * markup changes between releases. Everything below is additive — spacing,
 * type scale, a border — and nothing repositions or hides one of their
 * elements, so the worst a TEC update can do is make one of these rules stop
 * matching. That is a page that looks slightly plainer for a week, not a page
 * that breaks.
 *
 * All of it is scoped under .tribe-events-single so it cannot touch the month
 * view, the list view, or anything else on the site.
 * ---------------------------------------------------------------------- */

.tribe-events-single .tribe-events-single-event-title {
	font-size: clamp(1.7rem, 4.5vw, 2.4rem);
	line-height: 1.15;
	margin: 0 0 .4rem;
}

.tribe-events-single .tribe-events-schedule {
	color: var(--pushpin-soft);
	margin: 0 0 1.5rem;
}

/*
 * The details block. TEC gives it a two-column definition list that on a phone
 * ends up as a column of orphaned labels, so it is allowed to become one
 * column below 48em and only then splits.
 */
.tribe-events-single .tribe-events-event-meta {
	background: var(--pushpin-paper);
	border: 1px solid var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	padding: clamp(1rem, 3vw, 1.5rem);
	margin: 2rem 0;
	font-size: .95rem;
}

.tribe-events-single .tribe-events-meta-group {
	margin-bottom: 1rem;
}

.tribe-events-single .tribe-events-meta-group:last-child {
	margin-bottom: 0;
}

.tribe-events-single .tribe-events-meta-group h2,
.tribe-events-single .tribe-events-meta-group h3 {
	font-size: .75rem;
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--pushpin-soft);
	margin: 0 0 .5rem;
}

.tribe-events-single .tribe-events-event-meta dt {
	font-weight: 600;
}

.tribe-events-single .tribe-events-event-meta dd {
	margin: 0 0 .5rem;
}

.tribe-events-single .tribe-events-event-meta a {
	color: var(--pushpin-brand);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* The venue block, given the same card as the details rather than the plain
   run of paragraphs TEC leaves it as. */
.tribe-events-single .tribe-events-venue,
.tribe-events-single .tribe-events-single-section-title + address {
	font-style: normal;
	line-height: 1.6;
}

/*
 * "Add to calendar".
 *
 * Toned down rather than restyled. It is TEC's control and points at the
 * public event, while ours on the receipt points at the person's own booking —
 * the two must not look like the same button, and the public one is the less
 * important of them here.
 */
.tribe-events-single .tribe-events-cal-links a,
.tribe-events-single .tribe-events-c-subscribe-dropdown__button {
	border: 1px solid var(--pushpin-line);
	border-radius: 6px;
	background: #fff;
	color: var(--pushpin-ink);
	font-weight: 600;
	text-decoration: none;
}

.tribe-events-single .tribe-events-cal-links a:hover,
.tribe-events-single .tribe-events-c-subscribe-dropdown__button:hover {
	border-color: var(--pushpin-brand);
	color: var(--pushpin-brand);
}

.tribe-events-single a:focus-visible,
.tribe-events-single button:focus-visible {
	outline: 3px solid var(--pushpin-brand);
	outline-offset: 2px;
}

/* TEC's own navigation between events sits directly above our registration
   panel and needs a gap, or the two read as one block. */
.tribe-events-single .tribe-events-sub-nav {
	margin-top: 2.5rem;
}

/* -------------------------------------------------------------------------
 * Print, part two.
 *
 * An event page on paper is a notice on a board or a sheet in a board packet.
 * Empty form boxes, a basket link to a page that cannot be visited and a
 * cross-sell to two other events are all noise on paper — worse than noise,
 * because a printed form implies somebody could fill it in and post it.
 *
 * The sponsorship ladder stays: a printed list of levels and prices is exactly
 * what gets handed to a prospective sponsor. Its buttons go.
 * ---------------------------------------------------------------------- */

@media print {
	.pushpin-register,
	.pushpin-checkout,
	.pushpin-basket-link,
	.pushpin-cross,
	.pushpin-add,
	.pushpin-basket__remove {
		display: none !important;
	}

	.pushpin-sponsorships__grid {
		display: block;
	}

	.pushpin-sponsor-tier {
		break-inside: avoid;
		box-shadow: none;
		border: 1px solid #999;
		margin-bottom: 12pt;
	}

	.pushpin-sponsor-tier:first-child:not(.is-gone)::before {
		display: none;
	}

	.pushpin-basket__lines {
		display: table;
		width: 100%;
	}
}

/* -------------------------------------------------------------------------
   1.3.2 — The Events Calendar's own back link

   TEC prints "« All Events" above every single event, pointing at its default
   calendar view. The site's own navigation already has an Events item going to
   the same place, so it is a second route to somewhere the visitor can already
   get to — and it is styled like nothing else on the page, which makes it read
   as a piece of the software showing through rather than a piece of the
   chapter's website.

   Hidden rather than removed in PHP: reaching into another plugin's markup to
   delete a control is the kind of thing that breaks on their next release,
   whereas a hidden element that stops existing one day simply stops matching.
   ---------------------------------------------------------------------- */

.tribe-events-back,
.tribe-events-single .tribe-events-back,
.tribe-events-header__back,
.tribe-events-c-subscribe-dropdown__placeholder + .tribe-events-back {
	display: none !important;
}

/* ---- Sponsor wall ------------------------------------------------------

   The tiles are all one size and the logos inside them are not. That is the
   whole trick: eleven businesses send eleven differently-shaped files, and the
   wall has to make them look like a set without touching any of them.

   contain, never cover. Cropping a sponsor's logo is a phone call from
   somebody who paid four figures for it to be on this page.                */

.am-spon { margin: 2rem 0; }

.am-spon__tier {
	margin: 2rem 0 .9rem;
	font-size: .78rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .08em;
	color: var(--pushpin-soft);
}

.am-spon__grid {
	display: grid;
	gap: 1rem;
	grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}

.am-spon__tile {
	/* Flex, not grid, because a percentage max-height on a grid item did not
	   reliably resolve against the track: Northgate's 520x520 badge rendered
	   176px tall inside a 116px tile and was clipped top and bottom on the
	   live wall. Flex resolves it against a definite container height. */
	display: flex;
	align-items: center;
	justify-content: center;
	/* A fixed height is what lets a tall stacked logo and an eight-to-one
	   wordmark sit in the same row without either dictating the other. */
	height: 116px;
	padding: 16px 18px;
	border: 1px solid var(--pushpin-line);
	border-radius: var(--pushpin-radius);
	background: #fff;
	text-decoration: none;
	overflow: hidden;
	transition: border-color .15s ease, transform .15s ease;
}

a.am-spon__tile:hover,
a.am-spon__tile:focus-visible {
	border-color: var(--pushpin-brand);
	transform: translateY(-1px);
}

/* A logo that brought a dark background gets a tile to match, so its own
   edges disappear rather than reading as a black box somebody forgot to fix. */
.am-spon__tile--dark { border-color: rgba(255, 255, 255, .16); }

.am-spon__img {
	max-width: 100%;
	/* Belt and braces: the percentage is what should work, and the absolute
	   value is what guarantees it. 116px tile less 32px vertical padding is
	   84px of content box, and a sponsor's logo is never cropped. */
	max-height: 100%;
	max-height: min(100%, 84px);
	width: auto;
	height: auto;
	min-height: 0;
	object-fit: contain;
}

/* The sponsor who never sent artwork. Their name, set properly, rather than
   a hole in the wall. */
.am-spon__name {
	font-weight: 700;
	font-size: 1rem;
	line-height: 1.3;
	text-align: center;
	color: var(--pushpin-ink);
	text-wrap: balance;
}

.am-spon__tile--dark .am-spon__name { color: #fff; }

@media (max-width: 600px) {
	.am-spon__grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
	.am-spon__tile { height: 96px; padding: 12px; }
	.am-spon__img { max-height: min(100%, 72px); }
}

/* ---- Who has served ----------------------------------------------------
 *
 * A ROLL OF HONOUR, not a list of people.
 *
 * The reading order on a past-presidents page is year first, name second —
 * somebody scanning it is looking for a year, or looking for their own name
 * against one. So the term gets its own column rather than trailing after the
 * name, and the numbers are set with tabular figures so the column actually
 * lines up. Proportional digits put 2018 and 1996 at visibly different widths,
 * which is the difference between a plaque and a paragraph.
 *
 * Deliberately quieter than the current board above it. The board is who to
 * ask about something today; this is history, and history that shouts drowns
 * out the people still serving.
 * --------------------------------------------------------------------- */

.pushpin-history {
	list-style: none;
	margin: 1.25rem 0 0;
	padding: 0;
	border-top: 1px solid var(--pushpin-line);
}

.pushpin-history-row {
	display: grid;
	grid-template-columns: minmax(5.5rem, max-content) 1fr;
	gap: .15rem 1.5rem;
	align-items: baseline;
	padding: .75rem 0;
	border-bottom: 1px solid var(--pushpin-line);
}

.pushpin-history-term {
	font-variant-numeric: tabular-nums;
	font-weight: 600;
	font-size: .95rem;
	color: var(--pushpin-brand);
	/* "2018–2020" is one token and must never break across two lines. */
	white-space: nowrap;
}

.pushpin-history-name {
	display: block;
	font-weight: 700;
	color: var(--pushpin-ink);
	line-height: 1.35;
}

/* Only printed when the list is not already filtered to one position. */
.pushpin-history-role {
	display: block;
	color: var(--pushpin-brand);
	font-size: .85rem;
	font-weight: 600;
	line-height: 1.4;
}

.pushpin-history-company {
	display: block;
	color: var(--pushpin-soft);
	font-size: .85rem;
	line-height: 1.4;
}

/*
 * On a phone the two columns become two lines, with the years first and
 * smaller — a 5.5rem column on a 320px screen leaves the names squeezed into
 * a gutter, and a name is the thing people came to read.
 */
@media (max-width: 480px) {
	.pushpin-history-row {
		grid-template-columns: 1fr;
		gap: .1rem;
	}

	.pushpin-history-term {
		font-size: .8rem;
		letter-spacing: .02em;
	}
}

/* ---- The credit mark --------------------------------------------------
 * One line, quiet, under everything else. It is a mark, not a message.
 * --------------------------------------------------------------------- */

.pushpin-credit {
	margin: .75rem 0 0;
	font-size: .8rem;
	line-height: 1.5;
	opacity: .75;
}

.pushpin-credit a { text-decoration-thickness: 1px; text-underline-offset: 2px; }
