/*
Theme Name: Ama Odia Parivar
Theme URI: https://amaodiaparivar.org
Template: kadence
Author: Ama Odia Parivar Social & Charitable Society
Author URI: https://amaodiaparivar.org
Description: Child theme of Kadence for the Ama Odia Parivar society website. Holds brand tokens, the Yellow Pages directory styling, the festival calendar, the committee page and the archive and single layouts. All functionality lives in the AOP Core plugin so the directory survives a theme change.
Version: 1.0.0
Text Domain: aop-child
*/

/* ---------------------------------------------------------------------------
   Brand tokens
   Palette slots (--global-palette*) come from the Kadence customizer.
   These add what Kadence has no slot for: a tint, a radius scale and a
   shadow scale.
   --------------------------------------------------------------------------- */

:root {
	--aop-tint: #E6F5F1;
	--aop-gold: #C8912A;
	--aop-radius-sm: 6px;
	--aop-radius: 12px;
	--aop-radius-lg: 20px;
	--aop-shadow-sm: 0 2px 8px rgba(0, 0, 0, .07);
	--aop-shadow-md: 0 6px 24px rgba(0, 0, 0, .10);
	--aop-ease: .28s cubic-bezier(.4, 0, .2, 1);
}

/* ---------------------------------------------------------------------------
   Directory: filter bar
   --------------------------------------------------------------------------- */

.aop-directory {
	margin: 0 0 2rem;
}

.aop-filters {
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
	align-items: flex-end;
	padding: 20px;
	margin: 0 0 20px;
	background: var(--aop-tint);
	border-radius: var(--aop-radius);
}

.aop-filters__field {
	flex: 1 1 180px;
	margin: 0;
}

