/*
 * APOD Communication Preferences — front-end styles.
 *
 * Palette and type are taken from the live APOD theme (Hello Elementor + Elementor Pro),
 * read from its global kit rather than sampled from the mock-up:
 *
 *   --e-global-color-primary   #2F2A95   navy / indigo   → headings, brand accents
 *   --e-global-color-secondary #BA0C2F   APOD red        → destructive treatment
 *   --e-global-color-text      #97999B   body grey       → descriptions
 *   bright blue                #489FDF   theme accent    → decorative accents
 *   Gotham Bold / Gotham Book                            → headings / body
 *
 * The one deliberate departure: interactive blue is #1B6CB8 rather than the theme's #489FDF.
 * White text on #489FDF is 2.6:1, which fails WCAG AA; #1B6CB8 keeps the same bright-blue
 * character at 5.6:1. #489FDF is still used where it is decorative only.
 *
 * Everything is namespaced under .apod-cp so nothing here can affect the rest of the theme —
 * and every rule is ALSO scoped under it (`.apod-cp .apod-cp-hero__title`) rather than written
 * bare. That is not stylistic: Elementor's kit emits `.elementor-kit-10 h1` at specificity
 * (0,1,1), which outranks a single class (0,1,0) and loads after this file, so bare selectors
 * lose every heading colour and size to the theme. Rooting them takes each rule to (0,2,0) and
 * wins cleanly, without a single !important.
 *
 * Keep new rules rooted the same way.
 */

.apod-cp {
	/* Palette */
	--apod-cp-navy: #2f2a95;
	--apod-cp-navy-deep: #1d1a63;
	--apod-cp-blue: #1b6cb8;
	--apod-cp-blue-hover: #14548f;
	--apod-cp-blue-bright: #489fdf;
	--apod-cp-red: #ba0c2f;
	--apod-cp-red-hover: #970a26;
	--apod-cp-ink: #1a1a1f;
	--apod-cp-muted: #5c5f66;
	--apod-cp-grey: #97999b;
	--apod-cp-line: #dfe4ec;
	--apod-cp-card: #f4f8fd;
	--apod-cp-card-border: #e4ecf7;
	--apod-cp-page: #ffffff;
	--apod-cp-success-bg: #e8f6ee;
	--apod-cp-success-ink: #12633a;
	--apod-cp-warn-bg: #fdf3e6;
	--apod-cp-warn-ink: #7a4a05;
	--apod-cp-error-bg: #fdecef;

	/* Type */
	--apod-cp-font-heading: "Gotham Bold", "Gotham", "Helvetica Neue", Arial, sans-serif;
	--apod-cp-font-body: "Gotham Book", "Gotham", "Helvetica Neue", Arial, sans-serif;

	/* Layout — 1328px matches the theme's --container-max-width */
	--apod-cp-max: 720px;
	/* The APOD Elementor kit's container width. The cards track the site header rather than
	   the hero's narrower measure, so they start level with the logo and end level with the
	   last header item, and never run past either. */
	--apod-cp-content-max: 1328px;
	--apod-cp-radius: 14px;
	--apod-cp-gutter: 24px;

	font-family: var(--apod-cp-font-body);
	color: var(--apod-cp-ink);
	background: var(--apod-cp-page);
	line-height: 1.6;
	font-size: 16px;
	-webkit-font-smoothing: antialiased;
}

/*
 * Clips the few pixels the full-bleed hero overshoots by, because vw units include the
 * scrollbar. `clip` rather than `hidden`: hidden would make this a scroll container, which
 * would break the sticky save bar; clip does not.
 */
.apod-cp {
	overflow-x: clip;
}

.apod-cp *,
.apod-cp *::before,
.apod-cp *::after {
	box-sizing: border-box;
}

