/* ==========================================================================
   Palm Estate - global components
   --------------------------------------------------------------------------
   Built once, used on every page. Mobile-first: the base rules are the small
   screen and min-width blocks build up from there. (Note the difference from
   section 08 of main.css, which steps the global tokens down at max-width.
   Tokens step down, components build up.)

   01 Header and primary nav
   02 Mobile nav overlay
   03 Buttons
   04 Form fields
   05 Footer
   06 Curved divider
   07 Page band
   08 Accordion
   ========================================================================== */


/* 01 Header and primary nav ================================================ */

/*
 * The sentinel is one viewport tall and sits at the top of the document. The
 * header observes it rather than listening to scroll, so nothing runs per
 * frame. It is inert: no size contribution, no pointer events, behind
 * everything.
 */
#page {
	position: relative;
}

.header-sentinel {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100vh;
	pointer-events: none;
	z-index: -1;
}

/*
 * The bar floats. The fixed wrapper is transparent, inset by the gutter and
 * offset from the top edge; the rounded inner container carries the border,
 * tint and fill. Over the hero the fill is a dark glass tint with the image
 * blurred through it; once the sentinel has left it becomes solid Forest.
 * The container keeps its shape in both states, so nothing jumps.
 */
.site-header {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	z-index: var(--z-header);
	padding: var(--header-offset) var(--gutter) 0;
	color: var(--pe-text-on-dark);
	pointer-events: none; /* positioning only; the bar itself takes clicks */
}

/* Without a hero the header is solid from the first paint, so the page needs
   to start below it. */
.no-hero #page {
	padding-top: calc(var(--header-h) + var(--header-offset));
}

.site-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-md);
	width: 100%;
	max-width: var(--header-w);
	height: var(--header-h);
	margin-inline: auto;
	padding-inline: var(--header-pad);
	pointer-events: auto;
	border: var(--hairline) solid var(--pe-rule-accent);
	border-radius: var(--radius-pill);
	transition: background-color var(--dur-base) var(--ease);
}

/* Over the hero: a slight dark tint with the image blurred through it. */
.site-header--overlay .site-header__inner {
	background-color: color-mix(in srgb, var(--pe-deep) 35%, transparent);
	-webkit-backdrop-filter: blur(var(--blur-glass));
	backdrop-filter: blur(var(--blur-glass));
}

/* Past the hero, and on every page without one: solid Forest. */
.site-header--solid .site-header__inner,
.site-header--overlay.is-solid .site-header__inner {
	background-color: var(--pe-bg-dark);
	-webkit-backdrop-filter: none;
	backdrop-filter: none;
}

/* ---- Wordmark ---- */

.wordmark {
	display: inline-flex;
	align-items: center;
	color: inherit;
	text-decoration: none;
}

.wordmark__text {
	font-family: var(--font-body);
	font-size: var(--fs-sm);
	font-weight: 500;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
	white-space: nowrap;
}

.wordmark img {
	max-height: calc(var(--header-h) - var(--space-lg));
	width: auto;
}

/* ---- Desktop menu ---- */

/* Hidden on small screens: the overlay carries navigation there. */
.site-header__nav {
	display: none;
}

.nav-menu {
	display: flex;
	align-items: center;
	gap: var(--space-xl);
	margin: 0;
	padding: 0;
	list-style: none;
}

.nav-menu a {
	position: relative;
	display: inline-block;
	padding-block: var(--space-2xs);
	color: inherit;
	font-size: var(--fs-xs);
	font-weight: 400;
	letter-spacing: var(--ls-wide);
	text-decoration: none;
	text-transform: uppercase;
}

/* Bronze rule that grows from the centre on hover. */
.nav-menu a::after {
	content: "";
	position: absolute;
	bottom: 0;
	left: 50%;
	width: 0;
	height: var(--hairline);
	background-color: var(--pe-accent);
	transform: translateX(-50%);
	transition: width var(--dur-base) var(--ease);
}

.nav-menu a:hover::after,
.nav-menu a:focus-visible::after,
.nav-menu .current-menu-item > a::after {
	width: 100%;
}

