/* ==========================================================================
   Newsletter opt-in form — v11 "Prime"
   --------------------------------------------------------------------------
   The same form in three places: the dark closing band on the front page,
   the sidebar on cream, and the subscribe modal. All three share this file,
   and the differences between them are handled by context selectors at the
   bottom rather than by three separate components.

   The blue build drew a rounded pill input beside a rounded pill button. The
   reference has no rounded controls anywhere, and on a dark band a pill pair
   reads as a signup widget pasted onto the page. What is here instead is an
   UNDERLINED field — no box, no fill, just a rule under the text that goes
   gold on focus — beside a squared gold plate. It sits on the band rather
   than on top of it.

   Nothing in the form's BEHAVIOUR changed with the redesign: the nonce, the
   honeypot, the time trap, the consent capture and the double opt-in
   confirmation are all exactly as they were. This file only draws it.
   ========================================================================== */

.st-optin {
	--optin-ink: var(--ink);
	--optin-dim: var(--ink-400);
	--optin-rule: var(--line-firm);
	--optin-focus: var(--gold);

	display: flex;
	flex-direction: column;
	gap: 1.15rem;
	width: 100%;
	max-width: 32rem;
	margin-inline: auto;
	text-align: left;
}

/* ── The honeypot ────────────────────────────────────────────────────
   Hidden with CSS rather than type="hidden" so that bots, which read the
   markup and not the stylesheet, still fill it in. It must stay reachable
   to a scripted fill and unreachable to a person: off-screen rather than
   display:none, and taken out of the tab order in the markup. */
.st-optin__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.st-optin__field {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	min-width: 0;
}

/* ── The email field ─────────────────────────────────────────────────
   A rule under the text and nothing else. The placeholder does the work
   the label would — the real label is present for a screen reader and
   visually hidden — so the field needs no chrome to explain itself. */
.st-optin__input {
	width: 100%;
	padding: 0.85rem 0.25rem;
	border: 0;
	border-bottom: 1px solid var(--optin-rule);
	border-radius: 0;
	background: transparent;
	color: var(--optin-ink);
	font-family: var(--font-body);
	font-size: var(--fs-body);
	line-height: 1.4;
	transition: border-color var(--speed) var(--ease);
	/* iOS zooms the page when a focused input is under 16px. */
	-webkit-appearance: none;
	appearance: none;
}

.st-optin__input::placeholder {
	color: var(--optin-dim);
	opacity: 1;
}

.st-optin__input:focus {
	outline: none;
	border-bottom-color: var(--optin-focus);
	border-bottom-width: 2px;
	/* The extra pixel of border must not shift the field's height. */
	padding-bottom: calc(0.85rem - 1px);
}

/* Keyboard users still need a visible ring; the border change alone is too
   subtle to serve as the only focus signal. */
.st-optin__input:focus-visible {
	outline: 2px solid var(--optin-focus);
	outline-offset: 3px;
}

/* The error state. optin-form.js puts .has-error on the FIELD wrapper and
   appends a .st-optin__field-error note inside it — so the rule is written
   against the wrapper, not against the input. Getting this wrong is silent:
   the form still works and simply never looks wrong. */
.st-optin__field.has-error .st-optin__input {
	border-bottom-color: var(--flag);
}

.st-optin__field-error {
	color: var(--flag);
	font-size: var(--fs-meta);
	line-height: 1.5;
}

/* ── Consent ─────────────────────────────────────────────────────────
   Required, and deliberately legible rather than shrunk to nothing. A
   consent line small enough to miss is not consent. */
.st-optin__consent {
	flex-direction: row;
}

.st-optin__consent-label {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 0.7rem;
	align-items: start;
	cursor: pointer;
}

.st-optin__checkbox {
	width: 1.1rem;
	height: 1.1rem;
	margin: 0.15rem 0 0;
	flex: none;
	accent-color: var(--optin-focus);
	cursor: pointer;
}

.st-optin__consent-text {
	color: var(--optin-dim);
	font-size: var(--fs-meta);
	line-height: 1.55;
}

.st-optin__consent-text a {
	color: var(--optin-focus);
	text-underline-offset: 0.2em;
}