.apod-cp .apod-cp-sr-only {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ─────────────────────────────  Hero  ───────────────────────────── */

.apod-cp .apod-cp-hero {
	/*
	 * Track the banner's own proportions instead of letting the text alone set the height.
	 *
	 * APOD's banner is 2048x517 — very nearly 4:1 — and it is a composition, not a texture: a
	 * figure centred against a sunset. Sized only by its padding it came out around 210px on a
	 * desktop where showing the image whole needs about 645px, so `cover` sliced two thirds
	 * off and cut through the subject's head.
	 *
	 * 25vw is that 4:1 ratio. The floor keeps the heading readable on a phone, where a
	 * proportional hero would be too short to sit text in; the cap stops it dominating a large
	 * monitor, which is what the redesign was reacting to in the first place.
	 */
	min-height: clamp(170px, 25vw, 520px);
	/*
	 * Break out of the page builder's container. Elementor wraps page content in
	 * .e-con-inner at max-width 1328px with auto margins, which boxes the banner instead of
	 * letting it run edge to edge. Negative margins of (50% - 50vw) with width:auto expand it
	 * to the viewport.
	 *
	 * vw units include the scrollbar, so on any browser that reserves space for one this
	 * overshoots by half the scrollbar width on each side and the page grows its own
	 * horizontal scrollbar. `max-width: 100vw` used to sit here as a guard and did nothing at
	 * all, being the same scrollbar-inclusive unit. The overshoot is clipped on .apod-cp
	 * instead, which is the only reliable fix without knowing the scrollbar width.
	 */
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
	width: auto;
	position: relative;
	display: flex;
	align-items: center;
	padding: 40px var(--apod-cp-gutter);
	background-color: var(--apod-cp-navy-deep);
	background-image: var(--apod-cp-hero-image);
	background-size: cover;
	background-position: center 42%;
	background-repeat: no-repeat;
	overflow: hidden;
}

/* Fallback when no hero image is configured: an APOD-branded gradient, so the page never
   depends on a third-party image and never renders a broken banner. */
.apod-cp .apod-cp-hero--fallback {
	background-image:
		radial-gradient(120% 140% at 82% 18%, rgba(72, 159, 223, 0.55) 0%, rgba(72, 159, 223, 0) 58%),
		linear-gradient(105deg, #10123a 0%, #2f2a95 58%, #1b6cb8 100%);
}

.apod-cp .apod-cp-hero__scrim {
	position: absolute;
	inset: 0;
	/* Guarantees the AA contrast of the hero text over any photograph the admin chooses. */
	background: linear-gradient(90deg, rgba(8, 10, 30, 0.86) 0%, rgba(8, 10, 30, 0.62) 46%, rgba(8, 10, 30, 0.2) 100%);
}

.apod-cp .apod-cp-hero--fallback .apod-cp-hero__scrim {
	background: linear-gradient(90deg, rgba(8, 10, 30, 0.5) 0%, rgba(8, 10, 30, 0.1) 70%);
}

.apod-cp .apod-cp-hero__inner {
	position: relative;
	width: 100%;
	/*
	 * min() rather than the token alone. The hero breaks out of the page builder's container
	 * with negative margins, so its own width depends on whatever that container happens to
	 * be — and inside an email client's in-app browser that is not always what a normal
	 * browser reports. If the container is ever narrower than the hero believes, a fixed
	 * max-width lets this block run wider than the banner and the heading is clipped at both
	 * edges. Capping at 100% of the hero makes that impossible whatever the container does.
	 */
	max-width: min(var(--apod-cp-max), 100%);
	margin: 0 auto;
	min-width: 0;
}

/* Belt and braces for the same failure: long words break rather than push the block wider. */
.apod-cp .apod-cp-hero__title,
.apod-cp .apod-cp-hero__lede {
	max-width: 100%;
	overflow-wrap: break-word;
}

.apod-cp .apod-cp-hero__title {
	margin: 0 0 16px;
	/*
	 * Wide enough for the longest line anyone is likely to configure — 22ch fitted the
	 * original "email preferences" and nothing longer, so "communication preferences" (24
	 * characters) wrapped and turned a two-line heading into three. Still narrow enough to
	 * keep the measure short if someone pastes a sentence in.
	 */
	max-width: 28ch;
	font-family: var(--apod-cp-font-heading);
	font-weight: 700;
	font-size: clamp(1.6rem, 1.15rem + 1.6vw, 2.35rem);
	line-height: 1.12;
	letter-spacing: -0.01em;
	text-wrap: balance;
	color: #ffffff;
}

/* Each half of the heading on its own line above the mobile breakpoint. */
.apod-cp .apod-cp-hero__line {
	display: block;
}

/*
 * WordPress content filters (wpautop, and page builders that run their own) turn newlines in
 * shortcode output into <br>. The markup now has no newline to convert, but a stray break
 * here would silently add an empty line to the heading, so it is neutralised either way.
 */
.apod-cp .apod-cp-hero__title br {
	display: none;
}

.apod-cp .apod-cp-hero__lede {
	margin: 0;
	max-width: 44ch;
	font-size: clamp(1rem, 0.94rem + 0.28vw, 1.15rem);
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.94);
}

.apod-cp .apod-cp-hero__motto {
	position: absolute;
	right: max(var(--apod-cp-gutter), calc(50% - (var(--apod-cp-max) / 2)));
	bottom: 56px;
	display: flex;
	flex-direction: column;
	gap: 2px;
	margin: 0;
	padding-bottom: 14px;
	font-family: var(--apod-cp-font-heading);
	font-size: 0.95rem;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.92);
	/* The motto sits over whatever photograph the admin chooses, so it carries its own
	   shadow rather than relying on the scrim, which is weakest on the right. */
	text-shadow: 0 1px 6px rgba(0, 0, 0, 0.75);
	border-bottom: 2px solid rgba(255, 255, 255, 0.8);
}

@media (max-width: 1023px) {
	.apod-cp .apod-cp-hero__motto {
		display: none;
	}
}

/* ────────────────────────  Layout & panels  ────────────────────── */

.apod-cp .apod-cp-shell {
	max-width: var(--apod-cp-content-max);
	margin: 0 auto;
	padding: 32px var(--apod-cp-gutter) 40px;
}

/*
 * While the bar is sticky it floats over the end of the form, so the form needs room to scroll
 * clear of it. Without this the final row can never be brought fully into view.
 */
.apod-cp--has-unsaved-changes .apod-cp-form {
	scroll-padding-bottom: 96px;
}

.apod-cp .apod-cp-panel[hidden] {
	display: none;
}

.apod-cp .apod-cp-panel--loading {
	min-height: 320px;
	justify-content: center;
}

.apod-cp .apod-cp-panel--loading,
.apod-cp .apod-cp-panel--message {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 18px;
	padding: 48px 0;
	text-align: center;
}

.apod-cp .apod-cp-panel__message {
	margin: 0;
	color: var(--apod-cp-muted);
}

.apod-cp .apod-cp-spinner {
	width: 34px;
	height: 34px;
	border: 3px solid var(--apod-cp-line);
	border-top-color: var(--apod-cp-blue);
	border-radius: 50%;
	animation: apod-cp-spin 0.85s linear infinite;
}

@keyframes apod-cp-spin {
	to {
		transform: rotate(360deg);
	}
}

.apod-cp .apod-cp-preview-banner {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	padding: 12px 20px;
	font-family: var(--apod-cp-font-heading);
	font-size: 0.95rem;
	letter-spacing: 0.02em;
	color: var(--apod-cp-warn-ink);
	background: var(--apod-cp-warn-bg);
	border-bottom: 2px solid #e6b45f;
}

.apod-cp .apod-cp-preview-banner svg {
	width: 20px;
	height: 20px;
	flex: none;
}

/* ────────────────────────────  Cards  ──────────────────────────── */

.apod-cp .apod-cp-card {
	margin: 0 0 18px;
	padding: 28px 32px;
	background: var(--apod-cp-card);
	border: 1px solid var(--apod-cp-card-border);
	border-radius: var(--apod-cp-radius);
}

