/*
 * Reflection Form — front end.
 *
 * Structure and state only. A form is part of a project's design, so this
 * file sets no typography and no colour scheme: it makes the form WORK and
 * leaves how it looks to the theme's own stylesheet, which can target
 * .reflection-form and everything under it.
 *
 * What is here is what stops being correct if it is removed: the decoy has to
 * be unreachable, an error has to be visible, and a field in error has to be
 * distinguishable by something other than colour.
 *
 * TWO EXCEPTIONS, both in the overlay block at the foot of the file and both
 * stated there: a backdrop colour and a panel background. An overlay without
 * them is not an unstyled overlay, it is a broken one.
 */

/*--------------------------------------------------------------------------------
 * The honeypot.
 *
 * Off-screen rather than display:none or visibility:hidden — a bot worth
 * defending against skips both, and a bot that fills this one is telling us
 * what it is. It stays a real, focusable input in the accessibility tree's
 * eyes, so aria-hidden and tabindex="-1" in the markup are what keep it away
 * from anyone using a screen reader or the keyboard.
 *------------------------------------------------------------------------------*/

.reflection-form-decoy {
	position: absolute !important;
	left: -9999px !important;
	top: auto !important;
	width: 1px !important;
	height: 1px !important;
	overflow: hidden !important;
}

/*--------------------------------------------------------------------------------
 * Layout
 *------------------------------------------------------------------------------*/

.reflection-form-fields {
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
}

.reflection-form-field {
	display: flex;
	flex-direction: column;
	gap: .35rem;
	min-width: 0;
}

.reflection-form-label {
	display: block;
}

/* A consent row reads sentence-first, control beside it. */
.reflection-form-field-consent .reflection-form-control {
	display: flex;
	align-items: flex-start;
	gap: .6rem;
}

.reflection-form-field-consent .reflection-form-label-inline {
	margin: 0;
	cursor: pointer;
}

.reflection-form-boxes {
	display: flex;
	flex-direction: column;
	gap: .4rem;
}

.reflection-form-box-row {
	display: flex;
	align-items: center;
	gap: .5rem;
}

.reflection-form-input,
.reflection-form-select,
.reflection-form-textarea {
	width: 100%;
	box-sizing: border-box;
}

.reflection-form-filename {
	display: inline-block;
	margin-left: .5rem;
	overflow-wrap: anywhere;
}

.reflection-form-footer {
	margin-top: 1.5rem;
	display: flex;
	flex-direction: column;
	gap: .75rem;
	align-items: flex-start;
}

/*--------------------------------------------------------------------------------
 * State
 *
 * currentColor throughout, so a theme that restyles the form does not have to
 * come back and restyle the error states to match. The only thing asserted
 * here is that they are DISTINGUISHABLE — never by hue alone, because a
 * red border is not a message to someone who cannot see red.
 *------------------------------------------------------------------------------*/

.reflection-form-error {
	margin: 0;
	font-size: .875em;
}

.reflection-form-mark {
	text-decoration: none;
	border: 0;
}

.reflection-form-field.is-invalid .reflection-form-input,
.reflection-form-field.is-invalid .reflection-form-select,
.reflection-form-field.is-invalid .reflection-form-textarea {
	outline: 2px solid currentColor;
	outline-offset: 1px;
}

.reflection-form-field.is-invalid .reflection-form-error::before {
	content: "⚠ ";
}

.reflection-form.is-sending {
	opacity: .6;
	pointer-events: none;
}

.reflection-form-submit[disabled] {
	cursor: progress;
}

/*
 * Nothing overrides [hidden]. The script toggles it to show and hide the
 * error slots, and a stylesheet that gives .reflection-form-error a display
 * value would defeat that — the same trap the engine's admin stylesheet closes
 * with its own [hidden] rule.
 */
.reflection-form [hidden] {
	display: none !important;
}

@media (prefers-reduced-motion: reduce) {
	.reflection-form * {
		scroll-behavior: auto !important;
	}
}

/*--------------------------------------------------------------------------------
 * The response overlay.
 *
 * One per page, built by the script and appended to <body> — so it is NOT
 * inside .reflection-form and none of the rules above reach it.
 *
 * This is the one block in the file that carries colour, and it is not the
 * library changing its mind about that. A backdrop with no colour is not a
 * backdrop, and a panel with no background is the editor's sentence printed on
 * top of the page's own text. Both are what makes the thing work rather than
 * what makes it look like anything, which is the test the rest of this file is
 * held to. They are two declarations, easy to find and easy to replace, and a
 * theme that wants its own is expected to.
 *
 * No transition either. The closed state is opacity + visibility rather than
 * [hidden] precisely so a theme can put one on without touching the script:
 * transition opacity on .reflection-form-overlay and it fades.
 *------------------------------------------------------------------------------*/

.reflection-form-overlay {
	position: fixed;
	inset: 0;
	z-index: 9999;

	display: flex;
	align-items: center;
	justify-content: center;
	padding: 1.5rem;
	box-sizing: border-box;

	background: rgba(0, 0, 0, .5);

	/* visibility, not display: it keeps the panel out of the tab order and out
	   of the accessibility tree while closed, and stays animatable. */
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
}

.reflection-form-overlay.is-open {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
}

.reflection-form-overlay-panel {
	position: relative;
	box-sizing: border-box;
	max-width: 32rem;
	width: 100%;

	/* A long sentence on a short screen scrolls inside the panel rather than
	   off the top of it, which is the one place scrolling is still correct. */
	max-height: 100%;
	overflow-y: auto;

	padding: 2rem;
	background: #fff;
}

.reflection-form-overlay-panel > strong {
	display: block;
}

.reflection-form-overlay-panel > p {
	margin: .5rem 0 0;
}

/* Sits in the corner of the panel, out of the text's way. It is the only
   focusable thing in there, which is what makes preventing Tab a complete
   focus trap rather than half of one. */
.reflection-form-overlay-close {
	position: absolute;
	top: .5rem;
	right: .5rem;

	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	line-height: 1;
	padding: .25rem .5rem;
	cursor: pointer;
}

/* The script hides whichever of the title and the sentence the editor left
   empty. Same reason as the rule inside the form: a theme giving these a
   display value would defeat it. */
.reflection-form-overlay [hidden] {
	display: none !important;
}

/* Set on <html> while the overlay is up. The script restores the inline
   padding-right it pairs with this. */
.reflection-form-locked {
	overflow: hidden !important;
}
