/**
 * Etch Form Builder — runtime styles (base layout + state).
 *
 * The form's BASE LOOK ships here, not in Etch block-CSS: Etch does NOT emit a
 * component's internal block-CSS onto a host page (proven 2026-06-27 — see
 * docs/SESSION-HANDOFF.md + docs/ETCH-BLOCK-CSS-EMISSION.md), so block-CSS rules
 * never reach the published form. runtime.css is enqueued on every page and DOES
 * emit, so the classes the generator attaches (.etchform*) are styled here.
 * Uses ACSS tokens with safe fallbacks so it blends with the site.
 *
 * Trade-off: these base rules are not canvas-editable in Etch. Per-project visual
 * tweaks belong in the site's own CSS/ACSS, which override these via specificity
 * or source order. (For canvas-editable form styling the form must be authored as
 * page-level blocks, not a component — see the handoff "Path B".)
 */

/* ---- Base layout ---- */
.etchform {
	max-width: 40rem;
	margin-inline: auto;
}

.etchform__form {
	display: flex;
	flex-direction: column;
	gap: var(--space-m, 1.25rem);
	padding: var(--space-l, 2rem);
	background: var(--base-ultra-light, #fff);
	border: 1px solid var(--border-color-light, #e4e4e7);
	border-radius: var(--radius, 14px);
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 8px 24px rgba(0, 0, 0, 0.04);
}

.etchform__head {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	margin-block-end: 0.25rem;
}

.etchform__heading {
	margin: 0;
	line-height: 1.15;
}

.etchform__description {
	margin: 0;
	color: var(--text-muted, #555);
}

/* Single-column base; the @container rule below upgrades to two columns when wide. */
.etchform__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-m, 1.25rem);
}

.etchform__field {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
}

/* Stage 4 conditional logic: the runtime (rules.js + runtime.js's setupVisibility) toggles the
   NATIVE `hidden` attribute on a conditioned field's wrapper rather than a custom class, to avoid
   any specificity fight with 3rd-party/theme CSS. But `.etchform__field` above already sets its
   own `display: flex` (specificity 0,1,0), which otherwise beats the UA stylesheet's `[hidden]
   { display: none }` rule — so without this rule a hidden field's wrapper would stay visible
   despite the `hidden` attribute. This selector (0,2,0) wins over the base rule regardless of
   source order, and `display: none` also removes the field from the `.etchform__grid` layout
   above (desired — no leftover gap). */
.etchform__field[hidden] {
	display: none;
}

.etchform__label {
	font-weight: 600;
	font-size: var(--fs-sm, 0.9rem);
	line-height: 1.2;
}

.etchform__control {
	width: 100%;
	font: inherit;
	font-size: var(--fs-body, 1rem);
	line-height: 1.4;
	padding: 0.7em 0.9em;
	color: var(--base-ultra-dark, #18181b);
	background: #fff;
	border: 1px solid var(--border-color, #cbced4);
	border-radius: var(--radius, 10px);
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.etchform__control--area {
	min-height: 8rem;
	resize: vertical;
}

/* Choice groups (radio / checkbox) — a reset fieldset holding stacked options. */
.etchform__group {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	min-inline-size: 0;
	margin: 0;
	padding: 0;
	border: 0;
}

.etchform__option {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	font-weight: 400;
	font-size: var(--fs-body, 1rem);
	line-height: 1.3;
}

.etchform__option input {
	flex: none;
	margin: 0;
}

/* Per-field help / description text, shown under the control. */
.etchform__help {
	margin: 0;
	color: var(--text-muted, #555);
	font-size: var(--fs-sm, 0.9rem);
	line-height: 1.35;
}

.etchform__submit {
	align-self: flex-start;
	margin-block-start: 0.25rem;
}

/* Same specificity rationale as .etchform__field[hidden]/.etchform__step[hidden] below: the
   generator (CLASS_MAP) also gives the submit button theme utility classes (`btn`, `btn--primary`)
   so it matches the site's own button styling — but on a theme whose `.btn` sets its own
   `display` (e.g. Automatic.css's `display: flex`), that beats the UA stylesheet's bare
   `[hidden] { display: none }` rule, so runtime.js's `submitBtn.hidden = !isLast` (stepped forms)
   had no visible effect: the button stayed clickable on non-final steps. */
.etchform__submit[hidden] {
	display: none;
}

/* Captcha widget container, between the fields grid and the submit button. Sizing is the
   provider script's own widget (or empty, pre-render/no-sitekey); same spacing as .etchform__submit
   above, its neighbour in source order. */
.etchform__captcha {
	margin-block-start: 0.25rem;
}

/* Rich text (wysiwyg) fallback. The textarea also carries .etchform__control/--area (same
   data-ef-control special case every textarea gets), which already supplies border/padding —
   this rule exists for when the site setting is OFF and .etchform__rich is all a visitor sees:
   it must look like an intentional control on its own, not rely on that other class always
   being present. The TinyMCE-on path is styled by TinyMCE's own UI once the setting is enabled. */
.etchform__rich {
	border: 1px solid var(--border-color, #cbced4);
	border-radius: var(--radius, 10px);
}

.etchform__rich:focus {
	outline: none;
	border-color: var(--primary, #2563eb);
	box-shadow: 0 0 0 3px color-mix( in srgb, var(--primary, #2563eb) 22%, transparent );
}

/* File/image upload (Stage B). The wrapper (.etchform__file, attached from data-ef-file — see
   blueprint.js's CLASS_MAP) holds the visible <input type="file"> plus an invisible
   <input type="hidden"> that carries the upload ref once runtime.js's setupFileUpload() writes
   it (and is also where a failed-upload .etchform__error note lands, via
   `(input.parentNode || form).appendChild(...)` in showFieldErrors — input.parentNode is this
   wrapper). Neither input carries .etchform__control: that class is reserved for controls
   marked data-ef-control, which a file field's own attrs never include (it has no scalar text
   value that class's styling is meant for) — so the file input gets the same
   border/radius/focus-ring language directly, using the identical tokens .etchform__control and
   .etchform__rich already use, rather than inventing new ones. */
.etchform__file {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
}

.etchform__file input[type="file"] {
	width: 100%;
	font: inherit;
	font-size: var(--fs-body, 1rem);
	color: var(--base-ultra-dark, #18181b);
	background: #fff;
	border: 1px solid var(--border-color, #cbced4);
	border-radius: var(--radius, 10px);
	padding: 0.6em 0.9em;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.etchform__file input[type="file"]:focus {
	outline: none;
	border-color: var(--primary, #2563eb);
	box-shadow: 0 0 0 3px color-mix( in srgb, var(--primary, #2563eb) 22%, transparent );
}

.etchform__hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* Stage 5a multi-step forms. A step wraps its own fields one level inside .etchform__grid, so
   it needs the SAME grid treatment .etchform__grid itself gets (single column here, upgraded to
   12 columns in the @container block below) — otherwise its children sit inside a flex
   container with no grid ancestor to apply their span-N classes against, and silently stack
   full-width regardless of configured width (PR #85 review finding #0). */
.etchform__step {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-m, 1.25rem);
}

/* Same specificity rationale as .etchform__field[hidden] above: a bare UA `[hidden]` rule would
   already be beaten by the flex `display` this class sets, so it needs its own override. */
.etchform__step[hidden] {
	display: none;
}

.etchform__progress {
	display: flex;
	gap: var(--space-s, 0.75rem);
	margin-block-end: var(--space-m, 1rem);
}

.etchform__progress-item {
	flex: 1;
	padding-block-end: 0.4rem;
	border-block-end: 2px solid var(--border-color-light, #e4e4e7);
	color: var(--text-muted, #555);
	font-size: var(--fs-sm, 0.9rem);
	text-align: center;
}

.etchform__progress-item--active {
	border-color: var(--primary, #2563eb);
	color: var(--base-ultra-dark, #18181b);
	font-weight: 600;
}

.etchform__progress-item--done {
	border-color: var(--success, #198754);
}

.etchform__stepnav {
	display: flex;
	justify-content: space-between;
	gap: var(--space-s, 0.75rem);
	margin-block-start: 0.25rem;
}

/* ---- Runtime-injected state ---- */
.etchform__message {
	padding: var(--space-s, 0.75rem) var(--space-m, 1rem);
	border-radius: var(--radius, 8px);
	margin-block-end: var(--space-m, 1rem);
	font-size: var(--fs-sm, 0.95rem);
	line-height: 1.4;
}

.etchform__message--success {
	color: var(--success-dark, #0f5132);
	background: var(--success-trans-10, #d1e7dd);
	border: 1px solid var(--success, #198754);
}

.etchform__message--error {
	color: var(--danger-dark, #842029);
	background: var(--danger-trans-10, #f8d7da);
	border: 1px solid var(--danger, #dc3545);
}

.etchform__error {
	display: block;
	margin-block-start: 0.3rem;
	color: var(--danger, #dc3545);
	font-size: var(--fs-xs, 0.85rem);
	line-height: 1.3;
}

/* Focus ring. Pseudo rules do not compile into an Etch component via the Public
   API, so the generated form's :focus state ships here with the plugin. */
.etchform__control:focus {
	outline: none;
	border-color: var(--primary, #2563eb);
	box-shadow: 0 0 0 3px color-mix( in srgb, var(--primary, #2563eb) 22%, transparent );
}

.etchform__control.is-error,
.is-error {
	border-color: var(--danger, #dc3545) !important;
}

[type="submit"].is-busy {
	opacity: 0.65;
	cursor: progress;
}

/* Responsive field layout — progressive enhancement.
   The generated form wraps its fields in .etchform__grid (single column by default,
   set in the base section above). Where container queries are supported, the grid
   becomes two columns once the form itself is wide enough, regardless of screen width —
   so it adapts in a narrow sidebar as well as a wide main column. Textareas span the
   full width. Old browsers keep the single column. */
@supports (container-type: inline-size) {
	.etchform__form {
		container-type: inline-size;
	}

	@container (min-width: 28rem) {
		/* Selector is more specific than the base .etchform__grid above, so the multi-column
		   upgrade wins regardless of source order. The 28rem breakpoint is measured against
		   the form CONTENT box (.etchform max-width 40rem minus .etchform__form padding, both
		   set in the base section above); keep it well under that. A 12-column track lets each
		   field claim a per-field span (default full). grid-auto-flow:dense backfills the gap a
		   full-width field would otherwise leave when it sits mid-list. */
		.etchform__form .etchform__grid,
		.etchform__form .etchform__step {
			grid-template-columns: repeat(12, minmax(0, 1fr));
			grid-auto-flow: dense;
		}

		/* A step is itself an item of the OUTER .etchform__grid — without an explicit span it
		   would auto-place into a single 1/12 track (a thin sliver) instead of spanning the full
		   width it needs in order to host its own nested 12-column grid above. */
		.etchform__step { grid-column: 1 / -1; }

		/* A step's own children are not always fields: ConfigMigrator's reconciliation also
		   allows a heading/divider/text-block or a nested section directly inside a step (the
		   canvas UI doesn't expose adding one there yet, but a REST-authored config can). Only
		   .etchform__field gets an explicit span below — every other direct child needs the same
		   full-width span .etchform__field itself gets, or it falls back to the grid's default
		   single-track auto-placement and renders squeezed into a sliver. */
		.etchform__step > :not(.etchform__field) { grid-column: 1 / -1; }

		/* Default = full width; the per-field span modifiers (attached by the generator from the
		   field's width, 1–12) override via equal specificity + later source order. */
		.etchform__field { grid-column: span 12; }
		.etchform__field--span-1 { grid-column: span 1; }
		.etchform__field--span-2 { grid-column: span 2; }
		.etchform__field--span-3 { grid-column: span 3; }
		.etchform__field--span-4 { grid-column: span 4; }
		.etchform__field--span-5 { grid-column: span 5; }
		.etchform__field--span-6 { grid-column: span 6; }
		.etchform__field--span-7 { grid-column: span 7; }
		.etchform__field--span-8 { grid-column: span 8; }
		.etchform__field--span-9 { grid-column: span 9; }
		.etchform__field--span-10 { grid-column: span 10; }
		.etchform__field--span-11 { grid-column: span 11; }
		.etchform__field--span-12 { grid-column: span 12; }

		/* A textarea always claims the full row (its :has() specificity beats the span classes). */
		.etchform__field:has(textarea) {
			grid-column: 1 / -1;
		}
	}
}

/* :has()-driven validation feedback, no JavaScript required. :user-invalid only flags a
   field after the user has interacted with it (unlike :invalid), so untouched required
   fields don't look wrong before the user has tried to submit. The `:not(:focus)` guard
   yields to the :focus border so an actively-edited field isn't flagged red mid-typing. */
.etchform__control:user-invalid:not(:focus) {
	border-color: var(--danger, #dc3545);
}

.etchform__field:has(.etchform__control:user-invalid:not(:focus)) .etchform__label {
	color: var(--danger, #dc3545);
}