.site-header__actions {
	display: flex;
	align-items: center;
	gap: var(--space-sm);
}

/* The pill is a desktop affordance; the overlay carries its own CTA. Its
   type is one step under the button default, as in the design. */
.site-header__cta {
	display: none;
	font-size: var(--fs-3xs);
}

/* ---- Toggle ---- */

.nav-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	padding: 0;
	color: inherit;
	background: none;
	border: var(--hairline) solid var(--pe-rule-on-dark);
	border-radius: var(--radius-pill);
	cursor: pointer;
	transition: border-color var(--dur-fast) var(--ease);
}

.nav-toggle:hover {
	border-color: var(--pe-accent);
}

.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
	display: block;
	width: 1.05rem;
	height: 1px;
	background-color: currentColor;
	content: "";
}

.nav-toggle__bars::before {
	transform: translateY(-5px);
}

.nav-toggle__bars::after {
	transform: translateY(4px);
}

@media (min-width: 1024px) {
	.site-header__nav {
		display: block;
	}

	.site-header__cta {
		display: inline-flex;
	}

	.nav-toggle {
		display: none;
	}
}


/* 02 Mobile nav overlay ==================================================== */

.mobile-nav {
	position: fixed;
	inset: 0;
	z-index: var(--z-nav);
	background-color: var(--pe-bg-dark);
	color: var(--pe-text-on-dark);
	opacity: 0;
	transition: opacity var(--dur-base) var(--ease);
}

/* JS removes [hidden] first, then adds .is-open on the next frame so the
   transition has a starting state to move from. */
.mobile-nav.is-open {
	opacity: 1;
}

.mobile-nav__inner {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: center;
	gap: var(--space-xl);
	height: 100%;
	padding: var(--space-2xl) var(--gutter);
}

.mobile-nav__close {
	position: absolute;
	top: 0;
	right: var(--gutter);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: var(--header-h);
	color: inherit;
	font-size: var(--fs-xl);
	line-height: 1;
	background: none;
	border: 0;
	cursor: pointer;
}

.mobile-nav__menu {
	display: flex;
	flex-direction: column;
	gap: var(--space-md);
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
}

.mobile-nav__menu a {
	display: block;
	color: inherit;
	font-family: var(--font-display);
	font-size: var(--fs-2xl);
	letter-spacing: var(--ls-tight);
	text-decoration: none;
}

.mobile-nav__menu a:hover,
.mobile-nav__menu a:focus-visible {
	color: var(--pe-accent);
}

/* Staggered entrance. Each item starts low and faded and is released in turn
   once the overlay is open. Under prefers-reduced-motion the global rule in
   main.css collapses the duration, so items simply appear. */
.mobile-nav__menu li,
.mobile-nav__cta {
	opacity: 0;
	transform: translateY(0.75rem);
	transition:
		opacity var(--dur-base) var(--ease-out),
		transform var(--dur-base) var(--ease-out);
}

.mobile-nav.is-open .mobile-nav__menu li,
.mobile-nav.is-open .mobile-nav__cta {
	opacity: 1;
	transform: translateY(0);
}

.mobile-nav.is-open .mobile-nav__menu li:nth-child(1) { transition-delay: 80ms; }
.mobile-nav.is-open .mobile-nav__menu li:nth-child(2) { transition-delay: 130ms; }
.mobile-nav.is-open .mobile-nav__menu li:nth-child(3) { transition-delay: 180ms; }
.mobile-nav.is-open .mobile-nav__menu li:nth-child(4) { transition-delay: 230ms; }
.mobile-nav.is-open .mobile-nav__menu li:nth-child(5) { transition-delay: 280ms; }
.mobile-nav.is-open .mobile-nav__menu li:nth-child(6) { transition-delay: 330ms; }
.mobile-nav.is-open .mobile-nav__cta { transition-delay: 380ms; }

/* Scroll lock. Applied to <body> while the overlay is open. */
.nav-open {
	overflow: hidden;
}


