/*
 * The Contact form.
 *
 * Ruled, never boxed. Each field is a micro-label over a control over a single
 * hairline, which is the same grammar as the byline ledger and the search field
 * rather than a form style invented for this one page. No card, no panel, no
 * input chrome: the rule is the field.
 *
 * It sits inside the article prose measure, so it reads as part of the page's
 * one column instead of as a widget dropped into it.
 */

.dcv-contact {
	max-width: var(--dcv-measure);
	margin-block: var(--dcv-space-lg) 0;
}

/* --- one field -------------------------------------------------------------- */

.dcv-contact__field {
	display: grid;
	gap: var(--dcv-space-3xs);
	margin: 0 0 var(--dcv-space-md);
}

.dcv-contact__label {
	color: var(--dcv-muted);
	cursor: pointer;
}

.dcv-contact__control {
	width: 100%;
	padding: var(--dcv-space-2xs) 0;
	border: 0;
	border-bottom: 1px solid var(--dcv-line-strong);
	border-radius: 0;
	background: none;
	color: var(--dcv-ink);
	font-family: var(--dcv-font-ui);
	font-size: var(--dcv-text-prose);
	line-height: var(--dcv-leading-ui);
	transition: border-color var(--dcv-duration-fast) var(--dcv-ease);
}

/* The message is the point of the page, so it is given the room to look like it. */
textarea.dcv-contact__control {
	line-height: var(--dcv-leading-prose);
	resize: vertical;
	min-height: 11rem;
}

/* Hover and focus produce the same affordance; focus additionally rings. */
.dcv-contact__control:hover { border-bottom-color: var(--dcv-cat-ink); }

.dcv-contact__control:focus-visible {
	outline: var(--dcv-focus-width) solid var(--dcv-focus-ring);
	outline-offset: var(--dcv-focus-offset);
	border-bottom-color: var(--dcv-cat-ink);
}

.dcv-contact__hint,
.dcv-contact__error {
	font-size: var(--dcv-text-sm);
	line-height: var(--dcv-leading-ui);
}

.dcv-contact__hint { color: var(--dcv-muted); }

.dcv-contact__error {
	color: var(--dcv-cat-ink);
	font-weight: var(--dcv-label-weight);
}

/*
 * An invalid field thickens its own rule. Colour is never the only signal: the
 * error text under the field says what is wrong in words.
 */
.dcv-contact__field--invalid .dcv-contact__control {
	border-bottom-width: 2px;
	border-bottom-color: var(--dcv-cat-ink);
}

/* --- the whole-form alert --------------------------------------------------- */

.dcv-contact__alert {
	margin-bottom: var(--dcv-space-md);
	padding-block: var(--dcv-space-2xs);
	border-block: 1px solid var(--dcv-cat-ink);
	color: var(--dcv-cat-ink);
}

.dcv-contact__alert .dcv-label { margin: 0 0 var(--dcv-space-3xs); }

.dcv-contact__alert-text {
	margin: 0;
	font-size: var(--dcv-text-base);
	color: var(--dcv-ink);
}

/* --- the honeypot ----------------------------------------------------------- */

/*
 * Off-canvas rather than display:none: some crawlers skip what is hidden that
 * way, and the point is that a bot finds it. It is aria-hidden and tabindex=-1
 * in the markup, so no reader and no screen reader ever reaches it.
 */
.dcv-contact__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* --- the action ------------------------------------------------------------- */

.dcv-contact__submit {
	margin: var(--dcv-space-md) 0 0;
}

.dcv-contact__submit .dcv-action { font-family: var(--dcv-font-ui); }

/* --- the success state ------------------------------------------------------ */

/*
 * It replaces the form. The confirmation is set in the display face because it
 * is the one sentence the reader came back for.
 */
.dcv-contact--sent {
	padding-top: var(--dcv-space-sm);
	border-top: 1px solid var(--dcv-line-strong);
}

.dcv-contact__confirm {
	margin: var(--dcv-space-2xs) 0 var(--dcv-space-xs);
	font-family: var(--dcv-font-display);
	font-size: var(--dcv-display-3);
	line-height: var(--dcv-leading-title);
	color: var(--dcv-ink);
}

.dcv-contact__note {
	margin: 0;
	max-width: var(--dcv-measure);
	color: var(--dcv-muted);
	font-size: var(--dcv-text-base);
	line-height: var(--dcv-leading-ui);
}

/* --- the anti-bot widget ---------------------------------------------------- */

/*
 * Turnstile Guard's widget, at the foot of the form and below the action.
 *
 * The plugin reserves 73px for it from the first paint, which is the right
 * default when the widget sits above a submit button: deferred, it mounts at the
 * reader's first focus, and an unreserved widget would push the button down
 * under the pointer. Here the widget is the LAST child of the form, so it can
 * only grow downwards into space nothing is aiming at — and the reservation
 * would instead be a permanent empty block between the button and the end of the
 * page. Released, and taken at the moment the widget is real.
 */
.dcv-contact .tsg-field {
	margin: 0;
	max-width: 100%;
}

.dcv-contact .tsg-field--deferred .tsg-widget {
	min-height: 0;
	max-width: 100%;
}

/* Space is taken once the widget is real, and not a moment before. */
.dcv-contact .tsg-widget:not(:empty) { margin-top: var(--dcv-space-md); }