.aop-filters__field label {
	display: block;
	margin-bottom: 6px;
	font-size: .82rem;
	font-weight: 600;
	letter-spacing: .02em;
	text-transform: uppercase;
	color: var(--global-palette4, #2E3A44);
}

.aop-filters__field select,
.aop-filters__field input[type="search"] {
	width: 100%;
	min-height: 44px;
	padding: 8px 12px;
	background: #fff;
	border: 1px solid var(--global-palette6, #D9D5CC);
	border-radius: var(--aop-radius-sm);
}

/* The Open now and Verified toggles. They sit with the other filters but have
   no field label above them, so they line up with their inputs rather than
   their labels. Allowed to wrap: at narrow widths two toggles on one line
   would push the second off the edge. */
.aop-filters__check {
	flex: 0 0 auto;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 18px;
	min-height: 44px;
	margin: 0;
	align-self: flex-end;
}

.aop-filters__check label {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: .92rem;
	font-weight: 600;
	white-space: nowrap;
	cursor: pointer;
}

/* The browser default is 13px, which is a poor target on a phone. The label
   wraps the box so the whole 44px row is tappable either way, but a bigger box
   also makes the ticked state readable at arm's length. */
.aop-filters__check input[type="checkbox"] {
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	margin: 0;
}

.aop-filters__submit {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 0;
}

.aop-filters__reset {
	font-size: .9rem;
	text-decoration: underline;
}

.aop-directory__count {
	margin: 0 0 16px;
	font-size: .92rem;
	color: var(--global-palette5, #5A6672);
}

/* ---------------------------------------------------------------------------
   Mentors
   --------------------------------------------------------------------------- */

.aop-mentors {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: 18px;
	margin: 0 0 18px;
}

.aop-mentor {
	display: flex;
	gap: 14px;
	align-items: flex-start;
	padding: 16px;
	background: var(--aop-tint);
	border-radius: var(--aop-radius);
}

.aop-mentor__media {
	flex: 0 0 64px;
	width: 64px;
	height: 64px;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	background: #fff;
	border-radius: 50%;
}

.aop-mentor__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.aop-mentor__initials {
	font-size: 1.1rem;
	font-weight: 700;
	color: var(--global-palette1, #B7411F);
}

.aop-mentor__name {
	margin: 0;
	font-size: 1.02rem;
}

.aop-mentor__role {
	margin: 2px 0 0;
	font-size: .85rem;
	color: var(--global-palette5, #5A6672);
}

.aop-mentor__expertise {
	margin: 6px 0 0;
	font-size: .92rem;
}

/* ---------------------------------------------------------------------------
   Blood donor register
   --------------------------------------------------------------------------- */

.aop-donor__why {
	padding: 14px 16px;
	margin: 0 0 20px;
	background: var(--aop-tint);
	border-radius: var(--aop-radius);
}

.aop-donor .aop-form {
	max-width: 32rem;
}

/* ---------------------------------------------------------------------------
   RSVP
   --------------------------------------------------------------------------- */

.aop-rsvp__why {
	padding: 14px 16px;
	margin: 0 0 20px;
	background: var(--aop-tint);
	border-radius: var(--aop-radius);
}

.aop-rsvp .aop-form {
	max-width: 32rem;
}

/* ---------------------------------------------------------------------------
   Event actions: add to calendar, share
   --------------------------------------------------------------------------- */

.aop-eventacts {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 0 0 26px;
}

.aop-eventacts .aop-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 1 auto;
	min-height: 44px;
}

@media (max-width: 600px) {
	.aop-eventacts .aop-btn {
		flex: 1 1 100%;
	}
}

/* ---------------------------------------------------------------------------
   Notices: pinned flag and attachment tag
   --------------------------------------------------------------------------- */

.aop-notice__flag,
.aop-notice__tag {
	display: inline-block;
	margin-left: 8px;
	padding: 2px 8px;
	font-size: .72rem;
	font-weight: 700;
	letter-spacing: .03em;
	text-transform: uppercase;
	border-radius: 999px;
	vertical-align: middle;
	white-space: nowrap;
}

.aop-notice__flag {
	color: #fff;
	background: var(--global-palette1, #B7411F);
}

.aop-notice__tag {
	color: var(--global-palette4, #46545F);
	background: rgba(0, 0, 0, .07);
}

.aop-notice.is-pinned .aop-notice__title {
	font-weight: 700;
}

.aop-notice__pdf {
	margin: 24px 0 0;
}

.aop-notice__pdfmeta {
	font-weight: 400;
	opacity: .85;
}

/* ---------------------------------------------------------------------------
   Location map

   A button until somebody presses it. Sized close to the iframe that replaces
   it so the page does not jump when it loads.
   --------------------------------------------------------------------------- */

.aop-map {
	margin: 0 0 8px;
}

.aop-map__load {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 6px;
	width: 100%;
	/* Matches the iframe's min-height exactly. At 260 the page jumped 60px the
	   moment the map loaded, which is the shift this placeholder exists to
	   avoid. Measured, not guessed. */
	min-height: 320px;
	padding: 24px 16px;
	text-align: center;
	background: var(--aop-tint);
	border: 1px dashed rgba(0, 0, 0, .22);
	border-radius: var(--aop-radius);
	cursor: pointer;
}

.aop-map__load:hover,
.aop-map__load:focus-visible {
	border-color: var(--global-palette1, #B7411F);
	border-style: solid;
}

.aop-map__pin {
	font-size: 1.6rem;
	line-height: 1;
	color: var(--global-palette1, #B7411F);
}

.aop-map__label {
	font-size: 1rem;
	font-weight: 600;
	color: var(--global-palette3, #2E3A44);
}

.aop-map__note {
	font-size: .85rem;
	color: var(--global-palette5, #5A6672);
}

.aop-map iframe {
	display: block;
	width: 100%;
	min-height: 320px;
	border: 0;
	border-radius: var(--aop-radius);
}

/* ---------------------------------------------------------------------------
   Mobile filter sheet

   The filter bar measures 33% of an 800px screen at 900px wide, 51% at 600px
   and about 80% at 375px, so on a phone it is turned into a bottom sheet.

   Every rule below is gated on html:not(.no-js). Kadence strips the no-js class
   in the head before first paint, so a visitor with JavaScript never sees the
   inline form flash, and a visitor without it keeps the plain form. A sheet
   that cannot be opened would be worse than a tall filter bar.
   --------------------------------------------------------------------------- */

.aop-filterbar__toggle,
.aop-filterbar__head {
	display: none;
}

/* Belt and braces: on a wide screen the scrim must never cover the page, no
   matter what state the script was left in by a resize. */
.aop-filterbar__scrim {
	display: none;
}

@media (max-width: 767px) {
	html:not(.no-js) .aop-filterbar__toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		gap: 10px;
		width: 100%;
		min-height: 48px;
		margin: 0 0 20px;
		padding: 0 18px;
		font-size: 1rem;
		font-weight: 600;
		color: var(--global-palette3, #2E3A44);
		background: var(--aop-tint);
		border: 1px solid rgba(0, 0, 0, .12);
		border-radius: var(--aop-radius);
		cursor: pointer;
	}

	html:not(.no-js) .aop-filterbar__count {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-width: 24px;
		height: 24px;
		padding: 0 7px;
		font-size: .82rem;
		font-weight: 700;
		line-height: 1;
		color: #fff;
		background: var(--global-palette1, #B7411F);
		border-radius: 12px;
	}

	html:not(.no-js) .aop-filterbar.is-open .aop-filterbar__scrim {
		display: block;
		position: fixed;
		inset: 0;
		z-index: 998;
		background: rgba(0, 0, 0, .45);
	}

	html:not(.no-js) .aop-filterbar__sheet {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 999;
		max-height: 85vh;
		overflow-y: auto;
		/* Clears the home indicator on an iPhone, and is 0 everywhere else. */
		padding: 4px 16px calc(20px + env(safe-area-inset-bottom));
		background: var(--global-palette9, #fff);
		border-radius: 18px 18px 0 0;
		box-shadow: 0 -8px 30px rgba(0, 0, 0, .28);
		transform: translateY(100%);
		visibility: hidden;
		/* visibility is switched with a zero-length step, not interpolated:
		   instantly on the way in, and delayed until the slide has finished on
		   the way out. Transitioning it directly would leave the sheet hidden
		   for part of the opening frame, and focus() is ignored inside a hidden
		   subtree - so the first field would not take focus. */
		transition: transform .25s ease, visibility 0s linear .25s;
	}

	html:not(.no-js) .aop-filterbar.is-open .aop-filterbar__sheet {
		transform: translateY(0);
		visibility: visible;
		transition: transform .25s ease, visibility 0s linear 0s;
	}

	html:not(.no-js) .aop-filterbar__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 12px;
		margin: 0 0 4px;
		padding: 10px 0 6px;
	}

	html:not(.no-js) .aop-filterbar__title {
		font-size: 1.05rem;
		font-weight: 700;
	}

	html:not(.no-js) .aop-filterbar__close {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		margin-right: -10px;
		font-size: 1.7rem;
		line-height: 1;
		color: var(--global-palette4, #46545F);
		background: none;
		border: 0;
		cursor: pointer;
		/* The parent theme puts transition:all on buttons, which makes this one
		   animate the visibility it inherits from the opening sheet and sit at
		   hidden for a fifth of a second. Harmless to look at, but it made the
		   button unfocusable for that moment. */
		transition: none;
	}

	html:not(.no-js) .aop-filterbar__sheet:focus {
		outline: none;
	}

	/* The sheet is its own surface, so the bar inside it drops the tinted
	   panel it wears when it sits in the page. */
	html:not(.no-js) .aop-filterbar__sheet .aop-filters {
		padding: 0;
		margin: 0;
		background: none;
		border-radius: 0;
	}

	/* Stops the page behind scrolling while the sheet is up. */
	body.aop-sheet-open {
		overflow: hidden;
	}
}

@media (prefers-reduced-motion: reduce) {
	.aop-filterbar__sheet,
	.aop-filterbar.is-open .aop-filterbar__sheet {
		transition: none;
	}
}

/* ---------------------------------------------------------------------------
   Archive and single share a page shell
   --------------------------------------------------------------------------- */

.aop-archive,
.aop-single {
	max-width: 1200px;
	margin: 0 auto;
	padding: 48px 24px 64px;
}

.aop-archive__header {
	margin: 0 0 24px;
}

.aop-archive__eyebrow {
	margin: 0 0 6px;
	font-size: .8rem;
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--global-palette5, #5A6672);
}

.aop-archive__eyebrow a {
	color: var(--global-palette1, #0B5D4A);
	text-decoration: none;
}

.aop-archive__eyebrow a:hover {
	text-decoration: underline;
}

.aop-archive__eyebrow span {
	margin: 0 6px;
}

.aop-archive__title {
	margin: 0 0 8px;
	font-size: clamp(1.9rem, 4vw, 2.6rem);
	line-height: 1.15;
}

.aop-archive__desc {
	max-width: 60ch;
	margin: 0 0 8px;
	color: var(--global-palette4, #2E3A44);
}

.aop-archive__count {
	margin: 0;
	font-size: .92rem;
	color: var(--global-palette5, #5A6672);
}

.aop-archive__back {
	margin: 32px 0 0;
	font-size: .95rem;
}

.aop-archive__back a {
	color: var(--global-palette1, #0B5D4A);
	text-decoration: none;
}

.aop-archive__back a:hover {
	text-decoration: underline;
}

/* ---------------------------------------------------------------------------
   Single listing
   The contact actions sit directly under the name. On a phone that is the
   whole reason the visitor is here.
   --------------------------------------------------------------------------- */

.aop-single__header {
	display: flex;
	flex-wrap: wrap;
	gap: 20px;
	align-items: flex-start;
	justify-content: space-between;
	padding: 0 0 24px;
	margin: 8px 0 28px;
	border-bottom: 1px solid var(--global-palette6, #D9D5CC);
}

.aop-single__identity {
	display: flex;
	gap: 16px;
	align-items: flex-start;
	min-width: 0;
}

.aop-single__media {
	flex: 0 0 88px;
	width: 88px;
	height: 88px;
}

.aop-single__title {
	margin: 0 0 8px;
	font-size: clamp(1.6rem, 3.5vw, 2.2rem);
	line-height: 1.2;
}

.aop-single__prop {
	margin: 6px 0 0;
	font-size: .92rem;
	color: var(--global-palette5, #5A6672);
}

.aop-single__prop span {
	margin: 0 6px;
}

.aop-single__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.aop-single__layout {
	display: grid;
	grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
	gap: 40px;
	align-items: start;
}

.aop-section {
	margin: 0 0 32px;
}

.aop-section h2 {
	margin: 0 0 12px;
	font-size: 1.25rem;
}

.aop-prewrap {
	margin: 0;
	line-height: 1.7;
}

.aop-note {
	margin: 10px 0 0;
	font-size: .85rem;
	color: var(--global-palette5, #5A6672);
}

.aop-panel {
	padding: 20px;
	margin: 0 0 20px;
	background: #fff;
	border: 1px solid var(--global-palette6, #D9D5CC);
	border-radius: var(--aop-radius);
}

.aop-panel--muted {
	background: var(--global-palette7, #F7F5F0);
}

.aop-panel h2 {
	margin: 0 0 12px;
	font-size: 1.05rem;
}

.aop-dl {
	margin: 0;
}

.aop-dl dt {
	margin: 12px 0 2px;
	font-size: .76rem;
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--global-palette5, #5A6672);
}

.aop-dl dt:first-child {
	margin-top: 0;
}

.aop-dl dd {
	margin: 0;
	overflow-wrap: anywhere;
}

.aop-similar {
	margin-top: 8px;
	padding-top: 32px;
	border-top: 1px solid var(--global-palette6, #D9D5CC);
}

/* ---------------------------------------------------------------------------
   Festivals and events
   A festival is a term and never changes; an edition is a post with a date.
   The date block is the anchor of every event row, because "when" is the only
   thing anyone actually scans a festival list for.
   --------------------------------------------------------------------------- */

.aop-fgrid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: 16px;
	margin: 0 0 40px;
}

.aop-fcard {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: 20px;
	text-decoration: none;
	background: var(--aop-tint);
	border-radius: var(--aop-radius);
	transition: transform var(--aop-ease), box-shadow var(--aop-ease);
}

.aop-fcard:hover {
	transform: translateY(-2px);
	box-shadow: var(--aop-shadow-md);
}

.aop-fcard__name {
	font-size: 1.15rem;
	font-weight: 700;
	color: var(--global-palette1, #0B5D4A);
}

.aop-fcard__when {
	font-size: .9rem;
	color: var(--global-palette4, #2E3A44);
}

.aop-fcard__count {
	font-size: .74rem;
	letter-spacing: .05em;
	text-transform: uppercase;
	color: var(--global-palette5, #5A6672);
}

.aop-elist {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.aop-ecard {
	background: #fff;
	border: 1px solid var(--global-palette6, #D9D5CC);
	border-radius: var(--aop-radius);
	transition: box-shadow var(--aop-ease);
}

.aop-ecard:hover {
	box-shadow: var(--aop-shadow-sm);
}

.aop-ecard__link {
	display: flex;
	gap: 16px;
	align-items: center;
	padding: 14px 16px;
	text-decoration: none;
}

.aop-ecard__date {
	flex: 0 0 56px;
	width: 56px;
	padding: 8px 0;
	text-align: center;
	line-height: 1.1;
	background: var(--aop-tint);
	border-radius: var(--aop-radius-sm);
}

.aop-ecard__day {
	display: block;
	font-size: 1.3rem;
	font-weight: 700;
	color: var(--global-palette1, #0B5D4A);
}

.aop-ecard__mon {
	display: block;
	font-size: .7rem;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--global-palette5, #5A6672);
}

.aop-ecard__body {
	min-width: 0;
}

.aop-ecard__title {
	display: block;
	font-weight: 600;
	color: var(--global-palette3, #14202B);
}

.aop-ecard__meta {
	display: block;
	font-size: .86rem;
	color: var(--global-palette5, #5A6672);
}

.aop-edate {
	flex: 0 0 88px;
	width: 88px;
	padding: 12px 0;
	text-align: center;
	line-height: 1.1;
	background: var(--aop-tint);
	border-radius: var(--aop-radius-sm);
}

.aop-edate__day {
	display: block;
	font-size: 2rem;
	font-weight: 700;
	color: var(--global-palette1, #0B5D4A);
}

.aop-edate__mon {
	display: block;
	font-size: .78rem;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--global-palette5, #5A6672);
}

.aop-edate__yr {
	display: block;
	margin-top: 4px;
	font-size: .74rem;
	color: var(--global-palette5, #5A6672);
}

.aop-ehero {
	margin: 0 0 24px;
}

.aop-ehero img {
	width: 100%;
	height: auto;
	border-radius: var(--aop-radius);
}

/* ---------------------------------------------------------------------------
   Committee
   Office bearers get a larger card because a visitor checking who runs the
   society is usually looking for exactly three people.
   --------------------------------------------------------------------------- */

.aop-mgrid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: 20px;
}

.aop-mgrid--lead {
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.aop-mcard {
	display: flex;
	gap: 14px;
	padding: 16px;
	background: #fff;
	border: 1px solid var(--global-palette6, #D9D5CC);
	border-radius: var(--aop-radius);
}

.aop-mcard--lead {
	flex-direction: column;
	align-items: center;
	padding: 24px 20px;
	text-align: center;
	background: var(--global-palette7, #F7F5F0);
	border-color: transparent;
}

.aop-mcard__media {
	flex: 0 0 64px;
	width: 64px;
	height: 64px;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	background: var(--aop-tint);
	border-radius: 50%;
}

.aop-mcard--lead .aop-mcard__media {
	flex: 0 0 96px;
	width: 96px;
	height: 96px;
}

.aop-mcard__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.aop-mcard__body {
	min-width: 0;
}

.aop-mcard__name {
	margin: 0 0 2px;
	font-size: 1.05rem;
	line-height: 1.3;
}

.aop-mcard--lead .aop-mcard__name {
	font-size: 1.2rem;
}

.aop-mcard__role {
	margin: 0 0 2px;
	font-size: .88rem;
	font-weight: 600;
	color: var(--global-palette1, #0B5D4A);
}

.aop-mcard__term {
	margin: 0;
	font-size: .8rem;
	color: var(--global-palette5, #5A6672);
}

.aop-mcard__bio {
	margin: 8px 0 0;
	font-size: .88rem;
	color: var(--global-palette4, #2E3A44);
}

.aop-mcard__contact {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 10px 0 0;
	font-size: .85rem;
}

.aop-mcard--lead .aop-mcard__contact {
	justify-content: center;
}

/* ---------------------------------------------------------------------------
   Public submission form
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   Listing form wizard

   The step-hiding rule hangs off .is-wizard, which the script adds at runtime.
   If the script never runs, the class is absent, every fieldset stays visible
   and the form behaves exactly as it did before the wizard. That is deliberate:
   gating on html.no-js would hide the whole form whenever the script failed for
   any reason other than JavaScript being switched off.
   --------------------------------------------------------------------------- */

.aop-step {
	margin: 0;
	padding: 0;
	border: 0;
}

.aop-wizard.is-wizard .aop-step {
	display: none;
}

.aop-wizard.is-wizard .aop-step.is-current {
	display: block;
}

.aop-step__legend {
	width: 100%;
	padding: 0;
	margin: 0 0 16px;
}

.aop-step__title {
	display: block;
	font-size: 1.15rem;
	font-weight: 700;
	color: var(--global-palette3, #2E3A44);
}

.aop-step__blurb {
	display: block;
	margin-top: 2px;
	font-size: .9rem;
	font-weight: 400;
	color: var(--global-palette5, #5A6672);
}

.aop-wizard__progress {
	margin: 0 0 8px;
	font-size: .88rem;
	font-weight: 600;
	color: var(--global-palette5, #5A6672);
}

.aop-wizard__bar {
	height: 6px;
	margin: 0 0 24px;
	overflow: hidden;
	background: rgba(0, 0, 0, .09);
	border-radius: 3px;
}

.aop-wizard__bar-fill {
	display: block;
	width: 20%;
	height: 100%;
	background: var(--global-palette1, #B7411F);
	border-radius: 3px;
	transition: width .25s ease;
}

.aop-wizard__nav {
	display: flex;
	gap: 12px;
	margin: 24px 0 0;
}

.aop-wizard__nav .aop-btn {
	flex: 1 1 auto;
	min-height: 48px;
}

.aop-wizard__back[disabled] {
	opacity: .4;
	cursor: not-allowed;
}

.aop-form__notice--soft {
	background: var(--aop-tint);
}

.aop-plan__free {
	padding: 16px;
	margin: 0 0 18px;
	background: var(--aop-tint);
	border-radius: var(--aop-radius);
}

@media (prefers-reduced-motion: reduce) {
	.aop-wizard__bar-fill {
		transition: none;
	}
}

.aop-form-wrap {
	max-width: 680px;
}

.aop-form__field {
	margin: 0 0 20px;
}

.aop-form__field > label {
	display: block;
	margin-bottom: 6px;
	font-weight: 600;
}

.aop-form__field input[type="text"],
.aop-form__field input[type="email"],
.aop-form__field input[type="url"],
.aop-form__field textarea,
.aop-form__field select {
	width: 100%;
	min-height: 46px;
	padding: 10px 12px;
	background: #fff;
	border: 1px solid var(--global-palette6, #D9D5CC);
	border-radius: var(--aop-radius-sm);
}

.aop-form__field textarea {
	min-height: 110px;
	line-height: 1.6;
}

.aop-form__field input:focus-visible,
.aop-form__field textarea:focus-visible,
.aop-form__field select:focus-visible {
	outline: 3px solid var(--global-palette1, #0B5D4A);
	outline-offset: 1px;
}

.aop-form__hint {
	display: block;
	margin-top: 5px;
	font-size: .85rem;
	color: var(--global-palette5, #5A6672);
}

.aop-req {
	color: #B3261E;
}

.aop-form__consent {
	padding: 16px;
	background: var(--global-palette7, #F7F5F0);
	border-radius: var(--aop-radius-sm);
}

.aop-form__consent label {
	display: flex;
	gap: 10px;
	align-items: flex-start;
	font-weight: 400;
}

.aop-form__submit {
	margin: 24px 0 0;
}

.aop-form__submit .aop-btn {
	min-height: 48px;
	padding: 12px 28px;
	font-size: 1rem;
}

.aop-alert {
	padding: 16px 20px;
	margin: 0 0 24px;
	background: #FDECEA;
	border-left: 4px solid #B3261E;
	border-radius: var(--aop-radius-sm);
}

.aop-alert p {
	margin: 0 0 6px;
}

.aop-alert ul {
	margin: 0;
	padding-left: 20px;
}

.aop-submitted {
	text-align: left;
}

.aop-submitted .aop-btn {
	margin-top: 8px;
}

/* The honeypot must be unreachable for people but present in the DOM for
   bots. Kept off-screen rather than display:none, which many bots skip. */

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

/* ---------------------------------------------------------------------------
   Directory: the visiting card
   Roughly 3.5:2 like a real visiting card, but allowed to grow with content.
   --------------------------------------------------------------------------- */

.aop-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
	gap: 20px;
}

.aop-card {
	position: relative;
	display: flex;
	gap: 14px;
	padding: 16px;
	background: #fff;
	border: 1px solid var(--global-palette6, #D9D5CC);
	border-radius: var(--aop-radius);
	box-shadow: var(--aop-shadow-sm);
	transition: box-shadow var(--aop-ease), transform var(--aop-ease);
}

.aop-card:hover,
.aop-card:focus-within {
	box-shadow: var(--aop-shadow-md);
	transform: translateY(-2px);
}

.aop-card--promoted {
	border-color: var(--aop-gold);
}

.aop-card__promoted {
	position: absolute;
	top: -10px;
	right: 12px;
	padding: 2px 10px;
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: #fff;
	background: var(--aop-gold);
	border-radius: 999px;
}

.aop-card__media {
	flex: 0 0 72px;
	width: 72px;
	height: 72px;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	background: var(--aop-tint);
	border-radius: var(--aop-radius-sm);
	text-decoration: none;
}

.aop-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.aop-card__initials {
	font-size: 1.5rem;
	font-weight: 700;
	color: var(--global-palette1, #0B5D4A);
}

.aop-card__body {
	flex: 1 1 auto;
	min-width: 0;
}

.aop-card__title {
	margin: 0 0 6px;
	font-size: 1.06rem;
	line-height: 1.3;
}

.aop-card__title a {
	text-decoration: none;
	color: var(--global-palette3, #14202B);
}

.aop-card__title a:hover {
	color: var(--global-palette1, #0B5D4A);
}

.aop-card__verified {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	margin-left: 6px;
	font-size: .72rem;
	color: #fff;
	background: var(--global-palette1, #0B5D4A);
	border-radius: 50%;
	vertical-align: middle;
}

.aop-card__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin: 0 0 4px;
	font-size: .85rem;
}

.aop-card__tag {
	padding: 2px 10px;
	color: var(--global-palette1, #0B5D4A);
	background: var(--aop-tint);
	border-radius: 999px;
	font-weight: 600;
	text-decoration: none;
}

.aop-card__where {
	color: var(--global-palette5, #5A6672);
	text-decoration: none;
}

a.aop-card__tag:hover,
a.aop-card__where:hover {
	text-decoration: underline;
}

.aop-card__prop {
	margin: 0 0 12px;
	font-size: .88rem;
	color: var(--global-palette5, #5A6672);
}

/* Actions. Call and WhatsApp are the two controls that matter on a phone,
   so they are full-size tap targets and never collapse into an icon. */

.aop-card__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.aop-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 40px;
	padding: 8px 16px;
	font-size: .88rem;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	border: 1px solid transparent;
	border-radius: 999px;
	cursor: pointer;
	transition: background var(--aop-ease), color var(--aop-ease);
}

.aop-btn--primary,
.aop-btn--call {
	color: #fff;
	background: var(--global-palette1, #0B5D4A);
}

.aop-btn--primary:hover,
.aop-btn--call:hover {
	background: var(--global-palette2, #084535);
	color: #fff;
}

.aop-btn--wa {
	color: #128C7E;
	background: #fff;
	border-color: #128C7E;
}

.aop-btn--wa:hover {
	color: #fff;
	background: #128C7E;
}

.aop-btn--map {
	color: var(--global-palette4, #2E3A44);
	background: #fff;
	border-color: var(--global-palette6, #D9D5CC);
}

.aop-btn--map:hover {
	background: var(--global-palette7, #F7F5F0);
}

.aop-btn:focus-visible,
.aop-card__title a:focus-visible {
	outline: 3px solid var(--global-palette1, #0B5D4A);
	outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   Empty state and pagination
   --------------------------------------------------------------------------- */

.aop-empty {
	padding: 32px 24px;
	text-align: center;
	background: var(--global-palette7, #F7F5F0);
	border-radius: var(--aop-radius);
}

.aop-empty p {
	margin: 0 0 8px;
}

.aop-pagination {
	margin-top: 28px;
	text-align: center;
}

.aop-pagination .page-numbers {
	display: inline-block;
	min-width: 40px;
	min-height: 40px;
	padding: 9px 12px;
	margin: 0 3px;
	text-decoration: none;
	border: 1px solid var(--global-palette6, #D9D5CC);
	border-radius: var(--aop-radius-sm);
}

.aop-pagination .page-numbers.current {
	color: #fff;
	background: var(--global-palette1, #0B5D4A);
	border-color: var(--global-palette1, #0B5D4A);
}

/* ---------------------------------------------------------------------------
   Small screens. The directory is used mostly on a phone over 4G, so the
   card goes single column and the actions stay full width and thumb-sized.
   --------------------------------------------------------------------------- */

@media (max-width: 900px) {
	.aop-single__layout {
		grid-template-columns: 1fr;
		gap: 8px;
	}
}

@media (max-width: 600px) {
	.aop-grid,
	.aop-mgrid,
	.aop-mgrid--lead {
		grid-template-columns: 1fr;
	}

	.aop-archive,
	.aop-single {
		padding: 28px 16px 44px;
	}

	.aop-filters {
		padding: 16px;
	}

	.aop-filters__submit {
		flex: 1 1 100%;
	}

	.aop-filters__submit .aop-btn {
		flex: 1 1 auto;
	}

	.aop-card__actions .aop-btn {
		flex: 1 1 calc(50% - 4px);
	}

	.aop-single__media,
	.aop-edate {
		flex: 0 0 64px;
		width: 64px;
		height: auto;
	}

	.aop-single__actions {
		width: 100%;
	}

	.aop-single__actions .aop-btn {
		flex: 1 1 100%;
	}

	.aop-form__submit .aop-btn {
		width: 100%;
	}
}

/* ---------------------------------------------------------------------------
   Home page hero carousel
   Markup comes from the AOP Core plugin ([aop_hero]); only the look lives
   here, the same split the directory card uses.

   The slides are stacked and cross-faded rather than slid sideways: a
   horizontal track needs its width recalculated on every resize and fights
   the page's own scrolling on a phone, and a fade costs one property.
   --------------------------------------------------------------------------- */

.aop-hero {
	position: relative;
	overflow: hidden;
	border-radius: var(--aop-radius-lg);
	box-shadow: var(--aop-shadow-md);
	min-height: clamp(420px, 62vh, 620px);
	margin: 0 0 2.5rem;
	isolation: isolate;
	background: #06333A;
}

.aop-hero__track {
	display: grid;
}

/* Every slide occupies the same grid cell, so the tallest one sets the
   height and nothing jumps as the carousel advances. */
.aop-hero__slide {
	grid-area: 1 / 1;
	position: relative;
	display: flex;
	align-items: center;
	min-height: clamp(420px, 62vh, 620px);
	opacity: 0;
	visibility: hidden;
	transition: opacity var(--aop-ease), visibility var(--aop-ease);
}

.aop-hero__slide.is-active {
	opacity: 1;
	visibility: visible;
}

/* Without JavaScript nothing ever gets .is-active, so the first slide has to
   stand on its own.

   This MUST be scoped to :not(.is-ready), and the script adds .is-ready to the
   root once it takes over. Scoping it by :first-child alone does not work:
   .aop-hero__track .aop-hero__slide:first-child scores 0,3,0 against
   .aop-hero__slide.is-active at 0,2,0, so the fallback outranks the active
   slide and slide one can never hide. The symptom is two slides painted on top
   of each other with the text superimposed. */
.aop-hero:not(.is-ready) .aop-hero__slide:first-child {
	opacity: 1;
	visibility: visible;
}

.aop-hero__media {
	position: absolute;
	inset: 0;
	z-index: -1;
}

.aop-hero__art,
.aop-hero__photo {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* A scrim, not a flat overlay: the artwork stays visible on the right while
   the text side gets the contrast it needs. Text over imagery is where most
   hero carousels become unreadable. */
.aop-hero__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(100deg, rgba(3, 32, 26, .88) 0%, rgba(3, 32, 26, .72) 38%, rgba(3, 32, 26, .18) 72%, rgba(3, 32, 26, .05) 100%);
}

.aop-hero__body {
	position: relative;
	max-width: 46rem;
	padding: 3rem clamp(1.5rem, 5vw, 4.5rem);
	color: #fff;
}

.aop-hero__eyebrow {
	margin: 0 0 .6rem;
	font-size: .78rem;
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	/* The lighter gold, not --aop-gold (#C8912A). At 12.48px/700 this is not
	   "large text", so it needs 4.5:1 against whatever is behind it - and what
	   is behind it is artwork under a partly transparent scrim, not a flat
	   colour. #C8912A measured below 4.5:1 on the narrow layout where the scrim
	   is weakest. This tone is from the same family used in the artwork. */
	color: #E8C583;
}

.aop-hero__title {
	margin: 0 0 .85rem;
	font-size: clamp(1.9rem, 4.6vw, 3.25rem);
	line-height: 1.1;
	color: #fff;
}

.aop-hero__text {
	margin: 0 0 1.6rem;
	font-size: clamp(1rem, 1.5vw, 1.15rem);
	line-height: 1.6;
	color: rgba(255, 255, 255, .92);
	max-width: 34rem;
}

.aop-hero__cta {
	margin: 0;
}

/* Controls ---------------------------------------------------------------- */

.aop-hero__nav {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 1.25rem;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1rem;
	padding: 0 1rem;
}

.aop-hero__arrow,
.aop-hero__toggle {
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	border: 1px solid rgba(255, 255, 255, .45);
	border-radius: 50%;
	background: rgba(3, 32, 26, .45);
	color: #fff;
	font-size: 1.6rem;
	line-height: 1;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background var(--aop-ease), border-color var(--aop-ease);
}

.aop-hero__arrow:hover,
.aop-hero__arrow:focus-visible,
.aop-hero__toggle:hover,
.aop-hero__toggle:focus-visible {
	background: rgba(3, 32, 26, .8);
	border-color: #fff;
}

/* The pause control is smaller than the arrows and sits apart from them: it is
   a different kind of action, and it should not read as a third way to move
   between slides. */
.aop-hero__toggle {
	width: 38px;
	height: 38px;
	font-size: .9rem;
	margin-right: .25rem;
}

.aop-hero__dots {
	display: flex;
	align-items: center;
	gap: .5rem;
}

/* 14px of visible dot, but a 24px touch target - a 10px tap target is the
   commonest accessibility failure in a carousel. */
.aop-hero__dot {
	width: 24px;
	height: 24px;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
	position: relative;
}

.aop-hero__dot::after {
	content: "";
	position: absolute;
	inset: 5px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .45);
	transition: background var(--aop-ease), transform var(--aop-ease);
}

.aop-hero__dot.is-current::after {
	background: var(--aop-gold);
	transform: scale(1.25);
}

.aop-hero__dot:focus-visible::after {
	outline: 2px solid #fff;
	outline-offset: 2px;
}

/* Motion ------------------------------------------------------------------ */

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

	.aop-hero__slide {
		transition: none;
	}

	.aop-hero__dot::after,
	.aop-hero__arrow {
		transition: none;
	}
}

@media (max-width: 900px) {

	.aop-hero {
		border-radius: var(--aop-radius);
	}

	/* Stronger at the top than it looks like it needs to be: this is where the
	   eyebrow and headline sit once the layout stacks, and .58 left them over
	   whatever the artwork happened to be doing there. Legibility wins over
	   showing more of the drawing. */
	.aop-hero__media::after {
		background: linear-gradient(180deg, rgba(3, 32, 26, .80) 0%, rgba(3, 32, 26, .88) 55%, rgba(3, 32, 26, .94) 100%);
	}

	.aop-hero__body {
		max-width: none;
		padding: 2.5rem 1.5rem 5rem;
	}
}

@media (max-width: 600px) {

	.aop-hero,
	.aop-hero__slide {
		min-height: 460px;
	}

	.aop-hero__text {
		font-size: 1rem;
	}

	.aop-hero__cta .aop-btn {
		width: 100%;
	}

	.aop-hero__arrow {
		width: 40px;
		height: 40px;
	}
}

/* ---------------------------------------------------------------------------
   Hero band: carousel 70%, sponsor rail 30%
   Markup from inc/hero.php ([aop_hero_band]).

   The split only exists when .has-rail is present, which the shortcode adds
   only when there is an advertiser to show. With no sponsors booked there is
   one grid column and the carousel is full width - the same page it was
   before this existed, with no empty third of the screen.
   --------------------------------------------------------------------------- */

.aop-heroband {
	display: grid;
	gap: 1.25rem;
	margin: 0 0 2.5rem;
	align-items: stretch;
}

/* The carousel carries its own 2.5rem bottom margin for when it is used on its
   own; inside the band the wrapper owns the spacing, or the row and the rail
   end up different heights. */
.aop-heroband .aop-hero {
	margin-bottom: 0;
	height: 100%;
}

@media (min-width: 901px) {

	/* 70/30. fr rather than percentages so the gap comes out of the columns
	   instead of overflowing the row. */
	.aop-heroband.has-rail {
		grid-template-columns: 70fr 30fr;
	}
}

.aop-heroband__rail {
	display: flex;
	min-width: 0;
}

.aop-heroband__rail .aop-adslot {
	flex: 1;
	display: flex;
	flex-direction: column;
	min-width: 0;
	margin: 0;
}

/* :not([hidden]) is load-bearing, not decoration. banners.css hides the
   second and later advertiser with .aop-ad[hidden] { display: none }, which
   scores the same 0,2,0 as .aop-heroband__rail .aop-ad - so an unqualified
   display:flex here would win on order alone and paint every sponsor in the
   slot at once, on top of each other. */
.aop-heroband__rail .aop-ad:not([hidden]) {
	flex: 1;
	display: flex;
	flex-direction: column;
	min-height: 0;
	margin: 0;
}

/* The frame goes on __link, where banners.css already puts the background and
   border. .aop-ad also wraps the "Advertisement" label, which the module
   deliberately keeps outside the framed box. */
.aop-heroband__rail .aop-ad__link {
	flex: 1;
	min-height: 0;
	border-radius: var(--aop-radius-lg);
	box-shadow: var(--aop-shadow-md);
}

.aop-heroband__rail .aop-ad__link picture {
	display: block;
}

/* contain, not cover: this is somebody's paid artwork, and cropping their
   telephone number off the edge is not ours to do.

   Stacked under the carousel on a phone the creative keeps its natural flow
   and is simply capped, because a 300x600 banner at full width would be
   taller than the screen and push every real section below the fold. The
   advertiser can upload a wide mobile version; this caps the damage when
   they have not. */
.aop-heroband__rail .aop-ad__link img {
	max-height: 320px;
	object-fit: contain;
	object-position: center;
}

/* This block MUST come after the rule above, not beside the column rule higher
   up. A media query adds no specificity, so these and the base declarations
   score identically and the later one simply wins - written above, max-height
   went back to 320px and the sponsor sat as a small letterboxed picture in a
   tall white box.

   What these do: the carousel sets the height of the band and the sponsor fits
   into it. Taking the creative out of flow is what makes that true. Left in
   flow, a 300x600 banner's intrinsic height drives the grid row, the carousel
   is stretched past the bottom of its own artwork, and the band ends in a strip
   of bare background under the drawing. */
@media (min-width: 901px) {

	.aop-heroband__rail .aop-ad__link {
		position: relative;
	}

	.aop-heroband__rail .aop-ad__link picture {
		position: absolute;
		inset: 0;
	}

	.aop-heroband__rail .aop-ad__link img {
		width: 100%;
		height: 100%;
		max-height: none;
	}
}

@media (max-width: 900px) {

	.aop-heroband__rail .aop-ad__link {
		border-radius: var(--aop-radius);
	}
}

/* The unsold rail: the Society's own invitation, not an advertisement.

   It shares none of the .aop-ad furniture on purpose - no Advertisement label,
   no counting - so the dashed edge is what tells a visitor this is space
   offered rather than space bought. */
.aop-railhouse {
	position: relative;
	flex: 1;
	display: flex;
	min-height: 0;
}

/* Same :not([hidden]) guard as the advertisement rail. The panels are hidden
   in the markup so a visitor without JavaScript sees one rather than three,
   and an unqualified display:flex here would score the same and win on order,
   painting all three on top of each other. */
.aop-railhouse__panel:not([hidden]) {
	flex: 1;
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: .55rem;
	min-height: 0;
	padding: 2rem 1.5rem 2.75rem;
	text-align: center;
	border: 2px dashed var(--global-palette6, #D9D5CC);
	border-radius: var(--aop-radius-lg);
	background: var(--aop-tint);
}

/* Dots, so the column reads as a slider rather than as a panel that happens to
   change when you look away. Hidden until the script runs - without it they
   would control nothing. */
.aop-railhouse__dots {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 1rem;
	display: flex;
	justify-content: center;
	gap: 8px;
	margin: 0;
}

.aop-railhouse__dot {
	width: 26px;
	height: 26px;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
	display: grid;
	place-items: center;
}

.aop-railhouse__dot::after {
	content: "";
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: var(--global-palette4, #2E3A44);
	opacity: .32;
	transition: opacity var(--aop-ease), transform var(--aop-ease);
}

.aop-railhouse__dot.is-current::after {
	opacity: 1;
	transform: scale(1.25);
}

.aop-railhouse__dot:focus-visible {
	outline: 3px solid var(--global-palette1, #0B5D4A);
	outline-offset: 2px;
	border-radius: 50%;
}

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

	.aop-railhouse__dot::after {
		transition: none;
	}
}

.aop-railhouse__eyebrow {
	margin: 0;
	font-size: .72rem;
	font-weight: 700;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--global-palette4, #2E3A44);
}

.aop-railhouse__title {
	margin: 0;
	font-size: clamp(1.25rem, 2vw, 1.6rem);
	line-height: 1.2;
}

.aop-railhouse__text {
	margin: 0;
	font-size: .92rem;
	line-height: 1.5;
}

.aop-railhouse__cta {
	margin: .35rem 0 0;
}

/* Hidden once the band stacks. A paid banner still shows on a phone - the
   advertiser bought it - but the Society's own filler has no claim on that
   space, and stacking it under the carousel would push the real sections
   further down for nothing. */
@media (max-width: 900px) {

	.aop-heroband__rail--house {
		display: none;
	}
}

/* ---------------------------------------------------------------------------
   Home page sections (spec P1, sections 3-9)
   Markup from inc/home.php; only the look lives here.
   --------------------------------------------------------------------------- */

/* Impact counters ---------------------------------------------------------- */

.aop-stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 1.5rem;
	margin: 0 0 2.5rem;
	padding: 2rem 1.5rem;
	background: var(--aop-tint);
	border-radius: var(--aop-radius);
	text-align: center;
}

.aop-stat__n {
	display: block;
	font-size: clamp(1.9rem, 4vw, 2.75rem);
	font-weight: 700;
	line-height: 1.1;
	color: var(--global-palette1, #0B5D4A);
}

.aop-stat__l {
	display: block;
	margin-top: .35rem;
	font-size: .92rem;
	color: var(--global-palette5, #5A6672);
}

/* Our work: three pillars -------------------------------------------------- */

.aop-pillars {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 1.25rem;
	margin: 0 0 2.5rem;
}

.aop-pillar {
	display: block;
	padding: 1.75rem;
	border: 1px solid var(--border, #E5E7EB);
	border-radius: var(--aop-radius);
	background: #fff;
	text-decoration: none;
	color: inherit;
	transition: box-shadow var(--aop-ease), transform var(--aop-ease);
}

.aop-pillar:hover,
.aop-pillar:focus-visible {
	box-shadow: var(--aop-shadow-md);
	transform: translateY(-2px);
}

.aop-pillar__title {
	margin: 0 0 .5rem;
	font-size: 1.3rem;
	color: var(--global-palette1, #0B5D4A);
}

.aop-pillar__text {
	margin: 0 0 .85rem;
	font-size: .96rem;
	line-height: 1.55;
	color: var(--global-palette4, #2E3A44);
}

.aop-pillar__more {
	font-weight: 600;
	color: var(--global-palette1, #0B5D4A);
}

/* Events teaser ------------------------------------------------------------ */

.aop-home-events {
	margin: 0 0 2.5rem;
}

.aop-home-events__title,
.aop-notices__title,
.aop-teaser__title {
	margin: 0 0 1rem;
	font-size: clamp(1.4rem, 2.6vw, 1.9rem);
}

.aop-home-events__more,
.aop-notices__more {
	margin: 1rem 0 0;
	font-weight: 600;
}

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

.aop-teaser {
	margin: 0 0 2.5rem;
	padding: 2rem clamp(1.25rem, 4vw, 2.5rem);
	background: var(--aop-tint);
	border-radius: var(--aop-radius);
}

.aop-teaser__text {
	margin: 0 0 1.25rem;
	color: var(--global-palette4, #2E3A44);
}

.aop-teaser__form {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 1rem;
	margin: 0 0 1rem;
}

.aop-teaser__field {
	flex: 1 1 200px;
	margin: 0;
}

.aop-teaser__field label {
	display: block;
	margin-bottom: .3rem;
	font-size: .85rem;
	font-weight: 600;
}

.aop-teaser__field select {
	width: 100%;
}

.aop-teaser__submit {
	flex: 0 0 auto;
	margin: 0;
}

.aop-teaser__chips {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem;
	margin: 0;
}

.aop-chip {
	display: inline-block;
	padding: .35rem .85rem;
	border: 1px solid var(--global-palette1, #0B5D4A);
	border-radius: 999px;
	font-size: .85rem;
	text-decoration: none;
	color: var(--global-palette1, #0B5D4A);
	background: #fff;
	transition: background var(--aop-ease), color var(--aop-ease);
}

.aop-chip:hover,
.aop-chip:focus-visible {
	background: var(--global-palette1, #0B5D4A);
	color: #fff;
}

/* Notices ------------------------------------------------------------------ */

.aop-notices {
	margin: 0 0 2.5rem;
}

.aop-notices__list {
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--border, #E5E7EB);
}

.aop-notice {
	border-bottom: 1px solid var(--border, #E5E7EB);
}

.aop-notice__link {
	display: flex;
	flex-wrap: wrap;
	gap: .25rem 1.25rem;
	padding: .9rem 0;
	text-decoration: none;
	color: inherit;
}

.aop-notice__link:hover .aop-notice__title,
.aop-notice__link:focus-visible .aop-notice__title {
	text-decoration: underline;
}

.aop-notice__date {
	flex: 0 0 7.5rem;
	font-size: .88rem;
	color: var(--global-palette5, #5A6672);
}

.aop-notice__title {
	flex: 1 1 16rem;
	font-weight: 600;
	color: var(--global-palette1, #0B5D4A);
}

/* Trust strip -------------------------------------------------------------- */

.aop-trust {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem 1.25rem;
	align-items: center;
	margin: 0 0 2rem;
	padding: .85rem 1.25rem;
	border: 1px solid var(--border, #E5E7EB);
	border-radius: var(--aop-radius-sm);
	font-size: .9rem;
	color: var(--global-palette5, #5A6672);
}

.aop-trust__reg {
	font-weight: 600;
	color: var(--global-palette4, #2E3A44);
}

.aop-trust__badge {
	padding: .2rem .6rem;
	border-radius: 999px;
	background: var(--aop-tint);
	color: var(--global-palette1, #0B5D4A);
	font-weight: 600;
}

@media (max-width: 600px) {

	.aop-teaser__submit .aop-btn {
		width: 100%;
	}

	.aop-notice__date {
		flex: 1 1 100%;
	}
}

/* ---------------------------------------------------------------------------
   Site footer (spec 3.2)
   Markup from the child theme's functions.php, hooked to kadence_top_footer so
   it renders inside <footer> above Kadence's copyright row.
   --------------------------------------------------------------------------- */

/* The divider is a neutral grey, not white: Kadence renders this footer on a
   light background by default, and a white rule on white is invisible. Grey at
   low alpha reads on either, so it survives a change of footer colour. */
.aop-footer {
	padding: 3rem 0 2.5rem;
	border-bottom: 1px solid rgba(128, 128, 128, .3);
}

.aop-footer__inner {
	display: grid;
	grid-template-columns: 1.4fr 1fr 1fr 1.2fr;
	gap: 2.5rem;
	max-width: 1200px;
	margin: 0 auto;
	padding: 0 24px;
}

.aop-footer__name {
	margin: 0 0 .5rem;
	font-size: 1.15rem;
	font-weight: 700;
}

.aop-footer__mission,
.aop-footer__reg {
	margin: 0 0 .5rem;
	font-size: .9rem;
	line-height: 1.6;
	opacity: .85;
}

.aop-footer__reg {
	font-weight: 600;
	opacity: 1;
}

.aop-footer__heading {
	margin: 0 0 .85rem;
	font-size: .8rem;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	opacity: .7;
}

.aop-footer__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.aop-footer__list li {
	margin: 0 0 .5rem;
	font-size: .92rem;
	line-height: 1.5;
}

.aop-footer__list a {
	text-decoration: none;
	opacity: .85;
	transition: opacity var(--aop-ease);
}

.aop-footer__list a:hover,
.aop-footer__list a:focus-visible {
	opacity: 1;
	text-decoration: underline;
}

.aop-footer__contact li {
	opacity: .85;
}

/* --------------------------------------------------------------------------
   Opening hours
   -------------------------------------------------------------------------- */

/* Hidden until the script has worked out the answer. Rendering "Open now" from
   PHP would be frozen by the page cache, so the markup arrives blank and is
   filled in by the browser - which means it must not occupy space until then. */
.aop-openstate[hidden] {
	display: none;
}

.aop-openstate {
	display: inline-block;
	margin: 0 0 8px;
	padding: 3px 10px;
	font-size: .78rem;
	font-weight: 700;
	letter-spacing: .02em;
	border-radius: 999px;
}

.aop-openstate.is-open {
	color: var(--global-palette1, #0B5D4A);
	background: var(--aop-tint, #E6F5F1);
}

/* Closed is a fact, not a fault, so it is neutral rather than red. Red would
   read as something having gone wrong with the listing. */
.aop-openstate.is-shut {
	color: var(--global-palette4, #2E3A44);
	background: var(--global-palette7, #F7F5F0);
}

.aop-hours {
	margin: 12px 0 0;
	font-size: .92rem;
}

.aop-hours__row {
	display: grid;
	grid-template-columns: 7.5rem 1fr;
	gap: 4px 16px;
	padding: 6px 0;
	border-bottom: 1px solid var(--global-palette6, #D9D5CC);
}

.aop-hours__row:last-child {
	border-bottom: 0;
}

.aop-hours dt {
	font-weight: 600;
	color: var(--global-palette5, #5A6672);
}

.aop-hours dd {
	margin: 0;
	font-variant-numeric: tabular-nums;
}

@media (max-width: 480px) {

	.aop-hours__row {
		grid-template-columns: 6rem 1fr;
	}
}

/* --------------------------------------------------------------------------
   Utility pages: search results and 404 (spec P24)
   -------------------------------------------------------------------------- */

.aop-results {
	margin: 24px 0 0;
	padding: 0;
	list-style: none;
}

.aop-result {
	padding: 20px 0;
	border-bottom: 1px solid var(--global-palette6, #D9D5CC);
}

.aop-result:first-child {
	border-top: 1px solid var(--global-palette6, #D9D5CC);
}

/* The kind of thing a result is, said before its title. A visitor searching
   "Ganesh Puja" gets a page, an event and an album back; without the label they
   have to open each one to find out which is which. */
.aop-result__kind {
	display: inline-block;
	margin: 0 0 6px;
	padding: 3px 10px;
	font-size: .7rem;
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--global-palette1, #0B5D4A);
	background: var(--aop-tint, #E6F5F1);
	border-radius: 999px;
}

.aop-result__title {
	margin: 0 0 6px;
	font-size: 1.2rem;
	line-height: 1.3;
}

.aop-result__title a {
	text-decoration: none;
}

.aop-result__title a:hover,
.aop-result__title a:focus-visible {
	text-decoration: underline;
}

.aop-result__excerpt {
	margin: 0;
	max-width: 70ch;
	line-height: 1.6;
	color: var(--global-palette4, #2E3A44);
}

/* Shared by the 404 and the empty search result: both are the same problem,
   somebody wanted something and did not get it. */
.aop-helpful {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 14px 0 0;
	padding: 0;
	list-style: none;
}

.aop-helpful li {
	margin: 0;
}

.aop-helpful a {
	display: inline-block;
	padding: 10px 18px;
	font-weight: 600;
	text-decoration: none;
	background: var(--aop-tint, #E6F5F1);
	border-radius: 999px;
}

.aop-helpful a:hover,
.aop-helpful a:focus-visible {
	color: #fff;
	background: var(--global-palette1, #0B5D4A);
}

.aop-404 .aop-archive__desc {
	font-size: 1.05rem;
}

.aop-404 h2 {
	margin: 32px 0 0;
	font-size: 1.1rem;
}

/* --------------------------------------------------------------------------
   Header (spec 3.1)
   -------------------------------------------------------------------------- */

/* Two separate traps here, both found by measuring rather than by reading.
   1. The header's parent, div.site, sets overflow:clip. That clips painting but
      does NOT create a scroll container, so sticky still resolves against the
      viewport. overflow:hidden there would have broken this silently.
   2. Kadence sets "#masthead { position: relative }" in its header stylesheet.
      An ID out-ranks any class, so a plain .site-header rule here computed to
      relative and the header simply did not stick. Matching the ID as well puts
      this one step above it without reaching for !important. */
#masthead.site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	/* A permanent edge, not only the scrolled shadow below. The shadow is added
	   by JavaScript on scroll; this makes sure the header still reads as a
	   separate surface if that never runs. */
	border-bottom: 1px solid var(--global-palette6, #D9D5CC);
}

.admin-bar #masthead.site-header {
	top: 32px;
}

@media (max-width: 782px) {

	.admin-bar #masthead.site-header {
		top: 46px;
	}
}

#masthead.site-header.aop-is-stuck {
	box-shadow: 0 2px 12px rgba(0, 0, 0, .12);
}

/* Order the trailing group: navigation, then search, then the two calls to
   action. The menu ul is already display:flex, so order is all that is needed
   and Kadence's own layout is left alone. */
.header-navigation ul.menu > .aop-nav-search {
	order: 1;
}

.header-navigation ul.menu > .aop-nav-account {
	order: 1;
}

.header-navigation ul.menu > .aop-nav-cta {
	order: 2;
}

.header-navigation ul.menu > .aop-nav-cta--primary {
	order: 3;
}

/* Prefixed with #masthead deliberately. Kadence's inline header CSS colours nav
   links at ".main-navigation .primary-menu-container > ul > li.menu-item > a",
   which out-scores any class-only selector and is emitted after this file. Left
   unprefixed, Donate rendered as grey #5A6672 text on gold at 2.11:1 - a plain
   contrast failure that looked correct in the CSS and only showed when measured. */
#masthead .header-navigation ul.menu > .aop-nav-cta > a {
	display: inline-flex;
	align-items: center;
	min-height: 38px;
	margin-left: .45rem;
	padding: 6px 14px;
	font-size: .85rem;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	border: 1px solid var(--global-palette1, #0B5D4A);
	border-radius: 999px;
	color: var(--global-palette1, #0B5D4A);
	background: transparent;
	transition: background var(--aop-ease), color var(--aop-ease);
}

#masthead .header-navigation ul.menu > .aop-nav-cta > a:hover,
#masthead .header-navigation ul.menu > .aop-nav-cta > a:focus-visible {
	color: #fff;
	background: var(--global-palette1, #0B5D4A);
}

/* Donate is the one action the whole site exists to funnel people towards, so
   it is the only place gold is used as a fill. Dark text on that gold measures
   6.2:1; white would have measured 2.8:1 and failed. */
#masthead .header-navigation ul.menu > .aop-nav-cta--primary > a {
	color: #1A1A1A;
	background: var(--aop-gold, #C8912A);
	border-color: var(--aop-gold, #C8912A);
}

#masthead .header-navigation ul.menu > .aop-nav-cta--primary > a:hover,
#masthead .header-navigation ul.menu > .aop-nav-cta--primary > a:focus-visible {
	color: #1A1A1A;
	background: #B07F22;
	border-color: #B07F22;
}

/* Search */
.aop-nav-search {
	position: relative;
}

.aop-search-toggle {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	min-height: 38px;
	padding: 6px 10px;
	margin-left: .35rem;
	font: inherit;
	font-size: .85rem;
	color: inherit;
	background: none;
	border: 0;
	border-radius: 999px;
	cursor: pointer;
}

.aop-search-toggle:hover,
.aop-search-toggle:focus-visible {
	background: var(--global-palette7, #F7F5F0);
}

.aop-search-panel {
	position: absolute;
	top: calc(100% + 10px);
	right: 0;
	z-index: 20;
	width: min(21rem, calc(100vw - 2rem));
	padding: 12px;
	background: #fff;
	border: 1px solid var(--global-palette6, #D9D5CC);
	border-radius: var(--aop-radius-sm);
	box-shadow: var(--aop-shadow-md);
}

.aop-search-panel[hidden] {
	display: none;
}

.aop-search-panel form {
	display: flex;
	gap: .5rem;
}

/* On desktop the icon carries the control on its own. The label stays in the
   DOM, only visually hidden, so the button keeps its accessible name - the nav
   simply has no room for another 55px once both calls to action are in it. */
@media (min-width: 1025px) {

	.aop-search-toggle {
		padding: 6px 9px;
	}

	.aop-search-toggle__label {
		position: absolute;
		width: 1px;
		height: 1px;
		padding: 0;
		margin: -1px;
		overflow: hidden;
		clip: rect(0 0 0 0);
		white-space: nowrap;
		border: 0;
	}
}

.aop-search-panel input[type="search"] {
	flex: 1 1 auto;
	min-width: 0;
	min-height: 40px;
	padding: 6px 10px;
	border: 1px solid var(--global-palette6, #D9D5CC);
	border-radius: var(--aop-radius-sm);
}

/* Inside the mobile drawer the menu stacks, so the panel becomes part of the
   flow instead of a floating card that would be clipped by the drawer. */
@media (max-width: 1024px) {

	.aop-search-panel {
		position: static;
		width: auto;
		box-shadow: none;
	}

	#masthead .header-navigation ul.menu > .aop-nav-cta > a {
		margin-left: 0;
	}
}

/* Donate in the collapsed mobile bar (spec 3.1). Rendered through
   kadence_mobile_main_header, which was confirmed by probe to fire inside
   .site-mobile-header-wrap. A donate button that first requires opening a
   hamburger is one most people never see. */
.aop-mobile-donate {
	display: flex;
	justify-content: center;
	padding: 0 0 10px;
}

.aop-mobile-donate a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 40px;
	padding: 8px 28px;
	font-size: .9rem;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	color: #1A1A1A;
	background: var(--aop-gold, #C8912A);
	border-radius: 999px;
}

.aop-mobile-donate a:hover,
.aop-mobile-donate a:focus-visible {
	color: #1A1A1A;
	background: #B07F22;
}

/* kadence_mobile_main_header fires before the logo row, so without this the
   donate strip renders above the brand. Its parent is a plain block with only
   two children, so switching it to a column and ordering them is contained.
   Brand first, then the button, which becomes the bottom edge of the sticky
   header. */
@media (max-width: 1024px) {

	.site-mobile-header-wrap .site-header-upper-inner-wrap {
		display: flex;
		flex-direction: column;
	}

	.site-mobile-header-wrap .site-main-header-wrap {
		order: 1;
	}

	.site-mobile-header-wrap .aop-mobile-donate {
		order: 2;
	}
}

/* The legal links sit between the four columns and the theme's own copyright
   row, and are centred so they line up with it. There is deliberately no rule
   above them: .aop-footer already draws one below, and two hairlines a single
   row apart read as a box rather than as a separator. */
.aop-footer__legal {
	margin: 2.25rem 0 0;
}

.aop-footer__legal ul {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: .4rem 1.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* The padding here is for the thumb, not for the look. At .85rem these links
   render 16px tall, which clears WCAG 2.5.8 only through the spacing
   exception; the padding makes them comfortably tappable on a phone rather
   than merely conformant. Opacity matches the column links above so the two
   sets of footer links are the same shade. */
.aop-footer__legal a {
	display: inline-block;
	padding: .3rem 0;
	font-size: .85rem;
	text-decoration: none;
	opacity: .85;
}

.aop-footer__legal a:hover,
.aop-footer__legal a:focus-visible {
	opacity: 1;
	text-decoration: underline;
}

@media (max-width: 900px) {

	.aop-footer__inner {
		grid-template-columns: repeat(2, 1fr);
		gap: 2rem;
	}
}

@media (max-width: 600px) {

	.aop-footer {
		padding: 2.5rem 0 2rem;
	}

	.aop-footer__inner {
		grid-template-columns: 1fr;
		gap: 1.75rem;
	}

	.aop-footer__legal {
		margin-top: 1.75rem;
	}
}