/* 03 Buttons =============================================================== */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2xs);
	padding: var(--space-xs) var(--space-md);
	font-family: var(--font-body);
	font-size: var(--fs-2xs);
	font-weight: 500;
	letter-spacing: var(--ls-caps);
	line-height: 1;
	text-align: center;
	text-transform: uppercase;
	text-decoration: none;
	border: var(--hairline) solid transparent;
	cursor: pointer;
	transition:
		background-color var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease),
		color var(--dur-fast) var(--ease);
}

.btn--pill {
	border-radius: var(--radius-pill);
}

/* Outlined. Cream text means this belongs on a dark ground; use
   .btn--outline-ink on Cream. */
.btn--outline {
	background-color: transparent;
	border-color: var(--pe-accent);
	color: var(--pe-text-on-dark);
}

.btn--outline:hover {
	background-color: var(--pe-accent);
	color: var(--pe-text-on-accent);
}

.btn--outline-ink {
	background-color: transparent;
	border-color: var(--pe-accent);
	color: var(--pe-text);
}

.btn--outline-ink:hover {
	background-color: var(--pe-accent);
	color: var(--pe-text-on-accent);
}

/* Filled. */
.btn--filled {
	background-color: var(--pe-accent);
	border-color: var(--pe-accent);
	color: var(--pe-text-on-accent);
}

.btn--filled:hover {
	background-color: color-mix(in srgb, var(--pe-accent) 82%, var(--pe-ink));
	border-color: color-mix(in srgb, var(--pe-accent) 82%, var(--pe-ink));
}

/* Cream fill, Ink text: the nav pill. Warms slightly toward Bronze on hover. */
.btn--cream {
	background-color: var(--pe-cream);
	border-color: var(--pe-cream);
	color: var(--pe-ink);
}

.btn--cream:hover {
	background-color: color-mix(in srgb, var(--pe-cream) 85%, var(--pe-bronze));
	border-color: color-mix(in srgb, var(--pe-cream) 85%, var(--pe-bronze));
}

/* Focus is not left to hover. The offset ring reads on both grounds. */
.btn:focus-visible {
	outline: 2px solid var(--pe-accent);
	outline-offset: 3px;
}

.btn--filled:focus-visible {
	outline-color: var(--pe-text-on-dark);
}

.btn[disabled],
.btn[aria-disabled="true"] {
	opacity: 0.5;
	cursor: not-allowed;
}

/* Arrow that shifts on hover, for the hero CTA in Phase 03. */
.btn__arrow {
	transition: transform var(--dur-fast) var(--ease);
}

.btn:hover .btn__arrow {
	transform: translateX(0.25rem);
}


/* 04 Form fields =========================================================== */

/*
 * No boxes anywhere: a Bronze label above a hairline underline. The control is
 * transparent so the field takes the colour of whatever section it sits in.
 * Built in Phase 02; first used by the Phase 08 contact form and the listings
 * filter bar, which is where the states below were settled.
 *
 *   .field > .field__label + (.field__input | .field__textarea) + .field__error
 *   .field > .field__label + .field__select-wrap > .field__select
 *   .fieldset > legend.field__label + .choices > (.choice__input + .choice)*
 *
 * Measured on Forest, the dark ground these sit on today:
 *   label, focused underline   Bronze                   7.45:1
 *   resting underline          --pe-accent-quiet        3.17:1  (needs 3:1)
 *   error message              --pe-error-on-dark       5.08:1
 *   error underline            --pe-error               3.40:1  (needs 3:1)
 *   "Optional"                 --pe-text-muted-on-dark  6.12:1
 *   selected choice            Ink on Bronze            6.73:1
 * The labels, message and "Optional" colours assume a dark ground; a field on
 * Cream would need its own measured set.
 *
 * Invalid state is driven by aria-invalid="true" on the control (or on the
 * fieldset), which assistive technology needs anyway, so the style can never
 * disagree with what a screen reader is told. Messages use the hidden
 * attribute; the script that validates shows and hides them.
 */
.field {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
}

