/*
 * Colours use the contextual `--ds-color-*` aliases so the builder follows the
 * active colour scheme. Never add hex fallbacks.
 */

.ObFilterBuilder-root {
	display: grid;
	gap: var(--ds-size-4);
	/*
	 * The saved-filter list sits beside the editor. The buttons acting on the
	 * selected filter share the bottom row with OK/Cancel rather than being
	 * confined to the list's column, so they have room to stay on one line.
	 * On narrow viewports everything stacks.
	 */
	grid-template:
		"sidebar main" 1fr
		"error error" auto
		"footer footer" auto
		/ minmax(14rem, 22rem) minmax(0, 1fr);
	block-size: 100%;
	min-block-size: 0;
}

.ObFilterBuilder-sidebar {
	grid-area: sidebar;
	overflow: auto;
	padding: var(--ds-size-2);
	border: var(--ds-border-width-default) solid var(--ds-color-border-subtle);
	border-radius: var(--ds-border-radius-md);
}

/*
 * The editor manages its own scrolling — the conditions scroll, the filter
 * string stays put — so this only has to hand it the available height. A caller
 * that replaces the editor through `renderMain` gets the same treatment.
 */
.ObFilterBuilder-main {
	grid-area: main;
	display: flex;
	flex-direction: column;
	gap: var(--ds-size-3);
	min-inline-size: 0;
	min-block-size: 0;
}

.ObFilterBuilder-main > * {
	flex: 1 1 auto;
	min-inline-size: 0;
	min-block-size: 0;
}

.ObFilterBuilder-error {
	grid-area: error;
	margin: 0;
	color: var(--ds-color-danger-text-default);
}

.ObFilterBuilder-footer {
	grid-area: footer;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--ds-size-4);
}

.ObFilterBuilder-toolbar,
.ObFilterBuilder-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ds-size-2);
}

.ObFilterBuilder-actions {
	margin-inline-start: auto;
}

/*
 * Without the saved-filter list there are no buttons acting on one either, so
 * the editor takes the full width.
 */
.ObFilterBuilder-root--noSavedFilters {
	grid-template:
		"main" 1fr
		"error" auto
		"footer" auto
		/ minmax(0, 1fr);
}

/*
 * `Dialog` caps itself at `--dsc-dialog-max-width` (40rem), so setting a width
 * here would have no effect — the variable has to be raised instead. It needs
 * to be wide enough that a condition — field, operator, value and the group
 * buttons — fits on one line next to the saved-filter column.
 */
.ObFilterBuilder-dialog {
	--dsc-dialog-max-width: 84rem;
	--dsc-dialog-max-height: 90dvh;
}

/*
 * A fixed height keeps the dialog from resizing as conditions are added and
 * removed, and gives the saved-filter column and the editor a height to fill.
 * The dialog itself must not scroll — the body does — or the heading would
 * scroll away and the OK/Cancel row would not stay at the bottom.
 */
.ObFilterBuilder-dialog[open] {
	display: flex;
	flex-direction: column;
	block-size: 48rem;
	overflow: hidden;
}

/*
 * The heading and the close button share the header row.
 */
.ObFilterBuilder-dialogHeader {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ds-size-2);
}

.ObFilterBuilder-dialogBody {
	flex: 1 1 auto;
	min-block-size: 0;
	overflow: hidden;
}

@media (width < 48rem) {
	.ObFilterBuilder-root:not(.ObFilterBuilder-root--noSavedFilters) {
		grid-template:
			"sidebar" auto
			"main" 1fr
			"error" auto
			"footer" auto
			/ minmax(0, 1fr);
	}

	/*
	 * Stacked, the dialog body is the scroll container: the editor cannot give
	 * both the list and the conditions a useful height in the space left over.
	 */
	.ObFilterBuilder-dialogBody {
		overflow: auto;
	}

	.ObFilterBuilder-sidebar {
		max-block-size: 12rem;
	}
}
