/* ==========================================================================
   Newsletter opt-in — v11 "Ironclad"
   --------------------------------------------------------------------------
   The form's BEHAVIOUR is untouched: same fields, same honeypot, same time
   trap, same consent checkbox, same double opt-in, same handler. Only its
   appearance is redesigned.

   What changed, and why:

   The field and the button are ONE JOINED CONTROL — a single bordered row
   with a square red submit welded into its right end — rather than an input
   with a separate pill floating under it. A newsletter form is one action,
   and drawing it as one object is both truer and considerably harder to
   ignore. On the closing slab and in the modal it is the widest thing in its
   column, which is what a form asking for the only input on the page should
   be.

   The submit is a SLAB, not a pill: it carries the same square cut, the same
   capitals and the same tracking as every other button on the site, so the
   newsletter does not look like it was bolted on from a plugin. Below 480px
   the pair unjoins and stacks, because a 120px button inside a 280px field
   leaves no room to read the email being typed.

   Consent is drawn rather than native: a native box cannot be given this
   palette's red or this radius across browsers, and it is the last thing a
   reader looks at before subscribing.

   Three contexts, one component:
     default          on the page ground or a charcoal panel (the sidebar)
     --on-accent      on the red closing slab — white on red
     inside .st-modal the dialog's own plate
   ========================================================================== */

/* The gap is 1.4rem rather than the 0.9rem the spacing alone would want,
   because the email field's error note is positioned OUT of flow under it
   (see .st-optin__field-error) and the gap is what reserves the room it
   needs. Anything tighter and an invalid address prints its message on top
   of the consent checkbox. */
.st-optin {
	display: flex;
	flex-direction: column;
	gap: 1.4rem;
	width: 100%;
}

/* ── The joined field ─────────────────────────────────────────────────
   The input and the submit share one border. The submit is positioned inside
   the row's right edge and the input reserves room for it with padding rather
   than by being a grid cell — so a long email scrolls under the button
   instead of resizing it. */
.st-optin__field {
	display: block;
	width: 100%;
}

.st-optin__field:has(.st-optin__input) {
	position: relative;
}

.st-optin__input {
	width: 100%;
	padding: 1.05rem 10.5rem 1.05rem 1.1rem;
	border: 1px solid var(--line-firm);
	border-radius: var(--r-card);
	background: var(--surface-sink);
	color: var(--ink);
	font-family: var(--font-body);
	font-size: var(--fs-small);
	line-height: 1.4;
	transition: border-color var(--speed) var(--ease), background var(--speed) var(--ease),
		box-shadow var(--speed) var(--ease);
}

.st-optin__input::placeholder {
	color: var(--ink-500);
}

.st-optin__input:focus {
	outline: none;
	border-color: var(--signal);
	background: var(--surface);
	box-shadow: 0 0 0 3px var(--signal-tint);
}

/* The browser's own invalid styling fires while the field is still being
   typed into, so it is scoped to a field the reader has already left. */
.st-optin__input:not(:placeholder-shown):invalid {
	border-color: var(--flag);
}

/* ── Submit ───────────────────────────────────────────────────────────
   Welded into the field's right edge: absolutely positioned, inset by 5px on
   three sides so a hairline of the field's own border still reads around it.
   Square cut and capitalised, like every other control on the site. */
.st-optin__submit {
	position: absolute;
	top: 5px;
	right: 5px;
	bottom: 5px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0 1.4rem;
	border: 0;
	border-radius: 2px;
	background: var(--signal);
	color: #fff;
	font-family: var(--font-body);
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: var(--track-label);
	white-space: nowrap;
	cursor: pointer;
	transition: background var(--speed) var(--ease), box-shadow var(--speed) var(--ease);
}

.st-optin__submit:hover,
.st-optin__submit:focus-visible {
	background: var(--signal-lift);
	box-shadow: var(--glow);
}

.st-optin__submit:active {
	background: var(--signal-deep);
	box-shadow: none;
}

.st-optin__submit:disabled {
	opacity: 0.55;
	cursor: not-allowed;
	box-shadow: none;
}

/* ── The per-field error ──────────────────────────────────────────────
   optin-form.js appends this span INSIDE .st-optin__field, which is also the
   positioning context the submit is anchored to — so left as a plain inline
   element it grows the wrapper and stretches the button with it.

   Taking it out of flow fixes that: the note is absolutely positioned just
   under the field, and the form's own `gap` leaves exactly the room it needs.
   The input's error border is what marks the field itself. */
.st-optin__field {
	position: relative;
}

.st-optin__field-error {
	position: absolute;
	top: calc(100% + 0.3rem);
	left: 0;
	color: var(--flag);
	font-size: var(--fs-micro);
	font-weight: 600;
	line-height: 1.3;
}

.st-optin__field.has-error .st-optin__input,
.st-optin__field.has-error .st-optin__consent-text::before {
	border-color: var(--flag);
}

/* The consent field has no input box to carry the error colour, so its note
   sits in flow under the label rather than being pinned — there is no
   absolutely-positioned sibling to protect here. */
