/**
 * FORMS
 *
 * Conventions, principles, naming family, and migration status:
 *   docs/development/forms-conventions.md
 * Live specimen:
 *   /design-system/controls/forms
 *
 * Two systems coexist in this file during migration:
 *
 *   <input-field>       — current. Autonomous custom-element wrapper.
 *                         See the <input-field> section below.
 *
 *   .field / .field-inline / form :where(input, textarea, select)…
 *                       — legacy. Used by login-form.php and a few admin
 *                         tools. Retires once those migrate.
 */

:root {
	--control-fill: var(--fill-primary);
	--control-padding: 0.6em 0.8em;
	--control-border: 1px solid var(--stroke-primary);
	--control-radius: 0px;

	/* Focus ring shared by every control — buttons, featured actions,
	   inline links, text inputs, textareas, choice labels. Override
	   inside a mise-en-mode scope to retune the whole system. */
	--control-focus-ring: 3px solid var(--accent);
	--control-focus-offset: 2px;

	--field-gap: 1.5rem;
}

/* ===== BUTTONS =====
 *
 * Cross-browser-consistent native-feel button. Reads chrome / content
 * tokens from its scope, so it adapts to [data-ui='app'] dark mode and
 * any palette without changes. The slight bevel (gradient + inset
 * highlight + outer shadow) gives the skeuomorphic browser-button feel.
 *
 * Older browsers without color-mix or gradients fall back to the flat
 * --fill-secondary declaration above the gradient.
 *
 * Buttons that want to drop all chrome (icon buttons, kebab summaries):
 * use .unstyled.
 */

button {
	font:           inherit;
	color:          var(--ink-primary);
	background:     var(--fill-secondary);
	background:     linear-gradient(
		to bottom,
		color-mix(in oklch, var(--fill-primary) 85%, white) 0%,
		var(--fill-secondary) 100%
	);
	border:         1px solid var(--stroke-primary);
	border-radius:  4px;
	padding:        0.3em 0.8em;
	cursor:         pointer;
	user-select:    none;
	-webkit-user-select: none;
	box-shadow:
		inset 0 1px 0 rgb(255 255 255 / 0.4),
		0 1px 0 rgb(0 0 0 / 0.05);

	&:hover {
		background: linear-gradient(
			to bottom,
			color-mix(in oklch, var(--fill-primary) 92%, white) 0%,
			color-mix(in oklch, var(--fill-secondary) 92%, var(--fill-auxiliary)) 100%
		);
	}

	&:active {
		background: var(--fill-auxiliary);
		box-shadow:
			inset 0 1px 2px rgb(0 0 0 / 0.1),
			0 1px 0 rgb(0 0 0 / 0.02);
	}

	&:focus-visible,
	&[data-fakestate='focused'] {
		outline: var(--control-focus-ring);
		outline-offset: var(--control-focus-offset);
	}

	&:disabled {
		opacity: 0.5;
		cursor: not-allowed;
	}

	&.unstyled {
		all: unset;
		cursor: pointer;
	}
}



form {
	/* max-width: 28rem; */
	display: grid;
	gap: 1rem;
}

form > header {
	margin-bottom: 0.5rem;

	.teaser {
		color: var(--ink-secondary);
		margin-top: 0.25em;
	}
}

.field {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	margin: 0;
}

.field-inline {
	flex-direction: row;
	align-items: center;
	gap: 0.5rem;
}

form label {
	font-family: var(--font-ui);
	font-size: 0.875rem;
	font-weight: 500;
	color: var(--ink-primary);
	margin: 0;
}

/* Text-style form controls. The carveout list (checkbox/radio/submit/button/hidden)
   sits inside :where() so the whole selector stays at specificity 0,0,0,1 — state
   overrides like :disabled, :invalid, :focus stack cleanly without a fight. */
form :where(input, textarea, select):where(:not([type='checkbox']):not([type='radio']):not([type='submit']):not([type='button']):not([type='hidden'])) {
	font: inherit;
	padding: var(--control-padding);
	border: var(--control-border);
	border-radius: var(--control-radius);
	background: var(--fill-primary, white);
	color: var(--ink-primary);
	width: 100%;
}

form :where(input, textarea, select):where(:not([type='checkbox']):not([type='radio']):not([type='submit']):not([type='button']):not([type='hidden'])):disabled {
	background: var(--fill-secondary);
}

form :where(input, textarea, select):focus-visible {
	outline: 2px solid var(--accent, currentColor);
	outline-offset: 1px;
}

.actions {
	display: flex;
	gap: 0.5rem;
	margin-top: 0.5rem;
}

form .lost-password {
	font-size: 0.875rem;
	margin: 0;
	color: var(--ink-secondary);
}


