/* Two homes, one form. Above the mobile threshold the form sits in
   this centered glass popup; below it, menu.js moves .demo-body into
   the nav sheet and the popup is never opened (see menu.js). So the
   rules split accordingly: #demo dresses the popup, .demo-body
   dresses the form itself and travels with it. */
#demo {
	border: var(--hairline) solid var(--rule);
	z-index: 10;
	background-color: var(--glass-dialog-light);
	backdrop-filter: blur(var(--glass-blur));
	color: var(--ink);
	border-radius: var(--radius-dialog);
	/* 35vw through the desktop range (560px at the 1600px design
	   width, unchanged), held between block-stride endpoints: the
	   floor keeps the form usable beside the 4rem side paddings on
	   narrow windows, the ceiling stops it sprawling on wide ones. */
	width: clamp(24rem, 35vw, 36rem);
	padding: var(--space-2) var(--space-4);
	box-shadow: var(--shadow-dialog);
}

/* Centered under the popup's own width; in the sheet the heading is
   ranged left with the links it replaces. */
#demo h1 {
	text-align: center;
}

.demo-body label,
.demo-body p,
.demo-body input,
.demo-body textarea {
	font-size: var(--text-control);
}

.demo-body .button {
	font-family: var(--font-serif);
	background-color: #0000;
	font-size: var(--text-control);
	margin-top: var(--space-2);
	align-self: flex-end;
}

.demo-body .button:hover {
	background-color: var(--ink);
}

.demo-body form {
	display: flex;
	flex-direction: column;
}

.demo-body form label {
	display: block;
}

.demo-body form input,
.demo-body form textarea {
	all: unset;
	border-bottom: var(--hairline) solid var(--ink);
	background-color: #0000;
	resize: none;
	width: 100%;
	padding: var(--space-025) 0;
	margin-bottom: var(--space-1);
}

.demo-body form input::placeholder,
.demo-body form textarea::placeholder {
	color: var(--ink-a63);
}

/* Submission states (demo.js sets data-state on .demo-body, so they
   travel with the form between popup and sheet). Until sent, the
   confirmation stays out of the layout; once sent, it stands in for
   the form and the intro under the same heading. The error line keeps
   the site's quiet register — an italic aside under Send, no third
   color — and the [hidden] attribute governs it. */
.demo-body:not([data-state="sent"]) .demo-done {
	display: none;
}

.demo-body[data-state="sent"] :is(form, .demo-intro) {
	display: none;
}

.demo-body .demo-error {
	font-style: italic;
	margin: var(--space-1) 0 0;
}

/* Mid-flight: Send is out of reach while a request is away. Opacity
   effect, exempt from the grid. */
.demo-body .button:disabled {
	opacity: 0.5;
	pointer-events: none;
}

#demo::backdrop {
	background-color: #0000;
}

/* The page beneath the open popup holds still (the sheet's rule,
   style.css, for the form's other home). */
body:has(#demo[open]) {
	overflow: hidden;
}

#demo {
	opacity: 0;
	transition:
		opacity var(--duration-dialog),
		overlay var(--duration-dialog) allow-discrete,
		display var(--duration-dialog) allow-discrete;
}

#demo[open] {
	opacity: 1;
}

@starting-style {
	#demo[open] {
		opacity: 0;
	}
}

/* The fade is the popup's only motion; under reduced motion it cuts. */
@media (prefers-reduced-motion: reduce) {
	#demo {
		transition: none;
	}
}

/* In the sheet the form takes the panel anchoring and gutter it shares
   with the link list (style.css); all it adds is its own measure, so
   the fields don't run the width of a tablet-sized sheet. Ranged left
   with the links rather than centered, so the swap reads as one
   surface changing its contents. */
#menu .demo-body {
	max-width: 24rem;
}
