.wp-block-amm-dynamic-form-field,
.amm-dynamic-form-field {
	--amm-dff-width: 280px;
	--amm-dff-active-width: var(--amm-dff-width);
	--amm-dff-background: #ffffff;
	--amm-dff-border-color: #e4e4e7;
	--amm-dff-text-color: #18181b;
	--amm-dff-label-color: #52525b;
	display: flex;
	flex: 0 1 var(--amm-dff-active-width);
	flex-direction: column;
	gap: 0.375rem;
	margin: 0;
	max-width: 100%;
	position: relative;
	width: var(--amm-dff-active-width);
}

.amm-dynamic-form-field__label {
	color: var(--amm-dff-label-color);
	font-size: var(--amm-dff-label-size, 0.875rem);
	font-weight: 500;
	line-height: var(--amm-dff-label-line-height, 1.4);
}

.amm-dynamic-form-field__control {
	appearance: none;
	-webkit-appearance: none;
	background: var(--amm-dff-background);
	background-image: none;
	border: 1px solid var(--amm-dff-border-color);
	border-radius: 6px;
	box-sizing: border-box;
	color: var(--amm-dff-text-color);
	font-size: 0.875rem;
	line-height: 1.4;
	margin: 0;
	max-width: 100%;
	/* Read from an ancestor rather than declared on the field itself: the disclosure button is
	   the field's SIBLING, not its child, so a variable declared here could never reach it.
	   Set --amm-dff-min-height on the group or panel and the button and the field it opens
	   rise together — which is what keeps the two interchangeable in one slot. */
	min-height: var(--amm-dff-min-height, 40px);
	padding: 8px 16px;
	width: 100%;
}

.amm-dynamic-form-field select.amm-dynamic-form-field__control {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%2371717a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-position: right 14px center;
	background-repeat: no-repeat;
	background-size: 16px 16px;
	padding-right: 40px;
}

.amm-dynamic-form-field__control::placeholder {
	color: var(--amm-dff-text-color);
	opacity: 0.75;
}

.amm-dynamic-form-field.is-invalid .amm-dynamic-form-field__control {
	border-color: #dc2626;
}

.amm-dynamic-form-field__error {
	color: #dc2626;
	font-size: 0.75rem;
	font-weight: 500;
	line-height: 1.2;
	position: absolute;
	right: 0;
	top: 0;
}

textarea.amm-dynamic-form-field__control {
	min-height: 120px;
	padding-top: 14px;
	padding-bottom: 14px;
	resize: vertical;
}

.amm-dynamic-form-field__autocomplete {
	margin: 0;
	position: relative;
}

.amm-dynamic-form-field__autocomplete-input {
	padding-right: 40px;
}

.amm-dynamic-form-field__autocomplete.is-loading::after {
	content: "...";
}

.amm-dynamic-form-field__autocomplete-results {
	background: var(--amm-dff-background);
	border: 1px solid var(--amm-dff-border-color);
	border-radius: 8px;
	box-shadow: 0 10px 30px rgba(24, 24, 27, 0.12);
	display: block;
	left: 0;
	margin-top: 0.375rem;
	max-height: 16rem;
	overflow-y: auto;
	position: absolute;
	right: 0;
	top: 100%;
	z-index: 20;
}

.amm-dynamic-form-field__autocomplete-option,
.amm-dynamic-form-field__autocomplete-empty {
	background: transparent;
	border: 0;
	color: var(--amm-dff-text-color);
	display: block;
	font-size: 0.875rem;
	line-height: 1.4;
	margin: 0;
	padding: 0.75rem 1rem;
	text-align: left;
	width: 100%;
}

.amm-dynamic-form-field__autocomplete-option {
	cursor: pointer;
}

.amm-dynamic-form-field__autocomplete-option:hover,
.amm-dynamic-form-field__autocomplete-option.is-active {
	background: rgba(24, 24, 27, 0.06);
}

