@charset "utf-8";

/* =============================================================================
* Zero specificity. Global fixes.
* =========================================================================== */
@layer reset {
*,
*::after,
*::before {
	box-sizing: border-box;
}

* {
	margin: 0;
	padding: 0;
}

:where(
	img,
	picture,
	svg,
	video,
) {
	block-size: auto; /* Maintains aspect ratio relative to writing mode. */
	display: block;
	max-inline-size: 100%; /* Can scale downward without exceeding intrinsic width */
}
}

/* =============================================================================
* Typography, colors, spacing, element defaults. Use :where() for element
* selectors.
* =========================================================================== */
@layer base {
:where(html) {
	color: var(--color-text);
	font-family: var(--font-body);
}

:where(body) {
	block-size: 100%;	/* Fills full vertical space */
}

/* Elements that should have no margin and no padding. */
:where(
	body,
) {
	margin: 0;
	padding: 0;
}

/* Elements that should have margin (block spacing only) but no padding. */
:where(
	article,
	figure,
	nav,
	section,
) {
	margin-block: var(--size-md);
	margin-inline: 0;
	padding: 0;
}

/* Elements that should have padding but no margin. */
:where(
	footer,
	header,
	main,
) {
	margin: 0;
	padding: var(--size-md);
}

:where(main) {
	flex-grow: 1;
}

/**
* Fix for containers with non-collapsing margins.
* Note that a fieldset + legend is an edge case where an anonymous container is
* added by the browser, but it cannot be selected using CSS.
* fieldset
* ├ legend
* └ anonymous box
*   ├ .form-row
*   └ .button-row                      ← Last child inside anonymous box
*/
:where(
	article,
	form,
	main,
	.surface,
	.table,
	.table-wrapper,
) {
	& > :first-child:is(*) {
		margin-block-start: 0;
	}
	& > :last-child:is(*) {
		margin-block-end: 0;
	}
}

/* Headings */
:where(
	h1, h2, h3, h4, h5, h6,
	.h1, .h2, .h3, .h4, .h5, .h6,
) {
	color: var(--color-text);
	font-family: var(--font-heading);
	font-style: normal;
	font-weight: var(--font-weight-bold);
	text-wrap: balance;
}
:where(
	h1, h2, h3,
	.h1, .h2, .h3,
) {
	font-optical-sizing: auto;
	font-variation-settings: "grad" 0, "wdth" 150;
	line-height: var(--line-height-0);
	margin-block: var(--size-md);
}
:where(
	h4, h5, h6,
	.h4, .h5, .h6,
) {
	line-height: var(--line-height-1);
	margin-block: var(--size-sm);
}
/* :where(h4, h5) {
	font-weight: var(--font-weight-regular);
} */
:where(h1, .h1) {
	font-size: var(--font-2xl);
}
:where(h2, .h2) {
	font-size: var(--font-xl);
}
:where(h3, .h3) {
	font-size: var(--font-lg);
}
:where(h4, .h4) {
	font-size: var(--font-md);
}
:where(h5, .h5) {
	font-size: var(--font-sm);
}
:where(h6, .h6) {
	font-size: var(--font-xs);
}
/* :where(h6) {
	font-weight: var(--font-weight-light);
} */

:where(p) {
	margin-block: var(--size-sm);
	overflow-wrap: anywhere;
	text-wrap: pretty;
}

/* ===========================================================================
* Links. Order of selectors is important -- canonical order (LVFHA).
* ========================================================================= */
:where(a) {
	&:link {
		color: var(--color-link);
	}
	&:visited {
		/* Use fallback color only if both variable do not exist. */
		color: var(--color-link-visited, var(--color-link, #5a3e85));
	}
	&:focus {
		outline: 2px solid var(--color-link-focus-outline);
	}
	&:hover {
		color: var(--color-link-hover);
	}
	&:active {
		color: var(--color-link-active);
	}
}

/**
* <code> is for inline filenames or other computer text.
* <kbd> is for keyboard input.
* <pre> is for blocks of text, including lists of filenames.
* <samp> is for program output (i.e. sample output).
*/
:where(code) {
	font-weight: 600;
}
:where(
	code,
	kbd,
	pre,
	samp,
) {
	font-family: var(--font-code);
}
:where(pre) {
	background-color: var(--color-surface-1);
}

:where(dialog) {
	background-color: var(--color-surface-1);
	padding: var(--size-md);
}

/* =============================================================================
* Form layout
* =========================================================================== */
:where(
	form,
	fieldset,
) {
	--form-color-surface: var(--color-surface-1);

	padding: var(--size-md);

	&.borderless {
		background: transparent;
		border: none;
		padding-block-end: 0;
		padding-inline: 0;
	}
}

:where(.form) {
	inline-size: fit-content;
	margin-block: var(--size-md);
	max-inline-size: var(--width-content-max);
}

/**
* Two ways to nest elements, where label + control width determines container
* query breakpoint.
*
* .form
* └ .fieldset [optional]               ← Visual grouping of multiple fields
*   └ .field-body-grid [mandatory]     ← Internal layout for label + control
*     ├ .control-label
*     ├ .control-wrapper [optional]    ← Horizontal inline elements
*     │ └ [control]                    ← e.g. checkbox, input, select, etc.
*     ├ .control-label
*     └ .control-wrapper [optional]    ← Horizontal inline elements
*       └ [control]                    ← e.g. checkbox, input, select, etc.
*
* .form
* └ .fieldset [optional]               ← Visual grouping of multiple fields
*   └ .form-row [optional]             ← Horizontal layout of multiple fields
*     └ .form-field [semi-optional]    ← Defines one complete field
*       ├ .field-body [mandatory]      ← Internal layout for label + control
*       │ ├ .control-label
*       │ └ .control-wrapper [optional]    ← Horizontal inline elements
*       │   ├ [control]                ← e.g. checkbox, input, select, etc.
*       │   ├ .control-icon
*       │   ├ .control-hint
*       │   ├ .control-prefix
*       │   ├ .control-suffix
*       │   └ .control-clear-button
*       ├ .control-error
*       └ .control-description
*/

:where(
	.form-row,
	.form-field,
	.field-body,
) {
	max-inline-size: 100%;               /* Clamp to parent */
	min-inline-size: 0;                  /* Allow good shrinking */
}

:where(
	.field-body-grid,
	.field-row,
) {
	margin-block: var(--size-sm);
}

/**
* Simplified field layout using 2-column grid where labels are in column 1 and
* controls are in column 2. Each column shrinks and expands to fit the largest
* element within its column.
*/
:where(.field-body-grid) {
	align-items: baseline;
	display: grid;
	/* flex-shrink: 1; */
	gap: var(--size-sm);
	grid-template-columns: auto 1fr;
	justify-items: start;
	/* max-inline-size: 100%; */
	/* min-inline-size: 8rem; */

	& > .control-label {
		/* inline-size: max-content; */
		/* max-inline-size: 50cqw; */
		/* min-inline-size: 0; */
		/* flex: 0 0 auto; */
		/* min-inline-size: 0; */
		white-space: normal;
		overflow-wrap: break-word;
	}
}

/**
* Container for laying out multiple fields horizontally. Not needed if only one
* field exists. Example of multiple fields is first and last name together, or
* salutation + first, middle, and last name.
* Caveat: Do not use if child element needs to be full width of parent.
*/
.form-row {
	align-items: start;
	display: flex;
	flex-wrap: wrap;
	gap: var(--size-md);
	margin-block: var(--size-sm);

	& > * {
		margin-block: 0;
	}
}

/**
* Container for a single field with stacking. Optional, but recommended for a
* predictable field block. Future proof if additional blocks are added later
* (e.g. hint, error, or description).
* Semantic: This is a field.
* Container = semantic grouping of related elements into a meaningful unit.
* Answers the question "Which elements belong together?"
*/
:where(.form-field) {
	display: flex;
	flex-direction: column;
	gap: var(--size-sm);
	margin-block: var(--size-sm);
	min-inline-size: var(--switcher-xs);
}

/**
* Container for arranging the label + control only. Stacks on narrow screens.
* Mechanical: This is how the label and input are arranged.
*/
:where(.field-body) {
	align-items: baseline;
	display: flex;
	gap: var(--size-sm);

	/* Prevents label from hogging space. */
	& > .control-label {
		inline-size: fit-content;
	}
	& > .select {
		min-inline-size: 12ch;
	}
}

:where(.button-row) {
	display: flex;
	flex-wrap: wrap;
	gap: var(--size-sm);
	margin-block: var(--size-md);
}

:where(.control-label) {
	&.required::after {
		color: #c62828;
		content: " *";
		opacity: 0.8;
	}
}

:where(.control-description) {
	font-size: var(--font-sm);
	opacity: 0.8;
}

:where(.control-error) {
	font-size: var(--font-sm);
	font-weight: 500;
	opacity: 1;
}

/**
* Wrapper for managing icons, hints, padding, and absolute positioning. Answers
* the question "What layout mechanics does this element need?"
* Wrapper = mechanical layout to solve a specific layout problem.
*/
:where(.control-wrapper) {
	align-items: center;                 /* Vertically center input + icons */
	display: flex;                       /* Inline elements align cleanly */
	flex-wrap: nowrap;
	gap: var(--size-sm, 0.5rem);         /* Space between input and hints */
	position: relative;                  /* Anchor for icons/hints */
	inline-size: 100%;                   /* Input fills available space */
}

:where(.control-icon) {
	align-items: center;
	display: flex;
	font-size: var(--font-md);
	justify-content: center;
	opacity: 0.8;
	padding: 0 var(--size-sm);
	pointer-events: none;                /* Icon does not block input */
}

:where(.control-hint) {
	align-items: center;
	display: flex;
	font-size: var(--font-sm);
	margin-inline-start: auto;           /* Pushes hint to the right */
	opacity: 0.7;
}

/* =============================================================================
* Form controls
* =========================================================================== */

/* Interactive and non-interactive components. */
:where(
	fieldset,
	form,
	.button,
	.checkbox,
	.input,
	.radio,
	.select,
	.textarea,
) {
	background-color: var(--form-color-surface);
	border-color: var(--form-color-border);
	border-style: solid;
	border-width: var(--width-border);
	border-radius: var(--radius-border);
	color: var(--form-color-text);
	font-family: inherit;
	font-size: inherit;
	line-height: 1.2;
}

/* Interactive components. */
:where(
	.button,
	.checkbox,
	.input,
	.radio,
	.select,
	.textarea,
) {
	--form-color-surface: var(--color-surface-0);

	transition:
		background-color 0.15s ease,
		border-color 0.15s ease,
		color 0.15s ease;
	vertical-align: baseline;

	&::placeholder {
		--form-color-text: var(--form-color-placeholder);
	}

	&:active {
		background-color: color-mix(
			in srgb,
			var(--form-color-surface),
			black var(--color-mix-amount)
		);
		border-color: color-mix(
			in srgb,
			var(--form-color-border),
			black var(--color-mix-amount)
		);
	}

	&:focus-visible {
		outline: 2px solid var(--color-outline);
		outline-offset: 2px;
	}

	&:hover {
		background-color: color-mix(
			in srgb,
			var(--form-color-surface),
			white var(--color-mix-amount)
		);
		border-color: color-mix(
			in srgb,
			var(--form-color-border),
			white var(--color-mix-amount)
		);
	}

	&:is(                                /* Higher specificity than :where() */
		:disabled,
		[disabled],
	) {
		background-color: color-mix(
			in srgb,
			var(--form-color-surface),
			white var(--color-mix-amount)
		);
		border-color: color-mix(
			in srgb,
			var(--form-color-border),
			white var(--color-mix-amount)
		);
		color: color-mix(
			in srgb,
			var(--form-color-text),
			gray 50%
		);
		cursor: not-allowed;
		opacity: 0.6;
	}
}

/**
* Components whose primary action is "click to do something", not "click to
* edit".
*/
:where(
	.button,
	.checkbox,
	.radio,
) {
	cursor: pointer;
}

/* Choice components only. */
:where(
	.checkbox,
	.radio,
) {
	margin-block: calc(var(--size-xs) + var(--size-3xs)); /* Not quite exact... */
	padding: 0;
	vertical-align: baseline;
}

	/* Components with borders only. */
:where(
	.input,
	.select,
	.textarea,
) {
	display: inline-flex;
	padding: var(--size-xs) var(--size-sm);
}

:where(.button) {
	align-items: center;
	display: inline-flex;
	font-weight: 500;
	gap: var(--size-sm);
	inline-size: var(--width-button);
	justify-content: center;
	padding: var(--size-sm) var(--size-md);
	user-select: none;

	&.ghost {
		--form-color-surface: inherit;
	}
}

:where(.checkbox) {
	&:checked {
		background-color: var(--form-color-border);
		background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12'><path d='M2 6l2 2 6-6' stroke='%23fff' stroke-width='2' fill='none' stroke-linecap='round'/></svg>");
		background-position: center;
		background-repeat: no-repeat;
	}
}

:where(
	.checkbox,
	.radio,
	.switch,
	.toggle,
) {
	appearance: none;
	display: inline-block;
	height: var(--size-md);
	padding: 0;
	inline-size: var(--size-md);
}

:where(.input) {
	align-items: center;
	justify-self: start;
}

:where(.radio) {
	border-radius: 50%;

	&:checked {
		border-color: var(--form-color-border);
		box-shadow: 0 0 0 4px var(--form-color-border) inset;
	}
}

:where(.select) {
	/* Custom dropdown arrow. */
	appearance: none;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12'><path d='M2 4l4 4 4-4' stroke='%23aaa' stroke-width='2' fill='none' stroke-linecap='round'/></svg>");
	background-position: right var(--size-sm) center;
	background-repeat: no-repeat;
	inline-size: 100%;
	min-inline-size: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;               /* Firefox only */
}

:where(.textarea) {
	box-sizing: content-box;
	inline-size: 100%;
	max-block-size: 20lh;
	max-inline-size: 40ch;
	min-block-size: 10lh;
	overflow-wrap: break-word;
	resize: both;
	word-break: break-word;
}

/* =============================================================================
* Layout containers
* =========================================================================== */

:where(
	.cluster,
	.flex,
	.stack,
	.switcher,
) {
	align-items: flex-start;
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
}

/* Specialized flex containers to define layout patterns. */
:where(
	.cluster,
	.stack,
	.switcher,
	) {
	gap: var(--size-md);
	margin-block: var(--size-md);
	padding: 0;
}
:where(.stack) {
	flex-direction: column;
}
@media (max-width: var(--switcher-breakpoint)) {
	.switcher {
		flex-direction: column;
	}
}

/**
* Base primitive for defining flow, wrapping, alignment, and spacing between
* items.
*/
:where(.flex) {
	align-items: flex-start;
	display: flex;
	flex-wrap: wrap;
	margin: 0;
	padding: 0;
}
}

/* =============================================================================
* Semantic components. Normal selectors do not need :where().
* Always use <element>.<class> to avoid theme files from accidentally overriding
* identical class names within this file.
* =========================================================================== */
@layer components {
aside {
	--color-background: transparent;
	--color-border: var(--color-surface-3);

	background-color: var(--color-background);
	border: var(--size-3xs) solid var(--color-border);
	border-radius: var(--radius-border);
	margin-block: var(--size-sm);
	margin-inline: 0;
	overflow-wrap: anywhere;
	padding-block: var(--size-xs);
	padding-inline: var(--size-sm);
}

fieldset {
	margin-block: var(--size-md);

	&:first-child {
		margin-block-start: 0;
	}
	&:last-child {
		margin-block-end: 0;
	}

	& > legend {
		font-family: var(--font-heading);
		font-weight: var(--font-weight-bold);
		padding-inline: var(--size-sm);
	}
	
	&.borderless {
		& > legend {
			padding-inline: 0;
		}
	}
}

/* Interactive and non-interactive components. */
:where(
	details.details,
	table.table,
	.switch,
	.tab,
	.toggle,
) {
	background-color: var(--form-color-surface);
	border-color: var(--form-color-border);
	border-style: solid;
	border-width: var(--width-border);
	border-radius: var(--radius-border);
	color: var(--form-color-text);
	font-family: inherit;
	font-size: inherit;
	line-height: 1.2;
}

/* Interactive components. */
:where(
	details.details > summary,
	.switch,
	.tab,
	.toggle,
) {
	--form-color-surface: var(--color-surface-0);

	cursor: pointer;
	padding-block: 0;
	padding-inline: 0;
	transition:
		background-color 0.15s ease,
		border-color 0.15s ease,
		color 0.15s ease;
	vertical-align: baseline;

	&::placeholder {
		--form-color-text: var(--form-color-placeholder);
	}

	&:active {
		background-color: color-mix(
			in srgb,
			var(--form-color-surface),
			black var(--color-mix-amount)
		);
		border-color: color-mix(
			in srgb,
			var(--form-color-border),
			black var(--color-mix-amount)
		);
	}

	&:focus-visible {
		outline: 2px solid var(--color-outline);
		outline-offset: 2px;
	}

	&:hover {
		background-color: color-mix(
			in srgb,
			var(--form-color-surface),
			white var(--color-mix-amount)
		);
		border-color: color-mix(
			in srgb,
			var(--form-color-border),
			white var(--color-mix-amount)
		);
	}

	&:is(                                /* Higher specificity than :where() */
		:disabled,
		[disabled],
	) {
		background-color: color-mix(
			in srgb,
			var(--form-color-surface),
			white var(--color-mix-amount)
		);
		border-color: color-mix(
			in srgb,
			var(--form-color-border),
			white var(--color-mix-amount)
		);
		color: color-mix(
			in srgb,
			var(--form-color-text),
			gray 50%
		);
		cursor: not-allowed;
		opacity: 0.6;
	}
}

details.details {
	inline-size: fit-content;
	margin-block: var(--size-md);

	& > summary {
		align-items: center;
		display: list-item;
		justify-content: space-between;
		list-style: disclosure-closed;
		list-style-position: inside;
		padding-block: var(--size-xs);
		padding-inline: var(--size-sm);
		user-select: none;

		/* Remove default marker. */
/* 			display: block;
		list-style: none;
		&::-webkit-details-marker {
			display: none;
		} */
	}

	&[open] {
		& > summary {
			background-color: color-mix(
				in srgb,
				var(--form-color-surface),
				white var(--color-mix-amount)
			);
			border-block-end: var(--width-border) solid var(--color-border);
			list-style: disclosure-open;
			list-style-position: inside;
		}
	}

	& > .content {
		background-color: var(--color-surface-1);
		padding: var(--size-sm);

		& > :first-child {
			margin-block-start: 0;
		}
		& > :last-child {
			margin-block-end: 0;
		}
	}
}

/* Non-interactive components. */
table.table {
	border-collapse: collapse;
	max-inline-size: 100%;
	min-inline-size: 40rem;
	overflow: hidden;

	thead {
		--form-color-surface: var(--color-surface-1);

		position: sticky;
		top: 0;
		z-index: 2;

		th {
			font-weight: 600;
			vertical-align: bottom;
		}
	}

	tfoot {
		td {
			font-weight: 500;
		}
	}

	th,
	td {
		background-color: var(--form-color-surface);
		border: 1px solid var(--form-color-border);
		padding-block: 0.75rem;
		padding-inline: var(--size-md);
		text-align: start;

		&.empty {
			background-color: transparent;
			text-align: center;

			&::after {
				content: "–";
				opacity: 0.7;
			}
		}
	}

	td {
		vertical-align: top;
	}

	/* &.hover {
		tbody tr:hover td {
			background-color: color-mix(in srgb, var(--form-color-surface), white 8%);
		}
	} */

	&.borderless {
		th,
		td {
			border: none;
		}
	}

	&.compact {
		th,
		td {
			font-size: var(--font-sm);
			padding-block: var(--size-xs);
			padding-inline: var(--size-sm);
		}
	}

	&.zebra {
		tbody tr:nth-child(even) td {
			background-color: color-mix(in srgb, var(--form-color-surface), white 3%);
		}
	}
}

.table-wrapper {
	overflow-x: auto;
	overflow-y: hidden;
	padding-block-end: var(--size-xs); /* keeps scrollbar off the border */
	scroll-behavior: smooth;
}
}