/* ── The submit ──────────────────────────────────────────────────────
   The squared gold plate, matching .btn exactly. It is declared here in
   full rather than by adding .btn in the markup, because this form is also
   rendered by a shortcode on sites whose pages may not load the theme's
   button rules in the same cascade order. */
.st-optin__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	width: 100%;
	padding: 0.95rem 1.9rem;
	border: 1px solid var(--gold);
	border-radius: var(--r-pill);
	background: var(--gold);
	color: #fff;
	font-family: var(--font-body);
	font-size: var(--fs-meta);
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	line-height: 1.2;
	cursor: pointer;
	transition: background var(--speed) var(--ease), border-color var(--speed) var(--ease);
}

.st-optin__submit:hover,
.st-optin__submit:focus-visible {
	background: var(--gold-deep);
	border-color: var(--gold-deep);
}

.st-optin__submit[disabled] {
	opacity: 0.6;
	cursor: progress;
}

/* ── The status line ─────────────────────────────────────────────────
   aria-live, so the result is announced. Empty until there is something to
   say, and it must not reserve space while empty or every form carries a
   permanent gap under its button. */
.st-optin__message {
	margin: 0;
	font-size: var(--fs-meta);
	line-height: 1.5;
}

.st-optin__message:empty {
	display: none;
}

.st-optin__message.is-error {
	color: var(--flag);
}

.st-optin__message.is-success {
	color: var(--gold-deep);
}

/* While the request is in flight the submit is disabled by the script; the
   whole form also dims so a slow network looks like waiting rather than like
   nothing having happened. */
.st-optin.is-loading {
	opacity: 0.75;
}

/* After a successful submit the form is left in place with .is-done. The
   fields have nothing more to collect, so they go; the status line, which is
   the thing the reader now needs to read, stays. */
.st-optin.is-done .st-optin__field,
.st-optin.is-done .st-optin__submit {
	display: none;
}

.st-optin.is-done .st-optin__message {
	font-size: var(--fs-body);
}

/* ── On the dark bands ───────────────────────────────────────────────
   The closing newsletter band and the footer. Everything switches to the
   bright gold, which is the only value legible on this ground, and the
   filled control takes near-black text: bright gold with white text is the
   one combination in this palette that fails contrast both ways. */
.band--dark .st-optin,
.signal .st-optin,
.site-footer .st-optin {
	--optin-ink: var(--on-dark);
	--optin-dim: var(--on-dark-dim);
	--optin-rule: rgba(245, 241, 232, 0.28);
	--optin-focus: var(--gold-lift);
}

.band--dark .st-optin__submit,
.signal .st-optin__submit,
.site-footer .st-optin__submit {
	background: var(--gold-lift);
	border-color: var(--gold-lift);
	color: var(--dark);
}

.band--dark .st-optin__submit:hover,
.band--dark .st-optin__submit:focus-visible,
.signal .st-optin__submit:hover,
.signal .st-optin__submit:focus-visible,
.site-footer .st-optin__submit:hover,
.site-footer .st-optin__submit:focus-visible {
	background: #E0BC4A;
	border-color: #E0BC4A;
	color: var(--dark);
}

.band--dark .st-optin__message.is-success,
.signal .st-optin__message.is-success,
.site-footer .st-optin__message.is-success {
	color: var(--gold-lift);
}

/* The rust flag is too dark to read on the dark ground. */
.band--dark .st-optin__message.is-error,
.signal .st-optin__message.is-error,
.site-footer .st-optin__message.is-error,
.band--dark .st-optin__field-error,
.signal .st-optin__field-error,
.site-footer .st-optin__field-error {
	color: #E8836A;
}

.band--dark .st-optin__field.has-error .st-optin__input,
.signal .st-optin__field.has-error .st-optin__input,
.site-footer .st-optin__field.has-error .st-optin__input {
	border-bottom-color: #E8836A;
}

/* ── Side by side ────────────────────────────────────────────────────
   Where there is room, the field and the button share a row, with the
   consent line and the status beneath spanning both. This is the front
   page's closing band and the modal; the sidebar is too narrow and keeps
   the stacked arrangement.

   Grid rather than flex so the consent row can span, and so the button
   keeps its natural width instead of being stretched by align-items. */