.st-optin__consent .st-optin__field-error {
	position: static;
	display: block;
	margin-top: 0.4rem;
}

.st-optin--on-accent .st-optin__field-error {
	color: #fff;
	text-shadow: 0 1px 2px rgba(10, 10, 12, 0.5);
}

/* Below 480px the joined control comes apart. A button welded into a field
   that is itself only 280px wide leaves nowhere to read the address being
   typed, which is the one thing the reader needs to check before submitting. */
@media (max-width: 480px) {
	.st-optin__input {
		padding-right: 1.1rem;
	}

	.st-optin__submit {
		position: static;
		width: 100%;
		padding: 0.95rem 1.4rem;
		margin-top: 0.6rem;
		border-radius: var(--r-card);
	}
}

/* ── Consent ──────────────────────────────────────────────────────────
   Required, and deliberately not pre-ticked: this is the record that the
   reader agreed, and a pre-ticked box is not consent. */
.st-optin__consent-label {
	display: flex;
	align-items: flex-start;
	gap: 0.6rem;
	cursor: pointer;
}

/* The native input is kept in the DOM and focusable — it is what carries the
   `required` validation and what a screen reader announces — but drawn off
   under the custom box. `opacity:0` rather than `display:none`, which would
   remove it from the tab order and from constraint validation. */
.st-optin__checkbox {
	position: absolute;
	width: 1.1rem;
	height: 1.1rem;
	margin: 0;
	opacity: 0;
	cursor: pointer;
}

.st-optin__consent-text {
	position: relative;
	padding-left: 1.7rem;
	color: var(--ink-400);
	font-size: var(--fs-micro);
	line-height: 1.55;
}

/* The drawn box. A 2px corner — the smallest radius in the design, because at
   18px square anything more reads as a circle. */
.st-optin__consent-text::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.08rem;
	width: 1.1rem;
	height: 1.1rem;
	border: 1px solid var(--line-firm);
	border-radius: 2px;
	background: var(--surface-sink);
	transition: background var(--speed) var(--ease), border-color var(--speed) var(--ease);
}

/* The tick. Drawn as two borders on a rotated box rather than as an SVG or a
   glyph, so it inherits the accent and needs no second asset. */
.st-optin__consent-text::after {
	content: "";
	position: absolute;
	left: 0.38rem;
	top: 0.25rem;
	width: 0.28rem;
	height: 0.55rem;
	border: solid #fff;
	border-width: 0 2px 2px 0;
	transform: rotate(45deg) scale(0);
	transform-origin: center;
	transition: transform 160ms var(--ease);
}

.st-optin__checkbox:checked + .st-optin__consent-text::before {
	background: var(--signal);
	border-color: var(--signal);
}

.st-optin__checkbox:checked + .st-optin__consent-text::after {
	transform: rotate(45deg) scale(1);
}

.st-optin__checkbox:focus-visible + .st-optin__consent-text::before {
	outline: 2px solid var(--signal);
	outline-offset: 2px;
}

.st-optin__consent-text a {
	color: var(--ink-200);
	text-decoration-color: var(--ink-600);
	text-decoration-thickness: 1px;
}

.st-optin__consent-text a:hover {
	color: var(--signal);
	text-decoration-color: currentColor;
}

/* ── The status line ──────────────────────────────────────────────────
   role="status", so it is announced when the handler writes into it. Empty
   until then, and it takes no space while empty — an always-reserved line
   under the button is a permanent gap for a message most readers never see.

   Both states carry a left rule in their own colour rather than a full tint
   wash: at this size a filled block reads as a second button. */
.st-optin__message {
	margin: 0;
	padding: 0.7rem 0.9rem;
	border-left: 3px solid var(--ink-600);
	border-radius: 0 var(--r-card) var(--r-card) 0;
	background: var(--surface-lift);
	color: var(--ink-300);
	font-size: var(--fs-meta);
	line-height: 1.5;
}

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

/* Success is olive, not red: the red on this site means "act", and a
   confirmation is the one message that is asking for nothing. */
.st-optin__message.is-success {
	border-left-color: #8FA86F;
	background: rgba(95, 114, 72, 0.16);
	color: #A8BE8B;
}

.st-optin__message.is-error {
	border-left-color: var(--flag);
	background: var(--flag-tint);
	color: var(--flag);
}

/* The compliance footer that printed the sender's name, postal address and
   support address under every form is gone — see the note in render.php. That
   identity belongs on the email, where email-template.php still carries all
   three. */

/* The honeypot. Hidden from sight and from assistive tech, but present in the
   DOM and fillable, which is the entire point — a bot that fills it is
   rejected. Not `display:none`: some bots skip those. */