.apod-cp .apod-cp-card--message,
.apod-cp .apod-cp-card--verify {
	max-width: 560px;
	margin-inline: auto;
	text-align: left;
	background: var(--apod-cp-page);
	border-color: var(--apod-cp-line);
	box-shadow: 0 2px 18px rgba(16, 18, 58, 0.07);
}

.apod-cp .apod-cp-card__title {
	margin: 0 0 10px;
	font-family: var(--apod-cp-font-heading);
	font-size: 1.4rem;
	line-height: 1.25;
	color: var(--apod-cp-navy);
}

.apod-cp .apod-cp-card__body {
	margin: 0 0 16px;
	color: var(--apod-cp-muted);
}

.apod-cp .apod-cp-card__meta {
	margin: 0 0 16px;
	font-size: 0.85rem;
	color: var(--apod-cp-grey);
}

.apod-cp .apod-cp-card__meta code {
	font-size: 0.85em;
}

/* ─────────────────────  Preference groups & rows  ──────────────── */

/*
 * A settings page, not a stack of cards. Each group is a heading plus a list of rows divided
 * by hairlines; each row is one tappable strip with the switch on the right. That is what
 * gets three or more options onto a 375px screen instead of one and a half.
 */

/*
 * One light card per group. The group's icon, title and description sit in a left column and
 * its choices in a right one, which is the layout the design calls for and the reason the
 * fieldset itself is the grid container: the <legend> is the left column, so the grouping
 * stays a real fieldset/legend pair for assistive technology instead of a div pretending.
 */
.apod-cp .apod-cp-group {
	display: grid;
	grid-template-columns: minmax(190px, 300px) minmax(0, 1fr);
	gap: 18px 30px;
	align-items: start;
	margin: 0 0 16px;
	padding: 22px 26px;
	background: var(--apod-cp-card);
	border: 1px solid var(--apod-cp-card-border);
	border-radius: 14px;
	min-inline-size: 0;
}

.apod-cp .apod-cp-group__head {
	display: flex;
	gap: 12px;
	align-items: flex-start;
	grid-column: 1;
	grid-row: 1;
	min-width: 0;
}

.apod-cp .apod-cp-group__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 48px;
	height: 48px;
	border-radius: 50%;
	background: #e3edfa;
	color: var(--apod-cp-blue);
}

.apod-cp .apod-cp-group__icon svg {
	width: 26px;
	height: 26px;
}

/*
 * An uploaded icon sits in the same circle as the built-in glyph. object-fit keeps a
 * non-square upload from stretching, and the box is fixed so one odd file cannot change the
 * height of its card.
 */
.apod-cp .apod-cp-group__icon-image {
	width: 28px;
	height: 28px;
	object-fit: contain;
	display: block;
}

