/*
 * Round 7, NAEM-SPEC #9 — newsletter signup (inc/round7-newsletter.php).
 *
 * Loaded on every route, after round5-header.css. Three things live here:
 *   1. the signup form, in its two placements (.r7nl-top, .r7nl-inline);
 *   2. the layout compensations a taller top-of-page region needs, all scoped
 *      to body.has-r7nl-top so a page without the bar is untouched;
 *   3. .announce-ruo — the launch-wording disclaimer bar. It is here rather
 *      than in a sheet of its own because it is six declarations and this is
 *      the only round 7 sheet Lane D owns that loads sitewide.
 *
 * Tokens only: no new colours, no new fonts, token radii, hairline borders.
 */

/* ------------------------------------------------------------ shared parts */

.r7nl { color: var(--muted); font-size: 13px; line-height: 1.5; }
.r7nl p { margin: 0; }

/* The theme's .screen-reader-text only exists in round3.css, which is not
   loaded on every route, so the bar carries its own copy of the pattern. */
.r7nl-sr,
.r7nl-trap {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.r7nl-form { min-width: 0; }

.r7nl-row { display: flex; align-items: center; gap: var(--s3); min-width: 0; }

.r7nl-label { flex: 0 0 auto; color: var(--text); font-size: 13px; font-weight: 600; line-height: 1.3; }

.r7nl-input {
	flex: 1 1 auto;
	width: 100%;
	min-width: 0;
	min-height: 44px;
	padding: 10px 14px;
	/* Same boundary as the checkout fields (round5-checkout.css B6): --line
	   -strong alone is under 3:1 against the panel, which fails the contrast
	   an input's edge needs to be found at all. */
	border: 1px solid color-mix(in srgb, var(--quiet) 55%, var(--line-strong));
	border-radius: var(--r-md);
	background: var(--surface-raised);
	color: var(--text);
	font-family: inherit;
	/* 16px exactly: anything smaller makes iOS Safari zoom the page on focus,
	   and a zoomed page on a bar that sits above the header is a horizontal
	   scroll on every route at once. */
	font-size: 16px;
	line-height: 1.4;
	transition: border-color 160ms var(--ease);
}
.r7nl-input::placeholder { color: var(--quiet); opacity: 1; }
.r7nl-input:focus-visible { border-color: var(--accent); outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.r7nl-input[aria-invalid="true"] { border-color: var(--warn); }

/* .btn already gives the solid teal fill with the dark label; this only pins
   the touch target at 44px (.btn-sm alone is 40) and stops the label wrapping
   when the row gets tight. */
.r7nl .r7nl-submit { flex: 0 0 auto; min-height: 44px; white-space: nowrap; }
.r7nl .r7nl-submit[disabled] { cursor: progress; }

.r7nl-note { color: var(--muted); font-size: 12px; line-height: 1.45; }
.r7nl-note a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }

/* The live region stays in the layout even when empty — a region that is
   display:none at the moment its text changes is not announced by every screen
   reader. Empty, it is a zero-height paragraph and costs nothing. */
.r7nl-status { flex: 0 0 100%; color: var(--text); font-size: 13px; font-weight: 600; line-height: 1.45; }
.r7nl-status.is-ok { color: var(--ok); }
.r7nl-status.is-error { color: var(--warn); }

/* Subscribed: the question is gone, only the answer remains. */
.r7nl-form.is-done .r7nl-row,
.r7nl-form.is-done .r7nl-note { display: none; }

@media (hover: hover) and (pointer: fine) {
	.r7nl-input:hover { border-color: var(--quiet); }
	.r7nl-dismiss:hover { color: var(--text); background: var(--surface-raised); }
}

/* ------------------------------------------------------------ the top bar */

.r7nl-top { border-bottom: 1px solid var(--line); background: var(--band); }

/* Set before first paint by the inline script in the form markup, so a visitor
   who dismissed the bar never sees it arrive and the header never jumps. */
.r7nl-dismissed .r7nl-top { display: none; }

.r7nl-top .r7nl-wrap { display: flex; align-items: center; gap: var(--s3); padding-block: var(--s2); }

.r7nl-top .r7nl-form {
	flex: 1 1 auto;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	/* column-gap only: a row-gap would open a blank line above the empty
	   status region. The parts carry their own small block margins instead. */
	column-gap: var(--s4);
}
.r7nl-top .r7nl-row { flex: 0 1 470px; margin-block: 2px; }
.r7nl-top .r7nl-note { flex: 1 1 250px; margin-block: 2px; }
.r7nl-top .r7nl-status:not(:empty) { margin-block: 2px 4px; }
.r7nl-top .r7nl-form.is-done .r7nl-status { margin-block: 10px; }

.r7nl-dismiss {
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	display: grid;
	place-items: center;
	margin-right: -10px;
	padding: 0;
	border: 0;
	border-radius: var(--r-pill);
	background: transparent;
	color: var(--muted);
	cursor: pointer;
}
/* display:grid above would otherwise beat the hidden attribute the button
   ships with until the script proves it can honour a click. */
.r7nl-dismiss[hidden] { display: none; }

@media (max-width: 680px) {
	/* Stacked and compact: label, then field + button on one line, then the
	   consent note sharing its line with the close control — four short rows
	   instead of five, on the screens where the bar costs the most height. */
	.r7nl-top .r7nl-wrap { position: relative; display: block; padding-block: 6px 2px; }
	.r7nl-top .r7nl-form { display: block; }
	.r7nl-top .r7nl-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px var(--s2); margin: 0; }
	.r7nl-top .r7nl-label { grid-column: 1 / -1; font-size: 12px; }
	.r7nl-top .r7nl-note { min-height: 44px; display: flex; flex-wrap: wrap; align-items: center; column-gap: 6px; margin: 0; padding-right: 44px; }
	.r7nl-top .r7nl-status:not(:empty),
	.r7nl-top .r7nl-form.is-done .r7nl-status { min-height: 44px; display: flex; align-items: center; margin: 0; padding-right: 44px; }
	/* Anchored to the BOTTOM of the bar rather than to a measured offset, so it
	   always rides the last line — the note, an error under it, or the lone
	   answer once subscribed — however the label above happens to wrap. Every
	   line it can land on reserves 44px on the right for it. */
	.r7nl-top .r7nl-dismiss { position: absolute; right: max(10px, calc(var(--mobile-gutter, 20px) - 10px)); bottom: 2px; margin: 0; }
}