/* ============================================================
   <input-field> — autonomous custom-element wrapper
   ============================================================

   The new form-control system. Scoped to <input-field> only —
   nothing here touches plain <input>, <textarea>, <button>, or
   <select> outside the wrapper. Buttons stay browser-default
   (or opt into data-action='featured' from components.css).

   Variants live on the wrapper:
     <input-field class='text'>           text input
     <input-field class='textarea'>       textarea
     <input-field class='choice radio'>   radio group
     <input-field class='choice checkbox'> checkbox group / single

   Two label patterns inside:
     text/textarea  <label for> sibling
     choice         <label class='option'> wraps input + <span class='label'>

   See /design-system/controls/forms for the kitchen sink.
   ============================================================ */


/* Wrapper — block, label stacks above control */
input-field {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	margin: 0;

	accent-color: var(--accent);
}


/* Primary label (text / textarea sibling pattern) */
input-field > label {
	font-family: var(--font-ui);
	font-size: 0.875rem;
	font-weight: 500;
	color: var(--ink-secondary);
}


/* Helper text below the control. Can include links. */
input-field > .field-help {
	margin: 0;
	max-width: none;
	font-family: var(--font-ui);
	font-size: 0.875rem;
	line-height: 1.4;
	color: var(--ink-secondary);
}


/* Text input + textarea — share padding/border/radius/font from control tokens */
input-field > input,
input-field > textarea {
	font: inherit;
	padding: var(--control-padding);
	border: var(--control-border);
	border-radius: var(--control-radius);
	background: var(--control-fill, white);
	color: var(--ink-primary);
	width: 100%;
}

input-field > textarea {
	min-height: 4lh;
	resize: vertical;
}

input-field > input:focus-visible,
input-field > input[data-fakestate='focused'],
input-field > textarea:focus-visible,
input-field > textarea[data-fakestate='focused'] {
	outline: var(--control-focus-ring);
	outline-offset: var(--control-focus-offset);
}


/* Choice variant — radio / checkbox */

input-field.choice fieldset {
	border: 0;
	padding: 0;
	margin: 0;
}

/* Options live in <ul class='choice-list'> so AT announces "list of N
   items" up front (and the count is scannable in markup). The class is
   the explicit "this is a list of choices" hook — no list visuals,
   structural only. Single-option case skips the list. */
.choice-list {
	display: grid;
	grid-template-columns: minmax(24ch, max-content);
	gap: 0.5rem;
	list-style: none;
	padding-left: 0;
	max-width: 40ch;
}

input-field.choice legend {
	font-family: var(--font-ui);
	font-size: 0.875rem;
	font-weight: 500;
	color: var(--ink-primary);
	margin-bottom: 0.25rem;
	padding: 0;
}

input-field.choice label.option {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	cursor: pointer;
	margin: 0;
	font-weight: normal;
}

/* Single-option case (no .choice-list wrapper) — apply the same
   width range the grid gives grouped items, so the focus ring and
   click target don't stretch to the full container. */
input-field.choice > label.option {
	width: max-content;
	min-width: 24ch;
	max-width: 40ch;
}

/* Whole label gets the ring when its input is focused — focus indicator
   matches the click target. Suppress the native input ring so the two
   rings don't double up. */
input-field.choice label.option:focus-within,
input-field.choice label.option[data-fakestate='focused'] {
	outline: var(--control-focus-ring);
	outline-offset: var(--control-focus-offset);
	border-radius: var(--control-radius);
}

input-field.choice label.option > input:focus-visible {
	outline: 0;
}

input-field.choice .label {
	font-family: var(--font-ui);
	font-size: 0.875rem;
	color: var(--ink-primary);
}


/* A stack of fields. Real markup pattern — used anywhere a vertical
   list of <input-field> items belongs (forms, specimen pages, etc.).
   The <ul>/<li> shape carries the list semantics; this gives the gap.
   list-style + padding zeroed so it stays clean even inside <text-content>
   or anywhere else that re-enables prose-list visuals. */
.field-list {
	display: flex;
	flex-direction: column;
	gap: var(--field-gap);
	list-style: none;
	padding-left: 0;
}


/* Per-field error messages. Sits inside <input-field> after the input,
   linked via aria-describedby. Just a bullet list in the theme error color. */
.error-list {
	list-style: disc;
	padding-left: 1.25em;
	color: var(--ink-error);
}


.form-notice {
	&.error {
		background-color: #ffb8b8;
		padding: rem;
		margin-bottom: 1em;
		box-shadow: 0 0 0 0.5em #ffb8b8;  /* $todo - these need some theme-level warning/error type color */
		p {
			color: black;
			opacity:  0.8;
		}
	}

	/*
		/dftw?action=enroll&p=self-driven-alpha-early&signup_error=email_exists
		/dftw?action=enroll&p=self-driven-alpha-early&signup_error=username_exists
	*/
}


.login-form {
	max-width: 50ch;
}


/* Padded variant — <input-field class='choice checkbox padded'> /
   <input-field class='choice radio padded'>. */
input-field.choice.padded label.option {
	display: flex;
	align-items: center;
	gap: 0.5em;
	padding: 0.5em 0.875em;
	border: 1px solid currentColor;
}

input-field.choice.padded label.option:has(input:disabled) {
	background: lightgray;
}