.apod-cp .apod-cp-group__icon--offers { background: #e0ecfb; color: #1b6cb8; }
.apod-cp .apod-cp-group__icon--opportunities { background: #e0f2e6; color: #1e7a44; }
.apod-cp .apod-cp-group__icon--community { background: #ece4f8; color: #6b3fb5; }
.apod-cp .apod-cp-group__icon--member_experience { background: #fdefd9; color: #a8641a; }
.apod-cp .apod-cp-group__icon--danger { background: #fbe1e6; color: var(--apod-cp-red); }

.apod-cp .apod-cp-group__heading {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.apod-cp .apod-cp-group__title {
	font-family: var(--apod-cp-font-heading);
	font-size: 1.05rem;
	line-height: 1.3;
	color: var(--apod-cp-navy);
}

.apod-cp .apod-cp-group__description {
	font-size: 0.88rem;
	line-height: 1.4;
	color: var(--apod-cp-muted);
}

.apod-cp .apod-cp-rows {
	grid-column: 2;
	grid-row: 1;
	list-style: none;
	margin: 0;
	padding: 0;
	background: transparent;
	border: 0;
}

.apod-cp .apod-cp-row {
	position: relative;
	margin: 0;
}

/*
 * The input stays in the accessibility tree and keeps native keyboard behaviour; only its
 * default appearance is removed. It is not display:none, which would make it unfocusable.
 */
.apod-cp .apod-cp-row__input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: 0;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* Checkbox first, then the text — the reading order the design shows. */
.apod-cp .apod-cp-row__label {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 14px;
	align-items: start;
	/* Clears the 44px minimum touch target. */
	min-height: 46px;
	padding: 9px 8px;
	margin: 0 -8px;
	cursor: pointer;
	border-radius: 10px;
}

.apod-cp .apod-cp-row__switch {
	grid-column: 1;
	grid-row: 1;
	margin-top: 1px;
}

.apod-cp .apod-cp-row__text {
	grid-column: 2;
	grid-row: 1;
}

.apod-cp .apod-cp-row__text {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.apod-cp .apod-cp-row__name {
	font-family: var(--apod-cp-font-heading);
	font-size: 0.98rem;
	line-height: 1.35;
	color: var(--apod-cp-ink);
}

.apod-cp .apod-cp-row__description {
	font-size: 0.85rem;
	line-height: 1.4;
	color: var(--apod-cp-muted);
}

/* ── The switch ── */

/*
 * A checkbox, not a switch. The control the design calls for is a square box with a tick:
 * the same native <input type="checkbox"> drives it, and this decorative span is what is
 * actually painted, so the accessible name, label association and keyboard behaviour are
 * unchanged from the switch it replaces.
 */
.apod-cp .apod-cp-row__switch {
	position: relative;
	flex: none;
	width: 24px;
	height: 24px;
	border-radius: 5px;
	background: #ffffff;
	border: 2px solid #b8c2d2;
	transition: background-color 0.15s ease, border-color 0.15s ease;
}

/* The tick. Drawn as two borders on a rotated box so it needs no image or icon font. */
.apod-cp .apod-cp-row__knob {
	position: absolute;
	top: 3px;
	left: 7px;
	width: 6px;
	height: 11px;
	border: solid #ffffff;
	border-width: 0 2.5px 2.5px 0;
	transform: rotate(45deg) scale(0);
	transform-origin: center;
	transition: transform 0.15s ease;
}

.apod-cp .apod-cp-row__input:checked + .apod-cp-row__label .apod-cp-row__switch {
	background: var(--apod-cp-blue);
	border-color: var(--apod-cp-blue);
}

.apod-cp .apod-cp-row__input:checked + .apod-cp-row__label .apod-cp-row__knob {
	transform: rotate(45deg) scale(1);
}

.apod-cp .apod-cp-row--danger .apod-cp-row__input:checked + .apod-cp-row__label .apod-cp-row__switch {
	background: var(--apod-cp-red);
	border-color: var(--apod-cp-red);
}

/*
 * The selected state must not rest on colour alone. A checked row also gets a tinted
 * background and a coloured left edge, so it reads as on in greyscale and for anyone who
 * cannot distinguish the switch colour.
 */
.apod-cp .apod-cp-row__input:checked + .apod-cp-row__label {
	background: transparent;
}

.apod-cp .apod-cp-row--danger .apod-cp-row__input:checked + .apod-cp-row__label {
	background: #fdeef1;
	box-shadow: inset 3px 0 0 var(--apod-cp-red);
}

.apod-cp .apod-cp-row__input:focus-visible + .apod-cp-row__label {
	outline: 3px solid var(--apod-cp-blue-bright);
	outline-offset: -3px;
}

@media (hover: hover) {
	.apod-cp .apod-cp-row__label:hover .apod-cp-row__switch {
		border-color: var(--apod-cp-blue);
	}

	.apod-cp .apod-cp-row__input:checked + .apod-cp-row__label:hover .apod-cp-row__switch {
		background: var(--apod-cp-blue-hover);
		border-color: var(--apod-cp-blue-hover);
	}
}

/* ── Disabled while "unsubscribe from all" is on ── */

.apod-cp .apod-cp-group[data-disabled="true"] .apod-cp-rows {
	opacity: 0.45;
}

.apod-cp .apod-cp-group[data-disabled="true"] .apod-cp-row__label {
	cursor: not-allowed;
}

/* ── The unsubscribe group ── */

.apod-cp .apod-cp-group--danger .apod-cp-rows {
	background: #fdf6f7;
	border-color: #f1d4db;
}

.apod-cp .apod-cp-group__note {
	margin: 10px 2px 22px;
	padding: 12px 14px;
	font-size: 0.88rem;
	line-height: 1.45;
	color: #6d1020;
	background: #fdeef1;
	border-left: 3px solid var(--apod-cp-red);
	border-radius: 8px;
}

.apod-cp .apod-cp-group__note[hidden] {
	display: none;
}

/* ─────────────────────────────  Notices  ───────────────────────── */

.apod-cp .apod-cp-notice {
	display: flex;
	gap: 12px;
	align-items: flex-start;
	margin: 0 0 22px;
	padding: 14px 16px;
	border-radius: 12px;
}

.apod-cp .apod-cp-notice[hidden] {
	display: none;
}

.apod-cp .apod-cp-notice__icon {
	display: inline-flex;
	flex: none;
	margin-top: 1px;
}

.apod-cp .apod-cp-notice__icon svg {
	width: 20px;
	height: 20px;
}

.apod-cp .apod-cp-notice__body {
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-size: 0.92rem;
	line-height: 1.45;
}

.apod-cp .apod-cp-notice__actions {
	margin-top: 8px;
}

.apod-cp .apod-cp-notice--warning {
	color: #6d1020;
	background: #fdeef1;
	border: 1px solid #f1d4db;
}

/* ────────────────────────────  Fine print  ─────────────────────── */

.apod-cp .apod-cp-fineprint {
	margin: 12px 2px 4px;
	font-size: 0.85rem;
	line-height: 1.5;
	color: var(--apod-cp-muted);
}

/* ───────────────────────────  The save bar  ────────────────────── */

/*
 * The save bar sits in normal flow at the end of the form, and only becomes sticky once the
 * member has actually changed something.
 *
 * It used to be sticky at all times. Sticky does not mean "cannot cover content" — it means
 * the element floats over whatever scrolls beneath it — so on a page this long the bar was
 * permanently parked over a preference row, at every viewport, including the first screen on
 * desktop before any scrolling. A bar that obscures the options while asking the member to
 * choose between them is worse than one they have to scroll to, and while nothing has changed
 * the button is disabled anyway, so there is nothing to keep in reach.
 */
.apod-cp .apod-cp-savebar {
	position: static;
	z-index: 5;
	margin: 20px 0 16px;
	padding: 0;
	background: transparent;
	border: 0;
	border-radius: 12px;
	box-shadow: none;
}

/*
 * Only once it detaches and floats over the choices does it need to be a bar. Fully opaque
 * then: at 96% the row underneath bled through and read as a rendering fault.
 */
.apod-cp--has-unsaved-changes .apod-cp-savebar {
	padding: 8px 10px;
	background: var(--apod-cp-page);
	border: 1px solid var(--apod-cp-line);
	box-shadow: 0 2px 12px rgba(16, 18, 58, 0.08);
}

.apod-cp.apod-cp--has-unsaved-changes .apod-cp-savebar,
.apod-cp--has-unsaved-changes .apod-cp-savebar {
	position: sticky;
	/* Clear of the iPhone home indicator without any fixed positioning. */
	bottom: max(8px, env(safe-area-inset-bottom, 8px));
	box-shadow: 0 -2px 16px rgba(16, 18, 58, 0.12);
}

.apod-cp .apod-cp-savebar__inner {
	display: flex;
	gap: 12px;
	align-items: center;
	justify-content: flex-end;
	max-width: none;
	margin: 0 auto;
}

.apod-cp .apod-cp-savebar__status {
	flex: 1 1 auto;
	margin: 0;
	font-size: 0.9rem;
	line-height: 1.35;
	text-align: left;
}

.apod-cp .apod-cp-savebar__status[hidden] {
	display: none;
}

.apod-cp .apod-cp-savebar__status[data-tone="success"] { color: var(--apod-cp-success-ink); }
.apod-cp .apod-cp-savebar__status[data-tone="error"] { color: #97102a; }
.apod-cp .apod-cp-savebar__status[data-tone="info"] { color: var(--apod-cp-muted); }

/* ────────────────────────────  Buttons  ───────────────────────── */

/*
 * These must out-specify the theme. Elementor's kit styles bare `button` at (0,1,1) with its
 * own colour, 100px pill radius and padding, and the theme reset adds a border colour on top.
 * Rooting each rule under .apod-cp takes it to (0,2,0), which wins cleanly — no !important,
 * and nothing outside this component is touched.
 */

.apod-cp .apod-cp-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	min-height: 48px;
	padding: 13px 26px;
	font-family: var(--apod-cp-font-heading);
	font-size: 1rem;
	line-height: 1.2;
	text-align: center;
	text-decoration: none;
	background: transparent;
	border: 2px solid transparent;
	border-radius: 10px;
	cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.apod-cp .apod-cp-button:focus-visible {
	outline: 3px solid var(--apod-cp-blue-bright);
	outline-offset: 3px;
}

.apod-cp .apod-cp-button--primary {
	color: #ffffff;
	background: var(--apod-cp-blue);
	border-color: var(--apod-cp-blue);
}

.apod-cp .apod-cp-button--primary:hover:not([disabled]) {
	background: var(--apod-cp-blue-hover);
	border-color: var(--apod-cp-blue-hover);
}

.apod-cp .apod-cp-button--secondary {
	color: var(--apod-cp-blue);
	background: #ffffff;
	border-color: var(--apod-cp-blue);
}

.apod-cp .apod-cp-button--secondary:hover:not([disabled]) {
	background: #f2f7fd;
}

.apod-cp .apod-cp-button--ghost {
	padding-inline: 12px;
	color: var(--apod-cp-blue);
	background: transparent;
	border-color: transparent;
	text-decoration: underline;
}

.apod-cp .apod-cp-button--ghost:hover {
	color: var(--apod-cp-blue-hover);
}

.apod-cp .apod-cp-button[disabled] {
	cursor: not-allowed;
	color: #6c7480;
	background: #e6eaf0;
	border-color: #e6eaf0;
}

.apod-cp .apod-cp-button__spinner {
	display: none;
	width: 17px;
	height: 17px;
	border: 2px solid rgba(255, 255, 255, 0.45);
	border-top-color: #ffffff;
	border-radius: 50%;
	animation: apod-cp-spin 0.7s linear infinite;
}

.apod-cp .apod-cp-button[data-busy="true"] .apod-cp-button__spinner {
	display: inline-block;
}

.apod-cp .apod-cp-button--save {
	flex: none;
	min-width: 180px;
	min-height: 44px;
	padding: 11px 22px;
}

.apod-cp .apod-cp-button--small {
	min-height: 40px;
	padding: 8px 18px;
	font-size: 0.9rem;
}



/* ───────────────────────────  Verify form  ─────────────────────── */

.apod-cp .apod-cp-field {
	margin: 0 0 20px;
}

.apod-cp .apod-cp-field__label {
	display: block;
	margin-bottom: 6px;
	font-family: var(--apod-cp-font-heading);
	font-size: 0.95rem;
	color: var(--apod-cp-navy);
}

.apod-cp .apod-cp-code-input {
	width: 100%;
	max-width: 280px;
	padding: 14px 16px;
	font-family: "Courier New", Courier, monospace;
	font-size: 1.5rem;
	letter-spacing: 0.35em;
	text-align: center;
	color: var(--apod-cp-ink);
	background: #ffffff;
	border: 2px solid #9fb2cc;
	border-radius: 8px;
}

.apod-cp .apod-cp-code-input:focus-visible {
	outline: 3px solid var(--apod-cp-blue-bright);
	outline-offset: 2px;
	border-color: var(--apod-cp-blue);
}

.apod-cp .apod-cp-code-input[aria-invalid="true"] {
	border-color: var(--apod-cp-red);
}

.apod-cp .apod-cp-field__hint {
	margin: 8px 0 0;
	font-size: 0.9rem;
	color: var(--apod-cp-muted);
}

.apod-cp .apod-cp-field__error {
	margin: 8px 0 0;
	font-size: 0.94rem;
	font-weight: 600;
	color: #97102a;
}

.apod-cp .apod-cp-field__error[hidden] {
	display: none;
}

.apod-cp .apod-cp-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	align-items: center;
}

/* ─────────────────────────────  Modal  ─────────────────────────── */

.apod-cp .apod-cp-modal {
	position: fixed;
	inset: 0;
	z-index: 99999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 20px;
}

.apod-cp .apod-cp-modal[hidden] {
	display: none;
}

.apod-cp .apod-cp-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(10, 12, 32, 0.62);
}

.apod-cp .apod-cp-modal__panel {
	position: relative;
	width: 100%;
	max-width: 520px;
	max-height: calc(100vh - 40px);
	overflow-y: auto;
	padding: 30px 32px;
	background: #ffffff;
	border-radius: var(--apod-cp-radius);
	box-shadow: 0 18px 60px rgba(8, 10, 30, 0.35);
}

.apod-cp .apod-cp-modal__title {
	margin: 0 0 12px;
	font-family: var(--apod-cp-font-heading);
	font-size: 1.35rem;
	color: var(--apod-cp-navy);
}

.apod-cp .apod-cp-modal__title:focus-visible {
	outline: 3px solid var(--apod-cp-blue-bright);
	outline-offset: 4px;
}

.apod-cp .apod-cp-modal__body {
	margin: 0 0 16px;
	color: var(--apod-cp-muted);
}

.apod-cp .apod-cp-modal__list {
	margin: 0 0 22px;
	padding-left: 22px;
	color: var(--apod-cp-ink);
	font-size: 0.96rem;
}

.apod-cp .apod-cp-modal__list li {
	margin-bottom: 4px;
}

.apod-cp .apod-cp-modal__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

/* ───────────────────────────  Responsive  ──────────────────────── */

@media (max-width: 1023px) {
	.apod-cp .apod-cp-group {
		grid-template-columns: 1fr;
		gap: 22px;
	}
}

@media (max-width: 767px) {
	.apod-cp {
		--apod-cp-gutter: 18px;
	}

	.apod-cp .apod-cp-hero {
		padding: 28px var(--apod-cp-gutter);
		background-position: center 45%;
	}

	.apod-cp .apod-cp-hero__scrim {
		background: linear-gradient(180deg, rgba(8, 10, 30, 0.62) 0%, rgba(8, 10, 30, 0.82) 100%);
	}

	.apod-cp .apod-cp-hero__title {
		max-width: none;
	}

	/* Let the heading wrap naturally in a narrow column rather than forcing the break. The
	   spans are adjacent in the markup, so the space between them is restored here. */
	.apod-cp .apod-cp-hero__line {
		display: inline;
	}

	.apod-cp .apod-cp-hero__line + .apod-cp-hero__line::before {
		content: " ";
	}

	.apod-cp .apod-cp-shell {
		padding: 20px var(--apod-cp-gutter) 24px;
	}

	.apod-cp .apod-cp-card {
		padding: 22px 18px;
	}

	.apod-cp .apod-cp-group__icon {
		width: 34px;
		height: 34px;
	}

	.apod-cp .apod-cp-group__icon svg {
		width: 18px;
		height: 18px;
	}

	.apod-cp .apod-cp-row__label {
		padding: 12px 14px;
	}

	/* The save button fills the bar on a phone: a thumb-sized target, and no dead space. */
	.apod-cp .apod-cp-button--save {
		flex: 1 1 auto;
		min-width: 0;
	}

	.apod-cp .apod-cp-savebar__inner {
		flex-wrap: wrap;
		gap: 8px;
	}

	/* The status sits above the button rather than squeezing it. */
	.apod-cp .apod-cp-savebar__status {
		flex: 1 0 100%;
		font-size: 0.85rem;
	}

	.apod-cp .apod-cp-savebar__inner {
		gap: 10px;
	}

	.apod-cp .apod-cp-button--save {
		flex: 1 1 auto;
		min-width: 0;
	}

	.apod-cp .apod-cp-savebar__status {
		font-size: 0.85rem;
	}

	.apod-cp .apod-cp-button {
		width: 100%;
	}

	.apod-cp .apod-cp-button--small {
		width: auto;
	}

	.apod-cp .apod-cp-button--ghost {
		width: auto;
	}

	.apod-cp .apod-cp-actions .apod-cp-button {
		width: 100%;
	}

	.apod-cp .apod-cp-modal__panel {
		padding: 24px 20px;
	}

	.apod-cp .apod-cp-modal__actions .apod-cp-button {
		width: 100%;
	}
}

/* ───────────────  Reduced motion & forced colours  ─────────────── */

@media (prefers-reduced-motion: reduce) {
	.apod-cp *,
	.apod-cp *::before,
	.apod-cp *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}

	.apod-cp .apod-cp-spinner,
	.apod-cp .apod-cp-button__spinner {
		animation: none;
		border-top-color: currentColor;
	}
}

@media (forced-colors: active) {
	/* In forced colours the tinted row background is discarded, so the switch itself has to
	   carry the on/off distinction. A border plus the Highlight fill does that. */
	.apod-cp .apod-cp-row__switch {
		border: 1px solid ButtonBorder;
	}

	.apod-cp .apod-cp-row__input:checked + .apod-cp-row__label .apod-cp-row__switch {
		background: Highlight;
		border-color: Highlight;
	}

	.apod-cp .apod-cp-row__knob {
		background: ButtonText;
	}

	.apod-cp .apod-cp-row__input:checked + .apod-cp-row__label .apod-cp-row__knob {
		background: HighlightText;
	}

	.apod-cp .apod-cp-rows,
	.apod-cp .apod-cp-row + .apod-cp-row {
		border-color: ButtonBorder;
	}

	.apod-cp .apod-cp-button {
		border-color: ButtonBorder;
	}
}

.apod-cp .apod-cp-button--danger {
	color: #ffffff;
	background: var(--apod-cp-red);
	border-color: var(--apod-cp-red);
}

.apod-cp .apod-cp-button--danger:hover:not([disabled]) {
	background: var(--apod-cp-red-hover);
	border-color: var(--apod-cp-red-hover);
}

.apod-cp .apod-cp-banner__actions {
	margin: 10px 0 0;
}

.apod-cp .apod-cp-button--compact {
	min-height: 42px;
	padding: 10px 22px;
	font-size: 0.95rem;
}

/* ─────────────  Standalone unsubscribe confirmation  ───────────── */

.apod-cp .apod-cp-card--danger {
	border-color: #f0c5cf;
}

.apod-cp .apod-cp-card__icon {
	margin-bottom: 18px;
}

.apod-cp .apod-cp-card__error {
	padding: 12px 16px;
	font-weight: 600;
	color: #97102a;
	background: var(--apod-cp-error-bg);
	border: 1px solid #f0c5cf;
	border-radius: 8px;
}

.apod-cp .apod-cp-card__error[hidden] {
	display: none;
}

.apod-cp .apod-cp-card__title:focus-visible {
	outline: 3px solid var(--apod-cp-blue-bright);
	outline-offset: 4px;
}

/* ────────────  Page-scoped: floating third-party widgets  ─────── */

/*
 * The Jira Service Desk launcher is position:fixed at z-index 2147483647 and sat on top of the
 * form controls, the save button and the confirmation message. On a settings page every one of
 * those is something the member has to be able to see and press, so the launcher is hidden
 * here only. It remains on every other page of the site.
 *
 * Scoped by the body class the plugin adds, so nothing outside this page is affected.
 */
body.apod-cp-page #jsd-widget,
body.apod-cp-page iframe[name="JSD widget"] {
	display: none !important;
}

/* ──────────  Page-scoped: neutralise the wrapper's padding  ────── */

/*
 * The page builder wraps the shortcode in its own container, and that container's vertical
 * padding shows as a white strip between the site header and the full-bleed hero.
 *
 * :has() lets us target whatever the wrapper happens to be — "the element that contains our
 * root" — instead of hard-coding Elementor's internal class names, which would break the
 * moment the builder renames them or the page is rebuilt with a different block. Three levels
 * covers the observed nesting without reaching as far as <body>.
 *
 * Browsers without :has() simply keep the strip. It is cosmetic, so the degradation is safe.
 */
body.apod-cp-page :has(> #apod-cp-root),
body.apod-cp-page :has(> * > #apod-cp-root),
body.apod-cp-page :has(> * > * > #apod-cp-root) {
	padding-top: 0;
	padding-bottom: 0;
}


/* ─────────────────  Unsubscribe from all  ───────────── */

/*
 * The same control as the choices above, so the page reads as one set of options — but on
 * its own below a rule, because it is not a preference: ticking it opens a confirmation
 * rather than queueing a change for Save.
 */
.apod-cp .apod-cp-unsub {
	max-width: 100%;
	margin: 30px 0 0;
	padding: 30px 26px 22px;
	border-top: 1px solid var(--apod-cp-line);
}

.apod-cp .apod-cp-rows--unsub {
	margin: 0;
}

.apod-cp .apod-cp-rows--unsub .apod-cp-row__name {
	font-weight: 600;
}

@media (max-width: 600px) {
	.apod-cp .apod-cp-unsub {
		margin: 22px 0 0;
		padding: 22px 14px 16px;
	}
}

/* ─────────────────  Unsubscribed confirmation  ───────────── */

/*
 * Replaces the form outright. Leaving the category rows on screen — ticked, behind a notice
 * — read as "you are still subscribed", which is the opposite of what had just happened.
 * Calm and factual: no warning colour, no icon shouting at the member, no second attempt to
 * talk them out of it.
 */
.apod-cp .apod-cp-unsubscribed {
	margin: 0;
	padding: 32px 28px;
	background: var(--apod-cp-card);
	border: 1px solid var(--apod-cp-card-border);
	border-radius: 12px;
	text-align: center;
}

.apod-cp .apod-cp-unsubscribed__title {
	margin: 0 0 12px;
	font-family: var(--apod-cp-font-heading);
	font-size: 1.5rem;
	line-height: 1.25;
	color: var(--apod-cp-navy);
}

.apod-cp .apod-cp-unsubscribed__title:focus-visible {
	outline: 3px solid var(--apod-cp-blue-bright);
	outline-offset: 4px;
	border-radius: 4px;
}

.apod-cp .apod-cp-unsubscribed__body {
	margin: 0 auto 24px;
	max-width: 52ch;
	font-size: 1rem;
	line-height: 1.6;
	color: var(--apod-cp-ink);
}

.apod-cp .apod-cp-unsubscribed__actions {
	margin: 0;
}

@media (max-width: 600px) {
	.apod-cp .apod-cp-unsubscribed {
		padding: 26px 18px;
	}

	.apod-cp .apod-cp-unsubscribed__title {
		font-size: 1.3125rem;
	}
}

/*
 * display rules on .apod-cp-savebar and the group fieldsets beat the [hidden] attribute,
 * which is only a UA-stylesheet display:none. Without this the save bar and the form would
 * stay on screen underneath the unsubscribed confirmation.
 */
.apod-cp [hidden] {
	display: none !important;
}


/* Stack the card to a single column on a phone: heading, then its choices. */
@media (max-width: 782px) {
	.apod-cp .apod-cp-group {
		grid-template-columns: minmax(0, 1fr);
		gap: 14px;
		padding: 18px 16px;
	}

	.apod-cp .apod-cp-group__head,
	.apod-cp .apod-cp-rows {
		grid-column: 1;
	}

	.apod-cp .apod-cp-group__head {
		grid-row: 1;
	}

	.apod-cp .apod-cp-rows {
		grid-row: 2;
	}
}


/*
 * Phone density. A stacked card header plus card padding pushed the third choice below the
 * fold on a 375px screen, so the page opened showing two options and looked shorter than it
 * is. Tighten the card, not the touch targets: rows stay >= 44px.
 */
@media (max-width: 600px) {
	.apod-cp .apod-cp-group {
		margin: 0 0 12px;
		padding: 14px 14px 12px;
		gap: 10px;
		border-radius: 12px;
	}

	.apod-cp .apod-cp-group__head {
		gap: 10px;
		align-items: center;
	}

	.apod-cp .apod-cp-group__icon {
		width: 32px;
		height: 32px;
	}

	.apod-cp .apod-cp-group__icon svg {
		width: 17px;
		height: 17px;
	}

	.apod-cp .apod-cp-group__title {
		font-size: 1rem;
	}

	.apod-cp .apod-cp-group__description {
		font-size: 0.82rem;
		line-height: 1.35;
	}

	.apod-cp .apod-cp-row__label {
		min-height: 44px;
		padding: 7px 6px;
		margin: 0 -6px;
		gap: 12px;
	}
}


/*
 * Without the banner the panel would begin hard against whatever sits above it, so the shell
 * carries its own top spacing in that case. .apod-cp-shell keeps its padding either way; this
 * only adds the breathing room the hero used to provide.
 */
.apod-cp--no-hero .apod-cp-shell {
	padding-top: 44px;
}

@media (max-width: 600px) {
	.apod-cp--no-hero .apod-cp-shell {
		padding-top: 26px;
	}
}


/* Larger icons still need to fit a phone. */
@media (max-width: 600px) {
	.apod-cp .apod-cp-group__icon {
		width: 40px;
		height: 40px;
	}

	.apod-cp .apod-cp-group__icon svg {
		width: 22px;
		height: 22px;
	}

	.apod-cp .apod-cp-group__icon-image {
		width: 24px;
		height: 24px;
	}
}


/* ─────────────────  Unsubscribe confirmation card  ───────────── */

/*
 * Calm, not alarming. The warning icon and the pink border made a reversible choice look
 * like a hazard, and the buttons picked up the theme's own borders, so the primary action
 * came out navy with a red outline. Both actions are stated plainly and styled here at
 * button-element specificity so the theme cannot put its own chrome back.
 */
.apod-cp .apod-cp-card--confirm {
	max-width: 620px;
	margin-inline: auto;
	border-color: var(--apod-cp-card-border);
	text-align: left;
}

.apod-cp .apod-cp-card--confirm .apod-cp-card__title {
	margin-top: 0;
}

.apod-cp .apod-cp-card--confirm .apod-cp-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: 22px;
}

@media (max-width: 600px) {
	.apod-cp .apod-cp-card--confirm .apod-cp-actions .apod-cp-button {
		width: 100%;
	}
}


/*
 * A plain text action.
 *
 * !important is deliberate and confined to these declarations. The site theme styles bare
 * <button> elements with a filled background and its own colour, from selectors outside this
 * stylesheet that outrank anything scoped under .apod-cp — the result was a solid navy block
 * behind this text. Defending against CSS this component does not own is the one case where
 * raising the weight is the honest fix rather than a specificity race.
 */
.apod-cp button.apod-cp-textlink,
.apod-cp button.apod-cp-textlink:hover,
.apod-cp button.apod-cp-textlink:focus,
.apod-cp button.apod-cp-textlink:active {
	appearance: none !important;
	-webkit-appearance: none !important;
	background: none !important;
	background-color: transparent !important;
	background-image: none !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	text-shadow: none !important;
	-webkit-tap-highlight-color: transparent;
	padding: 2px 0 !important;
	margin: 0;
	width: auto !important;
	min-width: 0 !important;
	min-height: 0 !important;
	font-family: inherit;
	font-size: 0.9375rem;
	font-weight: 500;
	line-height: 1.5;
	letter-spacing: normal;
	text-transform: none;
	cursor: pointer;
}

.apod-cp button.apod-cp-textlink {
	color: var(--apod-cp-blue) !important;
	text-decoration: none !important;
}

.apod-cp button.apod-cp-textlink:hover,
.apod-cp button.apod-cp-textlink:focus-visible {
	color: var(--apod-cp-blue-hover) !important;
	text-decoration: underline !important;
	text-underline-offset: 3px;
}

.apod-cp button.apod-cp-textlink:focus-visible {
	outline: 2px solid var(--apod-cp-blue-bright);
	outline-offset: 3px;
	border-radius: 3px !important;
}

/*
 * The confirm button, without the red. Behind an explicit confirmation whose heading already
 * states what it does, an alarm colour added weight rather than clarity — and the theme kept
 * putting its own border around it. Navy is the brand's own, and the same treatment is
 * pinned down so nothing outside can restyle it.
 */
.apod-cp button.apod-cp-button--confirm,
.apod-cp button.apod-cp-button--confirm:hover,
.apod-cp button.apod-cp-button--confirm:focus {
	background: var(--apod-cp-navy) !important;
	background-image: none !important;
	border: 1px solid var(--apod-cp-navy) !important;
	color: #ffffff !important;
	box-shadow: none !important;
}

.apod-cp button.apod-cp-button--confirm:hover {
	background: var(--apod-cp-navy-deep) !important;
	border-color: var(--apod-cp-navy-deep) !important;
}

.apod-cp button.apod-cp-button--confirm:focus-visible {
	outline: 3px solid var(--apod-cp-blue-bright);
	outline-offset: 2px;
}

/* The way back sits above the action that cannot be undone from this screen. */
.apod-cp .apod-cp-card--confirm .apod-cp-actions {
	align-items: flex-start;
	flex-direction: column;
	gap: 18px;
	margin-top: 24px;
}

/* The heading takes focus when the card opens; it should not draw a ring for a mouse user. */
.apod-cp [data-slot="unsubscribe-confirm-title"]:focus {
	outline: none;
}

.apod-cp [data-slot="unsubscribe-confirm-title"]:focus-visible {
	outline: 3px solid var(--apod-cp-blue-bright);
	outline-offset: 4px;
	border-radius: 4px;
}


/*
 * On the unsubscribe row, only the box itself is clickable.
 *
 * The category rows are deliberately the opposite — the whole row is a target, which is what
 * makes them workable on a phone. This one ends a member's marketing email, so a target
 * spanning the full width of the card meant a stray click anywhere near the text opened the
 * confirmation. The label still belongs to the input, so the accessible name, the keyboard
 * and the screen reader are unchanged; only the pointer target shrinks to the box.
 */
.apod-cp .apod-cp-rows--unsub .apod-cp-row__label {
	pointer-events: none;
	cursor: default;
}

.apod-cp .apod-cp-rows--unsub .apod-cp-row__switch {
	pointer-events: auto;
	cursor: pointer;
}

/* Space between the decision and the help line under it. */
.apod-cp .apod-cp-card--confirm .apod-cp-card__meta {
	margin-top: 22px;
}


/*
 * Sub-heading lines, handled like the heading's: each starts on its own line on a wide
 * screen, and they rejoin into a running paragraph on a phone, where forcing an author's
 * break would leave short orphaned lines. The spans are adjacent in the markup — no
 * whitespace between them, or a content filter turns it into a <br> — so the space between
 * them is restored here when they rejoin.
 */
.apod-cp .apod-cp-hero__lede-line {
	display: block;
}

@media (max-width: 767px) {
	.apod-cp .apod-cp-hero__lede-line {
		display: inline;
	}

	.apod-cp .apod-cp-hero__lede-line + .apod-cp-hero__lede-line::before {
		content: " ";
	}
}