.field__label {
	font-family: var(--font-body);
	font-size: var(--fs-2xs);
	font-weight: 500;
	letter-spacing: var(--ls-caps);
	line-height: var(--lh-snug);
	text-transform: uppercase;
	color: var(--pe-accent);
}

.field__optional {
	margin-left: var(--space-2xs);
	color: var(--pe-text-muted-on-dark);
}

.field__input,
.field__textarea,
.field__select {
	display: block;
	width: 100%;
	padding: var(--space-2xs) 0;
	color: inherit;
	font-family: var(--font-body);
	font-size: var(--fs-base); /* 16px or larger, or iOS zooms in on focus */
	line-height: var(--lh-snug);
	background-color: transparent;
	border: 0;
	border-bottom: var(--hairline) solid var(--pe-accent-quiet);
	border-radius: 0;
	transition:
		border-color var(--dur-fast) var(--ease),
		box-shadow var(--dur-fast) var(--ease);
	-webkit-appearance: none;
	appearance: none;
}

.field__textarea {
	min-height: 6rem;
	resize: vertical;
}

.field__input::placeholder,
.field__textarea::placeholder {
	color: currentColor;
	opacity: 0.45;
}

/*
 * Focus brightens the underline and doubles it with a shadow (no layout
 * shift), and that IS the focus indicator: no ring. Text controls match
 * :focus-visible on a mouse click as well as from the keyboard, so a ring here
 * would draw a box around every field anyone clicked into.
 */
.field__input:focus,
.field__textarea:focus,
.field__select:focus,
.field__input:focus-visible,
.field__textarea:focus-visible,
.field__select:focus-visible {
	outline: none;
	border-bottom-color: var(--pe-accent);
	box-shadow: 0 var(--hairline) 0 0 var(--pe-accent);
}

/* Browser autofill paints its own pale fill, which on a dark ground looks
   broken. An inset shadow as large as the field covers it. */
.field__input:-webkit-autofill {
	-webkit-text-fill-color: var(--pe-text-on-dark);
	caret-color: var(--pe-text-on-dark);
	box-shadow: inset 0 0 0 100vmax var(--pe-bg-dark);
}

.field__input:-webkit-autofill:focus {
	box-shadow:
		inset 0 0 0 100vmax var(--pe-bg-dark),
		0 var(--hairline) 0 0 var(--pe-accent);
}

/* ---- Selects ---- */

/* A <select> cannot hold a pseudo-element, so the chevron lives on a wrapper
   and is drawn with borders to take the token colour. The open list is painted
   by the operating system, which on Windows reuses the colours of the select
   itself - transparent and Cream would be Cream on white - so the options get
   a solid ground. */
.field__select-wrap {
	position: relative;
}

.field__select {
	padding-right: var(--space-lg);
	cursor: pointer;
}

.field__select-wrap::after {
	content: "";
	position: absolute;
	top: 50%;
	right: var(--space-3xs);
	width: 0.4rem;
	height: 0.4rem;
	border-right: var(--hairline) solid var(--pe-accent);
	border-bottom: var(--hairline) solid var(--pe-accent);
	pointer-events: none;
	transform: translateY(-75%) rotate(45deg);
}

.field__select option {
	background-color: var(--pe-bg-dark);
	color: var(--pe-text-on-dark);
}

/* ---- Error state ---- */

.field__input[aria-invalid="true"],
.field__textarea[aria-invalid="true"],
.field__select[aria-invalid="true"] {
	border-bottom-color: var(--pe-error);
}

.field__input[aria-invalid="true"]:focus,
.field__textarea[aria-invalid="true"]:focus,
.field__select[aria-invalid="true"]:focus {
	border-bottom-color: var(--pe-error);
	box-shadow: 0 var(--hairline) 0 0 var(--pe-error);
}

.field__error {
	color: var(--pe-error-on-dark);
	font-size: var(--fs-sm);
	line-height: var(--lh-snug);
}

.field__hint {
	font-size: var(--fs-xs);
	opacity: 0.7;
}

/* ---- Choice boxes: intent toggles, sale or rent ---- */