.st-optin__hp {
	position: absolute !important;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* ── On the red slab ──────────────────────────────────────────────────
   White on red. The input goes to a dark translucent well rather than a pale
   one — on a saturated red ground a white-tinted field turns pink — and the
   submit inverts to near-black, which is the only fill that reads as a
   control on top of this much red. */
.st-optin--on-accent .st-optin__input {
	border-color: rgba(255, 255, 255, 0.35);
	background: rgba(10, 10, 12, 0.35);
	color: #fff;
}

.st-optin--on-accent .st-optin__input::placeholder {
	color: rgba(255, 255, 255, 0.6);
}

.st-optin--on-accent .st-optin__input:focus {
	border-color: #fff;
	background: rgba(10, 10, 12, 0.5);
	box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.2);
}

.st-optin--on-accent .st-optin__submit {
	background: #0A0A0C;
	color: #fff;
}

.st-optin--on-accent .st-optin__submit:hover,
.st-optin--on-accent .st-optin__submit:focus-visible {
	background: #fff;
	color: var(--signal-deep);
	box-shadow: none;
}

.st-optin--on-accent .st-optin__consent-text {
	color: rgba(255, 255, 255, 0.82);
}

.st-optin--on-accent .st-optin__consent-text::before {
	border-color: rgba(255, 255, 255, 0.5);
	background: rgba(10, 10, 12, 0.25);
}

.st-optin--on-accent .st-optin__checkbox:checked + .st-optin__consent-text::before {
	background: #fff;
	border-color: #fff;
}

/* The tick knocks out in the deep red against the white box. */
.st-optin--on-accent .st-optin__consent-text::after {
	border-color: var(--signal-deep);
}

.st-optin--on-accent .st-optin__checkbox:focus-visible + .st-optin__consent-text::before {
	outline-color: #fff;
}

.st-optin--on-accent .st-optin__consent-text a {
	color: #fff;
	text-decoration-color: rgba(255, 255, 255, 0.5);
}

.st-optin--on-accent .st-optin__consent-text a:hover {
	color: #fff;
	text-decoration-color: #fff;
}

.st-optin--on-accent .st-optin__message,
.st-optin--on-accent .st-optin__message.is-success,
.st-optin--on-accent .st-optin__message.is-error {
	border-left-color: #fff;
	background: rgba(10, 10, 12, 0.3);
	color: #fff;
}

/* ── The modal ────────────────────────────────────────────────────────
   Opened by any [href="#formPopup"]. The dialog is a charcoal plate with a
   red top edge on a near-opaque scrim, entering with one short rise — the
   only non-hover motion on the site besides the marquee. */
.st-modal {
	position: fixed;
	inset: 0;
	z-index: 200;
	display: grid;
	place-items: center;
	padding: var(--gutter);
}

.st-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(4, 4, 6, 0.8);
	-webkit-backdrop-filter: blur(6px);
	backdrop-filter: blur(6px);
}

.st-modal__dialog {
	position: relative;
	width: min(32rem, 100%);
	max-height: 90vh;
	overflow-y: auto;
	padding: clamp(1.75rem, 4vw, 2.5rem);
	border: 1px solid var(--line);
	border-radius: var(--r-panel);
	background: var(--surface);
	box-shadow: var(--shade-panel);
	animation: st-modal-rise 220ms var(--ease) both;
}

/* The red edge, the same mark the guides panel carries — it is what ties a
   dialog that appears over any page back to the design it came from. */
.st-modal__dialog::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 3px;
	border-radius: var(--r-panel) var(--r-panel) 0 0;
	background: var(--signal-grad);
}

@keyframes st-modal-rise {
	from { opacity: 0; transform: translateY(12px); }
	to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
	.st-modal__dialog { animation: none; }
}

.st-modal__close {
	position: absolute;
	top: 0.9rem;
	right: 0.9rem;
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 1px solid var(--line);
	border-radius: var(--r-card);
	background: var(--surface-lift);
	color: var(--ink-300);
	font-size: 1.25rem;
	line-height: 1;
	transition: background var(--speed) var(--ease), color var(--speed) var(--ease),
		border-color var(--speed) var(--ease);
}

.st-modal__close:hover,
.st-modal__close:focus-visible {
	background: var(--signal);
	border-color: var(--signal);
	color: #fff;
}

/* The modal's label, carrying the same capitals and leading rule as every
   other section label on the site. */
.st-modal__kicker {
	display: inline-flex;
	align-items: center;
	gap: 0.55rem;
	margin: 0 0 0.6rem;
	color: var(--signal);
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: var(--track-label);
}

.st-modal__kicker::before {
	content: "";
	width: 1.75rem;
	height: 2px;
	flex: none;
	background: var(--signal);
}

.st-modal__title {
	margin: 0;
	max-width: 18ch;
	font-family: var(--font-display);
	font-size: clamp(1.75rem, 3.5vw, 2.25rem);
	font-weight: 700;
	text-transform: uppercase;
	line-height: 1;
	letter-spacing: var(--track-tight);
	color: var(--ink);
	text-wrap: balance;
}

.st-modal__title em {
	display: block;
	font-style: normal;
	color: var(--signal);
}

.st-modal__sub {
	margin: 0.75rem 0 1.5rem;
	color: var(--ink-400);
	font-size: var(--fs-small);
	line-height: 1.6;
}