/* ------------------------------------------------------- inline placement */

.r7nl-inline {
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--surface);
}
.r7nl-inline .r7nl-wrap { padding: var(--s5); }
.r7nl-inline .r7nl-lede { margin-bottom: var(--s4); color: var(--text); font-size: 18px; font-weight: 600; line-height: 1.3; letter-spacing: -.01em; }
.r7nl-inline .r7nl-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s2) var(--s3); max-width: 560px; }
.r7nl-inline .r7nl-label { grid-column: 1 / -1; }
.r7nl-inline .r7nl-note { margin-top: var(--s3); }
.r7nl-inline .r7nl-status:not(:empty) { margin-top: var(--s3); }
.r7nl-inline .r7nl-form.is-done .r7nl-status { margin-top: 0; }

@media (max-width: 420px) {
	.r7nl-inline .r7nl-wrap { padding: var(--s4); }
	.r7nl-inline .r7nl-row { grid-template-columns: minmax(0, 1fr); }
	.r7nl-inline .r7nl-submit { width: 100%; }
}

/* ------------------------------------- what a taller top region must not break */

/* TABLET NAV. Between 681 and 900px the theme opens the nav panel as
   position:fixed at top: var(--nav-h) — a number that is only right when the
   header is at the very top of the viewport. Above the fold the header sits
   below the announcement AND now this bar, so the fixed panel would open
   ~95px too high and the header (z-index 100 over the panel's 99) would cover
   its first links. Hanging the panel off the header's own bottom edge is right
   at every scroll position; it is what mobile.css already does under 680px,
   which is why this rule stops there. --r7nl-nav-offset is measured by
   round7-newsletter.js when the toggle is pressed, so the panel can still
   scroll inside whatever height is really left under the header. */
@media (min-width: 681px) and (max-width: 900px) {
	body.has-r7nl-top .site-header .primary-nav {
		position: absolute;
		inset: 100% 0 auto;
		max-height: calc(100svh - var(--nav-h) - var(--r7nl-nav-offset, 0px));
		overflow-y: auto;
	}
}

/* DESKTOP HERO. Its height is "the viewport minus 102px" — announcement plus
   header, hard-coded in style.css. With the bar above it that sum is short by
   the bar's height and the hero's lower edge, where the scene controls sit,
   drops under the fold. The script reports the bar's real height; 61px is the
   one-row desktop height, used until it has. Dismissed = no bar = the theme's
   own number applies again. Min-height only, so tall content still grows it. */
@media (min-width: 681px) {
	html:not(.r7nl-dismissed) body.has-r7nl-top .hero {
		min-height: min(900px, calc(100svh - 102px - var(--r7nl-top-h, 61px)));
	}
}

/* ------------------------------------------ launch wording: the RUO banner */

/* header.php grants .announce-ruo only when the launch-wording switch has
   turned the banner into the research-use disclaimer. The base .announce is
   tuned for a four-word uppercase one-liner; a three-sentence legal statement
   in tracked capitals is unreadable on a phone, so it is set as a sentence and
   allowed to wrap evenly. Colours and the hairline are inherited unchanged. */
.announce.announce-ruo {
	padding-block: 8px;
	font-weight: 500;
	line-height: 1.45;
	letter-spacing: 0;
	text-transform: none;
	text-wrap: balance;
}

@media (prefers-reduced-motion: reduce) {
	.r7nl-input { transition: none; }
	/* The theme lifts .btn on hover; inside the bar that lift is the only
	   motion there is, so it goes too. */
	.r7nl .r7nl-submit:hover,
	.r7nl .r7nl-submit:active { transform: none; }
}