@media (min-width: 560px) {
	.signal .st-optin,
	.st-modal .st-optin {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		align-items: end;
		gap: 0.75rem 1rem;
		max-width: 34rem;
	}

	.signal .st-optin__field:not(.st-optin__consent),
	.st-modal .st-optin__field:not(.st-optin__consent) {
		grid-column: 1;
	}

	.signal .st-optin__submit,
	.st-modal .st-optin__submit {
		grid-column: 2;
		width: auto;
		/* Sits on the field's baseline rule rather than below it. */
		margin-bottom: 1px;
	}

	.signal .st-optin__consent,
	.signal .st-optin__message,
	.st-modal .st-optin__consent,
	.st-modal .st-optin__message {
		grid-column: 1 / -1;
	}
}

/* ── Reduced motion ──────────────────────────────────────────────────
   The only transitions here are colour changes, which are not motion, but
   the border-width swap on focus does shift a pixel. */
@media (prefers-reduced-motion: reduce) {
	.st-optin__input,
	.st-optin__submit {
		transition: none;
	}
}

/* ==========================================================================
   The subscribe modal
   --------------------------------------------------------------------------
   Opened by the masthead's Subscribe control and by any [href="#formPopup"]
   link; optin-form.js toggles the `hidden` attribute and adds
   .st-modal-open to <body>.

   The markup is .st-modal > .st-modal__backdrop + .st-modal__dialog. The
   dialog is a CREAM plate, not a dark one: the modal appears over whatever
   the reader was looking at, and a dark panel over a cream page reads as a
   second site rather than as a layer of this one.

   The `hidden` attribute is what closes it, and main.css already gives
   [hidden] a display:none carrying !important — which it needs, because the
   display:grid below would otherwise win and the modal could never be
   closed.
   ========================================================================== */
.st-modal {
	position: fixed;
	inset: 0;
	z-index: 200;
	display: grid;
	place-items: center;
	padding: var(--gutter);
	/* The dialog can be taller than a short viewport once the consent line
	   wraps, so the overlay scrolls rather than clipping it. */
	overflow-y: auto;
}

.st-modal__backdrop {
	position: fixed;
	inset: 0;
	background: rgba(20, 18, 15, 0.72);
	border: 0;
	cursor: pointer;
}

.st-modal__dialog {
	position: relative;
	width: 100%;
	max-width: 34rem;
	padding: clamp(2rem, 4vw, 3rem);
	background: var(--ground);
	border: 1px solid var(--line-gold);
	border-radius: var(--r-panel);
	box-shadow: var(--shade-panel);
	text-align: center;
}

.st-modal__close {
	position: absolute;
	top: 0.65rem;
	right: 0.65rem;
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 0;
	border-radius: var(--r-pill);
	background: transparent;
	color: var(--ink-400);
	font-size: 1.5rem;
	line-height: 1;
	cursor: pointer;
	transition: color var(--speed) var(--ease), background var(--speed) var(--ease);
}

.st-modal__close:hover,
.st-modal__close:focus-visible {
	background: var(--gold-tint);
	color: var(--ink);
}

.st-modal__kicker {
	margin: 0 0 0.75rem;
	color: var(--gold);
	font-family: var(--font-body);
	font-size: var(--fs-micro);
	font-weight: 600;
	letter-spacing: var(--track-label);
	text-transform: uppercase;
}

.st-modal__title {
	margin: 0 0 0.85rem;
	font-family: var(--font-display);
	font-size: clamp(1.6rem, 3vw, 2.1rem);
	font-weight: 400;
	line-height: 1.15;
	letter-spacing: var(--track-claim);
	color: var(--ink);
	text-wrap: balance;
}

/* The italic second line — the design's recurring display gesture. */
.st-modal__title em {
	display: block;
	font-style: italic;
	font-weight: 300;
	color: var(--gold);
}

.st-modal__sub {
	margin: 0 0 1.75rem;
	color: var(--ink-300);
	font-size: var(--fs-small);
	line-height: 1.6;
	text-wrap: pretty;
}

/* Stops the page behind the overlay scrolling under it. Set by the script. */
body.st-modal-open {
	overflow: hidden;
}

@media (max-width: 480px) {
	.st-modal__dialog {
		padding: 2rem 1.35rem;
	}
}