/*
 * Real radio buttons drawn as boxes: single choice, arrow keys move between
 * them, no script needed. The radio itself is visually hidden and the label is
 * the box. Square corners - boxes, not pills.
 */
.fieldset {
	min-width: 0;
	border: 0;
}

/* Two columns on a phone and four from sm up by default; a group with a
   different number of options sets --choices-cols and --choices-cols-wide.
   Positioned so the hidden radios stay in place when focused and the page
   does not jump to wherever they would otherwise sit. */
.choices {
	position: relative;
	display: grid;
	grid-template-columns: repeat(var(--choices-cols, 2), 1fr);
	gap: var(--space-xs);
	margin-top: var(--space-sm);
}

@media (min-width: 480px) {
	.choices {
		grid-template-columns: repeat(var(--choices-cols-wide, 4), 1fr);
	}
}

.choice {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 2.75rem; /* 44px tap target */
	padding: var(--space-xs) var(--space-sm);
	border: var(--hairline) solid var(--pe-accent);
	color: var(--pe-text-on-dark);
	cursor: pointer;
	user-select: none;
	transition:
		background-color var(--dur-fast) var(--ease),
		color var(--dur-fast) var(--ease);
}

.choice:hover {
	background-color: color-mix(in srgb, var(--pe-bronze) 12%, transparent);
}

.choice__input:checked + .choice {
	background-color: var(--pe-accent);
	color: var(--pe-text-on-accent);
}

/* The radio is hidden, so its focus ring goes on the box. */
.choice__input:focus-visible + .choice {
	outline: 2px solid var(--pe-accent);
	outline-offset: 3px;
}

.fieldset[aria-invalid="true"] .choice {
	border-color: var(--pe-error);
}

/* A .field spaces its message with a flex gap; a fieldset has none. */
.fieldset > .field__error {
	margin-top: var(--space-2xs);
}

/* Windows high contrast drops background colours, which would make the
   selected box indistinguishable. A thick outline survives. */
@media (forced-colors: active) {
	.choice__input:checked + .choice {
		outline: 3px solid CanvasText;
		outline-offset: -5px;
	}
}


/* 05 Footer ================================================================ */

/*
 * Deep ground, one step darker than the Forest section above it, with that
 * section's colour arcing down into it from the divider at the top.
 *
 * The ground is the client's texture file, drawn over a Deep fill so the
 * colour is right before the file arrives and at any edge it does not cover.
 * The file is served as delivered, per the no-compression decision.
 *
 * It is shaded, though. As delivered the texture averages #162C22, lighter
 * than the Forest above it (luminance 0.0209 against 0.0125), and even its
 * darkest pixel is lighter than Forest - so it hid the Deep ground completely
 * and the arc read as dropping into something paler, not darker. Multiplying
 * it by --footer-shade brings its average to Deep (0.0064 against 0.0066).
 * Multiply scales every pixel by the same factor, so the mottling keeps its
 * relative strength rather than being washed out, as a flat overlay would do.
 */
.site-footer {
	--footer-shade: color-mix(in srgb, var(--pe-cream) 45%, var(--pe-deep));

	position: relative;
	color: var(--pe-text-on-dark);
	background-color: var(--pe-bg-darkest);
	background-image:
		linear-gradient(var(--footer-shade), var(--footer-shade)),
		url("../images/footer-texture.png");
	background-blend-mode: multiply, normal;
	background-size: cover;
	background-position: center;
}

/* The arc and the content both sit above the ground by DOM order. */
.site-footer__inner {
	position: relative;
	z-index: 2;
	padding-block: var(--space-2xl) var(--space-lg);
}

/* Mark, wordmark, tagline ------------------------------------------------- */

.site-footer__mark {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}

.site-footer__mark .palm-mark {
	width: 4.375rem; /* ~70px */
	height: auto;
	color: var(--pe-accent);
}

.site-footer__name {
	margin-top: var(--space-md);
	max-width: none;
	color: var(--pe-text-on-dark);
	font-size: var(--fs-md);
	font-weight: 400;
	line-height: var(--lh-snug);
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
}