.amm-dynamic-form-field__autocomplete-empty {
	color: var(--amm-dff-label-color);
	cursor: default;
}

/* ---------- disclosure ----------
   A field held behind a labelled button until the visitor asks for it. */

.amm-dynamic-form-field__disclosure {
	--amm-dff-active-width: var(--amm-dff-width);
	/* Reserve the height of the label the revealed field will carry. The button has no label
	   of its own, so without this the row grows by one line the first time a field appears
	   and everything below the form shifts down. Derived from the label's own metrics rather
	   than a measured pixel value, so restyling the label keeps the two in step. */
	margin-top: calc((var(--amm-dff-label-size, 0.875rem) * var(--amm-dff-label-line-height, 1.4)) + 0.375rem);
	background: var(--amm-dff-background, #fff);
	border: 1px solid var(--amm-dff-border-color, #e4e4e7);
	border-radius: 4px;
	color: var(--amm-dff-text-color, inherit);
	cursor: pointer;
	/* Same slot as the field it opens, so swapping one for the other changes nothing about
	   the row. Without this the button sizes to its label and every field revealed shifts
	   whatever follows it. */
	flex: 0 1 var(--amm-dff-active-width);
	font: inherit;
	font-size: 0.9375rem;
	max-width: 100%;
	/* Matches the field control's own min-height: the two swap places in one slot, so a
	   different height here would change the row's height the moment a field is revealed.
	   Same variable, same ancestor, so raising one raises both. */
	min-height: var(--amm-dff-min-height, 40px);
	padding: 0 1.25rem;
	width: var(--amm-dff-active-width);
}

.amm-dynamic-form-field__disclosure:hover {
	border-color: var(--amm-palette-primary-1, #0e5c7a);
	color: var(--amm-palette-primary-1, #0e5c7a);
}

/* Once the field is showing, the button has done its job and would only be competing for
   the same row. It steps out and the field takes the slot; the field's own clear control
   brings it back. */
.amm-dynamic-form-field__disclosure[aria-expanded="true"] {
	display: none;
}

.amm-dynamic-form-field__disclosure:focus-visible {
	outline: 2px solid var(--amm-palette-primary-1, #0e5c7a);
	outline-offset: 2px;
}

/* A revealed field takes the button's place in the row rather than sitting under it, so it
   keeps the row's own alignment and adds no offset of its own. */
.amm-dynamic-form-field__disclosure[aria-expanded="true"] + .amm-dynamic-form-field {
	margin-top: 0;
}

@media (max-width: 767px) {
	.amm-dynamic-form-field__disclosure {
		width: 100%;
	}

	.amm-dynamic-form-field__disclosure[aria-expanded="true"] + .amm-dynamic-form-field {
		margin-top: 0;
	}
}

/* ---------- grouped suggestions ----------
   Emitted only when the payload carries groups; a flat suggestion list is unaffected. */

.amm-dynamic-form-field__autocomplete-group {
	color: var(--amm-dff-label-color);
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	padding: 0.75rem 1rem 0.25rem;
	text-transform: uppercase;
}

.amm-dynamic-form-field__autocomplete-option:has(.amm-dynamic-form-field__autocomplete-meta) {
	align-items: baseline;
	display: flex;
	gap: 1rem;
	justify-content: space-between;
}

.amm-dynamic-form-field__autocomplete-label {
	min-width: 0;
}

/* The matched run is marked up rather than recoloured, so the emphasis survives high-contrast
   modes and does not rely on colour alone. */
.amm-dynamic-form-field__autocomplete-label mark {
	background: none;
	color: inherit;
	font-weight: 700;
}

.amm-dynamic-form-field__autocomplete-meta {
	color: var(--amm-dff-label-color);
	flex: 0 0 auto;
	font-size: 0.8125rem;
	white-space: nowrap;
}

.amm-dynamic-form-field__autocomplete-option.is-view-all {
	border-top: 1px solid var(--amm-dff-border-color);
	font-weight: 600;
	margin-top: 0.25rem;
}

.amm-dynamic-form-field__hidden-preview {
	align-items: center;
	background: rgba(24, 24, 27, 0.04);
	border: 1px dashed var(--amm-dff-border-color);
	border-radius: 6px;
	color: var(--amm-dff-label-color);
	display: flex;
	font-size: 0.875rem;
	min-height: 40px;
	padding: 0.5rem 0.75rem;
}

.amm-dynamic-form-field[data-amm-df-security="true"] {
	position: absolute;
	left: -10000px;
	width: 1px;
	height: 1px;
	overflow: hidden;
	flex: 0 0 0;
	margin: 0;
	padding: 0;
	opacity: 0;
	pointer-events: none;
}

.amm-dynamic-form-field[data-amm-df-conditional-hidden="true"] {
	display: none;
}

.amm-dynamic-form-field__checkbox {
	align-items: flex-start;
	cursor: pointer;
	display: flex;
	gap: 0.625rem;
	margin: 0;
	min-height: 0;
	width: 100%;
}

.amm-dynamic-form-field__control--checkbox {
	accent-color: var(--amm-palette-primary-1, #005762);
	align-self: flex-start;
	appearance: auto;
	-webkit-appearance: checkbox;
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	flex-shrink: 0;
	height: 1.125rem;
	margin: 0.125rem 0 0;
	min-height: 1.125rem !important;
	padding: 0 !important;
	width: 1.125rem;
}

.amm-dynamic-form-field__checkbox-text {
	color: var(--amm-dff-text-color);
	flex: 1;
	font-size: 0.875rem;
	font-weight: 400;
	line-height: 1.4;
	margin: 0;
	padding: 0;
}

.amm-dynamic-form-field.is-invalid .amm-dynamic-form-field__control--checkbox {
	outline: 2px solid #dc2626;
	outline-offset: 2px;
}

.amm-dynamic-form-field__control:disabled {
	cursor: not-allowed;
	opacity: 0.6;
}

/* Out of sight, still announced. It leaves the flow, so the field loses the label's line:
   use it on a field whose placeholder already carries the label, not on one behind a
   disclosure button — that button reserves the label's height on the assumption it is there. */
.amm-dynamic-form-field--label-hidden .amm-dynamic-form-field__label {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

/* Announces dependent-option changes without taking up layout space. */
.amm-dynamic-form-field__status {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

@media (min-width: 768px) and (max-width: 1023px) {
	.wp-block-amm-dynamic-form-field,
	.amm-dynamic-form-field,
	.amm-dynamic-form-field__disclosure {
		--amm-dff-active-width: var(--amm-dff-width-tablet, var(--amm-dff-width));
	}
}

@media (max-width: 767px) {
	.wp-block-amm-dynamic-form-field,
	.amm-dynamic-form-field {
		--amm-dff-active-width: var(--amm-dff-width-mobile, var(--amm-dff-width));
		flex-basis: auto;
		width: var(--amm-dff-active-width);
	}

	.amm-dynamic-form-field__disclosure {
		--amm-dff-active-width: var(--amm-dff-width-mobile, var(--amm-dff-width));
		flex-basis: auto;
	}

	.amm-dynamic-form-group[data-amm-dfg-mobile-gap-zero="true"] .wp-block-amm-dynamic-form-field[data-amm-dff-mobile-full-width="true"],
	.amm-dynamic-form-group[data-amm-dfg-mobile-gap-zero="true"] .amm-dynamic-form-field[data-amm-dff-mobile-full-width="true"],
	.amm-dynamic-form-group[data-amm-dfg-single-field-submit="true"] .wp-block-amm-dynamic-form-field[data-amm-dff-mobile-full-width="true"],
	.amm-dynamic-form-group[data-amm-dfg-single-field-submit="true"] .amm-dynamic-form-field[data-amm-dff-mobile-full-width="true"] {
		margin-bottom: 16px;
	}

	/* The same spacing the field above gets, so swapping a button for its field leaves the
	   stack the same height. On mobile the button is full width, so it always applies. */
	.amm-dynamic-form-group[data-amm-dfg-mobile-gap-zero="true"] .amm-dynamic-form-field__disclosure,
	.amm-dynamic-form-group[data-amm-dfg-single-field-submit="true"] .amm-dynamic-form-field__disclosure {
		margin-bottom: 16px;
	}
}

/* ---------- autocomplete panel ----------
   The rich suggestion panel: a card grid rather than a list of rows. Everything here is
   scoped to .is-panel, which only the finder's search field sets, so the compact list the
   header search and every other autocomplete use is untouched. */

.amm-dynamic-form-field__autocomplete-results.is-panel {
	/* The list caps at 16rem and scrolls after roughly four rows. A panel is meant to be read
	   whole, so it sizes to its content and only scrolls when the viewport cannot hold it.
	   The outer max() is a floor: on a very short viewport the subtraction goes negative, and
	   without it the panel would collapse to nothing rather than simply scrolling. */
	max-height: max(16rem, min(34rem, calc(100vh - 12rem)));
	padding: 0.5rem 0 0.25rem;
}

.amm-dynamic-form-field__autocomplete-grid {
	display: grid;
	gap: 0.5rem;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	padding: 0 1rem 0.75rem;
}

.amm-dynamic-form-field__autocomplete-results.is-panel
	.amm-dynamic-form-field__autocomplete-option {
	border: 1px solid var(--amm-dff-border-color);
	border-radius: 6px;
	display: flex;
	padding: 0.75rem;
	width: auto;
}

/* Only the list is a single column. Cards and chips keep the three-column grid above, which is
   what the entry-point finder uses — it owns its whole screen. The results-page field asks the
   endpoint for the list presentation instead, because there a card grid covers the results it
   sits above and overruns the panel's 544px ceiling. */
.amm-dynamic-form-field__autocomplete-results.is-panel
	.amm-dynamic-form-field__autocomplete-grid.is-list {
	grid-template-columns: minmax(0, 1fr);
}

/* One line per row. Stacking the name above the meta made every row 66px, so ten suggestions
   overran the panel exactly as the card grid had — the list has to be a list. The meta sits on
   the right and is allowed to shrink and ellipsise; on a code row that means the range is cut
   after a few entries, which is why the matched code is sorted to the front of it. */
.amm-dynamic-form-field__autocomplete-results.is-panel
	.amm-dynamic-form-field__autocomplete-grid.is-list
	.amm-dynamic-form-field__autocomplete-option {
	align-items: baseline;
	flex-direction: row;
	gap: 0.75rem;
	justify-content: space-between;
	padding: 0.5rem 0.75rem;
	text-align: left;
}

.amm-dynamic-form-field__autocomplete-results.is-panel
	.amm-dynamic-form-field__autocomplete-grid.is-list
	.amm-dynamic-form-field__autocomplete-label {
	flex: 0 1 auto;
	font-weight: 600;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.amm-dynamic-form-field__autocomplete-results.is-panel
	.amm-dynamic-form-field__autocomplete-grid.is-list
	.amm-dynamic-form-field__autocomplete-meta {
	flex: 0 1 auto;
	min-width: 0;
	overflow: hidden;
	text-align: right;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.amm-dynamic-form-field__autocomplete-option.is-card {
	align-items: center;
	gap: 0.75rem;
	text-align: left;
}

.amm-dynamic-form-field__autocomplete-card-media {
	align-items: center;
	display: flex;
	flex: 0 0 auto;
	height: 3.25rem;
	justify-content: center;
	overflow: hidden;
	width: 3.25rem;
}

.amm-dynamic-form-field__autocomplete-card-media img {
	height: 100%;
	object-fit: contain;
	width: 100%;
}

.amm-dynamic-form-field__autocomplete-card-body {
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
	min-width: 0;
}

.amm-dynamic-form-field__autocomplete-card-line {
	color: var(--amm-dff-label-color);
	font-size: 0.8125rem;
	line-height: 1.35;
}

.amm-dynamic-form-field__autocomplete-option.is-chip {
	align-items: center;
	background: rgba(24, 24, 27, 0.03);
	font-weight: 600;
	justify-content: center;
	min-height: 3rem;
	text-align: center;
}

.amm-dynamic-form-field__autocomplete-option.is-chip.is-active {
	background: rgba(24, 24, 27, 0.06);
}

/* The view-all row leaves the grid and reads as a link, not a bordered option. */
.amm-dynamic-form-field__autocomplete-results.is-panel
	.amm-dynamic-form-field__autocomplete-option.is-view-all {
	background: none;
	border: 0;
	border-radius: 0;
	/* The palette variable every other accent in this file uses. The neutral default belongs
	   to the plugin; an instance sets --amm-palette-primary-1 to its own brand colour. A
	   brand's literal hex must never be the fallback here — this component ships to every
	   ammweb instance, not one of them. */
	color: var(--amm-palette-primary-1, #0e5c7a);
	margin: 0;
	padding: 0.25rem 1rem 0.75rem;
	width: 100%;
}

.amm-dynamic-form-field__autocomplete-results.is-panel
	.amm-dynamic-form-field__autocomplete-option.is-view-all:hover,
.amm-dynamic-form-field__autocomplete-results.is-panel
	.amm-dynamic-form-field__autocomplete-option.is-view-all.is-active {
	text-decoration: underline;
}

@media (max-width: 900px) {
	.amm-dynamic-form-field__autocomplete-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 600px) {
	.amm-dynamic-form-field__autocomplete-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* ---------- disclosure clear ----------
   Restores the button that opened the field. It exists because the button hides while the
   field is showing, and without it a disclosure could be opened but never closed. */

.amm-dynamic-form-field__disclosure-clear {
	background: none;
	border: 0;
	color: var(--amm-dff-label-color);
	cursor: pointer;
	font: inherit;
	font-size: 0.75rem;
	line-height: 1;
	padding: 0;
	position: absolute;
	right: 0;
	top: 0;
}

.amm-dynamic-form-field__disclosure-clear:hover {
	color: var(--amm-palette-primary-1, #0e5c7a);
	text-decoration: underline;
}

.amm-dynamic-form-field__disclosure-clear:focus-visible {
	outline: 2px solid var(--amm-palette-primary-1, #0e5c7a);
	outline-offset: 2px;
}

/* ---------- panel loading state ----------
   Placeholder cards while a request is in flight. The panel used to set aria-busy and show
   nothing, so a slow connection was indistinguishable from a search that had failed. */

.amm-dynamic-form-field__autocomplete-grid.is-skeleton {
	pointer-events: none;
}

.amm-dynamic-form-field__autocomplete-skeleton {
	background: linear-gradient(90deg, rgba(24, 24, 27, 0.05) 25%, rgba(24, 24, 27, 0.09) 37%, rgba(24, 24, 27, 0.05) 63%);
	background-size: 400% 100%;
	border-radius: 6px;
	display: block;
	min-height: 68px;
}

/* The shimmer is decoration; anyone who has asked for less motion just gets the flat block. */
@media (prefers-reduced-motion: no-preference) {
	.amm-dynamic-form-field__autocomplete-skeleton {
		animation: amm-dff-skeleton 1.3s ease-in-out infinite;
	}
}

@keyframes amm-dff-skeleton {
	0% { background-position: 100% 50%; }
	100% { background-position: 0 50%; }
}

/* The empty state can carry routes now, so it needs room to breathe above them. */
.amm-dynamic-form-field__autocomplete-results.is-panel
	.amm-dynamic-form-field__autocomplete-empty {
	padding-bottom: 0.5rem;
}