.site-footer__tagline {
	margin-top: var(--space-xs);
	color: var(--pe-accent);
}

/* Columns ----------------------------------------------------------------- */

.site-footer__columns {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-xl);
	margin-top: var(--space-3xl);
}

.site-footer__heading {
	margin-bottom: var(--space-md);
}

.site-footer__address {
	font-style: normal;
	font-size: var(--fs-sm);
	line-height: var(--lh-loose);
	color: color-mix(in srgb, var(--pe-cream) 82%, transparent);
}

.site-footer__menu {
	display: flex;
	flex-direction: column;
	gap: var(--space-xs);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Links are Cream at reduced opacity, normal case. Mixed to transparent
   rather than using opacity so the focus ring stays at full strength. */
.site-footer__menu a {
	color: color-mix(in srgb, var(--pe-cream) 78%, transparent);
	font-size: var(--fs-sm);
	text-decoration: none;
	transition: color var(--dur-fast) var(--ease);
}

.site-footer__menu a:hover,
.site-footer__menu a:focus-visible {
	color: var(--pe-accent);
}

/* Legal row --------------------------------------------------------------- */

.site-footer__legal {
	display: flex;
	flex-direction: column;
	gap: var(--space-sm);
	margin-top: var(--space-2xl);
	padding-top: var(--space-md);
	border-top: var(--hairline) solid var(--pe-rule-accent);
	font-size: var(--fs-xs);
	color: color-mix(in srgb, var(--pe-cream) 60%, transparent);
}

.site-footer__copyright {
	margin: 0;
	max-width: none;
}

.site-footer__legal-menu {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-md);
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-footer__legal-menu a {
	color: inherit;
	text-decoration: none;
	transition: color var(--dur-fast) var(--ease);
}

.site-footer__legal-menu a:hover,
.site-footer__legal-menu a:focus-visible {
	color: var(--pe-accent);
}

@media (min-width: 768px) {
	.site-footer__columns {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.site-footer__columns {
		grid-template-columns: repeat(4, 1fr);
	}

	.site-footer__legal {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
	}
}


/* 06 Curved divider ======================================================== */

/*
 * The arc carries the colour of the section it belongs to. An "up" divider is
 * placed at the top of its section and bows up over whatever is above it; a
 * "down" divider sits at the top of the next section and bows down into it.
 *
 * The path fills its whole box, so the box height is the depth of the curve.
 * The 1px negative margins overlap the neighbouring section to hide the
 * sub-pixel seam that otherwise shows at some zoom levels.
 */
.divider {
	--divider-h: clamp(2.5rem, 5vw, 5rem);

	position: relative;
	width: 100%;
	line-height: 0;
	pointer-events: none;
}

.divider--sm { --divider-h: clamp(1.5rem, 3vw, 2.5rem); }
/* Only the arc at the foot of the journey is lg. It spans the full window
   while every other arc sits over a measure-width block, so it needs a much
   deeper curve to read as one at all: the old 8.75rem cap left it a near
   straight line on anything wider than a laptop. */
.divider--lg { --divider-h: clamp(4.5rem, 10vw, 12rem); }

.divider svg {
	display: block;
	width: 100%;
	height: var(--divider-h);
}

/*
 * An "up" divider belongs to the section below it and arcs up over the one
 * above: its dome overlays the previous section while its flat bottom edge
 * meets this section's ground.
 *
 * It is lifted with `top`, not a negative margin. A negative top margin on a
 * first child collapses out to the parent unless the parent happens to have
 * padding, a border or its own formatting context - and when it collapses,
 * the whole section moves up instead and the dome is drawn on its own
 * background, invisible. `top` shifts only the rendering; the negative bottom
 * margin then reclaims the layout space, so the section itself does not move
 * whatever the parent looks like.
 */
.divider--up {
	top: calc(-1 * var(--divider-h));
	margin-bottom: calc(-1 * var(--divider-h));
}

/* A "down" divider sits at the top of its own section and bulges down into
   it, so it needs no overlap. */
.divider--down {
	margin-top: -1px;
}

/* fill="currentColor" on the path, so colour is set here. */
.divider--cream  { color: var(--pe-cream); }
.divider--forest { color: var(--pe-forest); }
.divider--pine   { color: var(--pe-pine); }
.divider--deep   { color: var(--pe-deep); }


/* 07 Page band ============================================================= */

/*
 * The Forest band an inner page opens with: eyebrow, title, and whatever the
 * page needs up top (the listings filters). A Forest divider usually follows,
 * bowing down into the Cream section beneath.
 *
 * The band starts at the very top of the page, behind the floating header, so
 * the header sits on Forest rather than on a strip of Cream. A template that
 * uses it adds the has-page-band body class (functions.php), which drops the
 * header clearance that .no-hero #page otherwise adds, and the band takes that
 * clearance into its own padding instead.
 */
.has-page-band #page {
	padding-top: 0;
}

.page-band {
	/*
	 * The band's ground is the footer's: the paper texture under a Cream
	 * shade multiplied over it, on Forest rather than Deep, so the dark ends
	 * of every page share one surface. And the band draws its own arc into
	 * the section beneath: the ground is masked to the divider part's "down"
	 * dome (the same path, stretched to the width), rather than a second,
	 * flat-Forest arc drawn under it, which met this ground in a visible
	 * line. A band that runs straight into another Forest section takes
	 * .page-band--flush and keeps a plain ground with no arc.
	 */
	--band-shade: color-mix(in srgb, var(--pe-cream) 45%, var(--pe-forest));
	--band-arc-h: clamp(2.5rem, 5vw, 5rem);

	background-color: var(--pe-bg-dark);
	background-image:
		linear-gradient(var(--band-shade), var(--band-shade)),
		url("../images/footer-texture.png");
	background-blend-mode: multiply, normal;
	background-size: cover;
	background-position: center;
	color: var(--pe-text-on-dark);
	padding-top: calc(var(--header-h) + var(--header-offset) + var(--space-2xl));
	padding-bottom: calc(var(--space-lg) + var(--band-arc-h));
	-webkit-mask-image:
		linear-gradient(#000, #000),
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 80' preserveAspectRatio='none'%3E%3Cpath d='M0,0 C480,106.7 960,106.7 1440,0 Z'/%3E%3C/svg%3E");
	mask-image:
		linear-gradient(#000, #000),
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 80' preserveAspectRatio='none'%3E%3Cpath d='M0,0 C480,106.7 960,106.7 1440,0 Z'/%3E%3C/svg%3E");
	-webkit-mask-size: 100% calc(100% - var(--band-arc-h) + 1px), 100% var(--band-arc-h);
	mask-size: 100% calc(100% - var(--band-arc-h) + 1px), 100% var(--band-arc-h);
	-webkit-mask-position: top, bottom;
	mask-position: top, bottom;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
}

.page-band--flush {
	padding-bottom: var(--space-lg);
	background-image: none;
	-webkit-mask-image: none;
	mask-image: none;
}

.page-band__eyebrow {
	margin-bottom: var(--space-sm);
}

.page-band__title {
	font-size: var(--fs-3xl);
	line-height: var(--lh-tight);
}

/* A line beneath the title, for pages that open with one. */
.page-band__lead {
	margin-top: var(--space-md);
	max-width: var(--measure-narrow);
	color: color-mix(in srgb, var(--pe-cream) 80%, transparent);
	font-size: var(--fs-md);
	line-height: var(--lh-loose);
	text-wrap: pretty;
}


/* 08 Accordion ============================================================= */

/*
 * One answer open at a time (assets/js/faq.js): the FAQ page's groups and the
 * homepage's FAQ block share it. The height eases through a grid-row
 * transition, which is the one way to animate to an unknown height in CSS
 * alone. Without the script every answer shows (a noscript style in the
 * templates), so it is never a row of buttons that do nothing.
 */

.accordion {
	margin-top: var(--space-lg);
	border-top: var(--hairline) solid var(--pe-rule);
}

.accordion__item {
	border-bottom: var(--hairline) solid var(--pe-rule);
	/* A linked-to question (#faq-buy-2) lands clear of the floating header
	   rather than against its edge; the header itself is already allowed for
	   by scroll-padding-top on the root. */
	scroll-margin-top: var(--space-lg);
}

/* The heading is only there for structure; the button carries the type. */
.accordion__heading {
	margin: 0;
	font-size: inherit;
	line-height: inherit;
}

.accordion__trigger {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--space-md);
	width: 100%;
	padding: var(--space-md) 0;
	color: var(--pe-text);
	font-family: var(--font-display);
	font-size: var(--fs-lg);
	line-height: var(--lh-snug);
	text-align: left;
	background: none;
	border: 0;
	cursor: pointer;
}

.accordion__trigger:hover .accordion__question {
	color: var(--pe-accent-on-light);
}

/* The global Bronze ring is 2:1 on Cream; the darkened Bronze passes. */
.accordion__trigger:focus-visible {
	outline: 2px solid var(--pe-accent-on-light);
	outline-offset: 2px;
}

.accordion__question {
	transition: color var(--dur-fast) var(--ease);
}

/*
 * The plus: two Bronze hairlines. Opening turns the upright one a quarter
 * turn onto the crossbar, leaving a minus. Decoration, so pure Bronze.
 */
.accordion__icon {
	position: relative;
	flex: none;
	width: 0.875rem;
	height: 0.875rem;
	margin-top: 0.3em;
}

.accordion__icon::before,
.accordion__icon::after {
	content: "";
	position: absolute;
	background-color: var(--pe-accent);
	transition: transform var(--dur-base) var(--ease);
}

.accordion__icon::before {
	top: 50%;
	left: 0;
	width: 100%;
	height: var(--hairline);
	transform: translateY(-50%);
}

.accordion__icon::after {
	top: 0;
	left: 50%;
	width: var(--hairline);
	height: 100%;
	transform: translateX(-50%);
}

.accordion__item.is-open .accordion__icon::after {
	transform: translateX(-50%) rotate(90deg);
}

/*
 * The panel is a one-row grid whose row goes from 0fr to 1fr: the browser
 * works out the height, so the answer can be any length. Closed, it is also
 * visibility: hidden - after the row has finished closing, and immediately
 * on opening - so a closed answer is out of the tab order and the
 * accessibility tree, not just out of sight.
 */
.accordion__panel {
	display: grid;
	grid-template-rows: 0fr;
	visibility: hidden;
	transition:
		grid-template-rows var(--dur-base) var(--ease),
		visibility 0s linear var(--dur-base);
}

.accordion__item.is-open .accordion__panel {
	grid-template-rows: 1fr;
	visibility: visible;
	transition:
		grid-template-rows var(--dur-base) var(--ease),
		visibility 0s;
}

.accordion__body {
	min-height: 0;
	overflow: hidden;
}

.accordion__answer {
	max-width: var(--measure);
	padding-bottom: var(--space-lg);
	color: var(--pe-text-muted);
	line-height: var(--lh-loose);
}

/* The global rule shortens durations but leaves the visibility delay, which
   would hide a closing answer a third of a second late. No transition at all. */
@media (prefers-reduced-motion: reduce) {
	.accordion__panel,
	.accordion__icon::before,
	.accordion__icon::after {
		transition: none;
	}
}

/* Numbered: a small Bronze ordinal before each question, drawn by a
   counter so the items renumber themselves. */
.accordion--numbered {
	counter-reset: faq;
}

.accordion--numbered .accordion__trigger {
	counter-increment: faq;
}

.accordion--numbered .accordion__trigger::before {
	content: counter(faq, decimal-leading-zero);
	flex: none;
	width: 2.25rem;
	margin-top: 0.45em;
	color: var(--pe-accent-on-light);
	font-family: var(--font-body);
	font-size: var(--fs-3xs);
	font-weight: 500;
	letter-spacing: var(--ls-caps);
	line-height: 1;
}

.accordion--numbered .accordion__question {
	flex: 1;
}

.accordion--numbered .accordion__answer {
	margin-left: 2.25rem;
}

