/*
 * The file tree, structure only. Every colour, radius, shadow and font comes from a
 * custom property that the admin or the frontend skin sets on an element above.
 */

.mls3-tree {
	display: flex;
	flex-direction: column;
	min-height: 0;
	box-sizing: border-box;
	color: var(--mls3-fg);
	background: var(--mls3-bg);
	font-family: var(--mls3-font);
	font-size: var(--mls3-size);
	line-height: 1.5;
}

.mls3-tree *,
.mls3-tree *::before,
.mls3-tree *::after {
	box-sizing: inherit;
}

.mls3-tree button {
	font-family: inherit;
}

/* Summary */

.mls3-tree__summary {
	padding: var(--mls3-space-2) var(--mls3-space-4);
	color: var(--mls3-muted);
	font-size: var(--mls3-size-sm);
	text-align: start;
}

.mls3-tree__summary[hidden] {
	display: none;
}

.mls3-tree__summary-text {
	display: inline-block;
	font-variant-numeric: tabular-nums;
}

/* Toolbar */

.mls3-tree__bar {
	position: sticky;
	top: 0;
	z-index: 2;
	display: flex;
	flex-wrap: wrap;
	gap: var(--mls3-space-2);
	align-items: center;
	padding: var(--mls3-space-3) var(--mls3-space-4);
	background: var(--mls3-bg);
	border-block-end: 1px solid var(--mls3-border);
}

.mls3-tree__search {
	position: relative;
	display: flex;
	flex: 1 1 200px;
	min-width: 0;
	align-items: center;
}

.mls3-tree__search-icon {
	position: absolute;
	inset-inline-start: 10px;
	display: flex;
	color: var(--mls3-muted);
	pointer-events: none;
}

.mls3-tree__search-icon svg {
	width: 15px;
	height: 15px;
}

.mls3-tree__search-input {
	width: 100%;
	min-width: 0;
	padding: 7px var(--mls3-space-3);
	padding-inline-start: 32px;
	color: inherit;
	font: inherit;
	background: var(--mls3-bg);
	border: 1px solid var(--mls3-border);
	border-radius: var(--mls3-radius-sm);
	transition: border-color var(--mls3-dur) var(--mls3-ease), box-shadow var(--mls3-dur) var(--mls3-ease);
}

.mls3-tree__search-input::-webkit-search-cancel-button {
	display: none;
}

.mls3-tree__search-input:focus {
	outline: 0;
	border-color: var(--mls3-accent);
	box-shadow: 0 0 0 3px var(--mls3-accent-soft);
}

.mls3-tree__search-clear {
	position: absolute;
	inset-inline-end: 6px;
	inset-block-start: 50%;
	padding: 2px 6px;
	color: var(--mls3-muted);
	font: inherit;
	font-size: var(--mls3-size-sm);
	background: none;
	border: 0;
	border-radius: var(--mls3-radius-sm);
	transform: translateY(-50%);
	cursor: pointer;
}

.mls3-tree__search-clear[hidden] {
	display: none;
}

.mls3-tree__search-clear:hover {
	color: var(--mls3-fg);
	background: var(--mls3-row-hover);
}

.mls3-tree__sort {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
}

.mls3-tree__sort-select {
	max-width: 12rem;
	padding: 7px var(--mls3-space-2);
	color: inherit;
	font: inherit;
	font-size: var(--mls3-size-sm);
	background: var(--mls3-bg);
	border: 1px solid var(--mls3-border);
	border-radius: var(--mls3-radius-sm);
	cursor: pointer;
}

.mls3-tree__sort-select:focus-visible {
	outline: 2px solid var(--mls3-accent);
	outline-offset: 1px;
}

/* Status line */

.mls3-tree__status {
	padding: 0 var(--mls3-space-4);
	color: var(--mls3-muted);
	font-size: var(--mls3-size-sm);
	min-height: 0;
}

.mls3-tree__status:not(:empty) {
	padding-block: var(--mls3-space-2);
}

/* List */

/* The rows and the line that counts them, so a skin can frame the two as one card. */
.mls3-tree__body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	min-height: 0;
}

.mls3-tree__list {
	flex: 1 1 auto;
	min-height: 0;
	margin: 0;
	padding: var(--mls3-space-2) 0;
	overflow-x: hidden;
	overflow-y: auto;
	list-style: none;
}

/*
 * Opening and closing a folder slides its rows. The script sets the height and clears it
 * again when the slide is over, so a long list is never stuck at a fixed height. The time
 * below and the one in tree.js belong together.
 */
.mls3-tree__children {
	margin: 0;
	margin-inline-start: 18px;
	padding-inline-start: 20px;
	border-inline-start: 1px solid var(--mls3-border);
	list-style: none;
	transition: height 180ms var(--mls3-ease);
}

.mls3-tree__item {
	margin: 0 !important;
}

.mls3-tree__row {
	display: grid;
	grid-template-columns: 20px 22px minmax(0, 1fr) auto auto;
	gap: var(--mls3-space-2);
	align-items: center;
	min-height: var(--mls3-row-h);
	margin-inline: var(--mls3-space-2);
	padding: 0 var(--mls3-space-3);
	border-inline-start: 2px solid transparent;
	border-radius: var(--mls3-radius-sm);
	cursor: pointer;
	transition: background var(--mls3-dur) var(--mls3-ease);
}

.mls3-tree__row:hover {
	background: var(--mls3-row-hover);
}

.mls3-tree__item.is-selected > .mls3-tree__row {
	background: var(--mls3-selected);
	border-inline-start-color: var(--mls3-accent);
}

.mls3-tree__item.is-selected > .mls3-tree__row .mls3-tree__name {
	font-weight: 600;
}

.mls3-tree__row:focus-visible {
	outline: 2px solid var(--mls3-accent);
	outline-offset: -1px;
}

.mls3-tree__twisty {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
}

/*
 * The chevron is a rotated corner, so logical borders would rebuild the shape itself in
 * right to left. The borders stay physical and only the angle changes.
 */
.mls3-tree__twisty::before {
	content: "";
	display: block;
	width: 6px;
	height: 6px;
	border-right: 1.5px solid var(--mls3-muted);
	border-bottom: 1.5px solid var(--mls3-muted);
	transform: rotate(-45deg);
	transition: transform var(--mls3-dur) var(--mls3-ease);
}

[dir="rtl"] .mls3-tree__twisty::before {
	transform: rotate(135deg);
}

.mls3-tree__item.is-folder[aria-expanded="true"] > .mls3-tree__row > .mls3-tree__twisty::before,
[dir="rtl"] .mls3-tree__item.is-folder[aria-expanded="true"] > .mls3-tree__row > .mls3-tree__twisty::before {
	transform: rotate(45deg);
}

.mls3-tree__twisty:disabled::before {
	content: none;
}

/*
 * File type hues. They say what kind of file a row holds, so they are the same in both
 * skins. Each skin only picks the saturation and the lightness that suit its background.
 */
.mls3-tree__icon {
	--mls3-ft-h: 220;

	display: flex;
	align-items: center;
	justify-content: center;
	color: hsl(var(--mls3-ft-h) var(--mls3-ft-s) var(--mls3-ft-l));
}

.mls3-tree__icon.is-archive {
	--mls3-ft-h: 38;
}

.mls3-tree__icon.is-pdf {
	--mls3-ft-h: 4;
}

.mls3-tree__icon.is-image {
	--mls3-ft-h: 145;
}

.mls3-tree__icon.is-audio {
	--mls3-ft-h: 270;
}

.mls3-tree__icon.is-video {
	--mls3-ft-h: 340;
}

.mls3-tree__icon.is-code {
	--mls3-ft-h: 215;
}

.mls3-tree__icon.is-sheet {
	--mls3-ft-h: 168;
}

.mls3-tree__icon.is-font {
	--mls3-ft-h: 250;
}

.mls3-tree__icon.is-generic {
	color: var(--mls3-muted);
}

.mls3-tree__item.is-folder > .mls3-tree__row > .mls3-tree__icon {
	color: var(--mls3-accent);
}

.mls3-tree__icon svg {
	width: 17px;
	height: 17px;
	fill: currentColor;
}

/*
 * isolate, not plaintext: a Persian file name reads correctly inside a left to right list,
 * but it does not jump to the other edge and break the column.
 */
.mls3-tree__name {
	overflow: hidden;
	white-space: nowrap;
	text-align: start;
	text-overflow: ellipsis;
	unicode-bidi: isolate;
}

.mls3-tree__name mark {
	color: var(--mls3-accent);
	font-weight: 600;
	background: none;
}

/* The mark the newest file wears. */
.mls3-tree__badge {
	display: inline-flex;
	align-items: center;
	padding: 2px var(--mls3-space-2);
	color: var(--mls3-accent);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: .03em;
	text-transform: uppercase;
	white-space: nowrap;
	background: var(--mls3-selected);
	border-radius: 999px;
}

/* Each value inside is wrapped in a bdi element, so nothing reorders in a mirrored panel. */
.mls3-tree__meta {
	color: var(--mls3-muted);
	font-size: var(--mls3-size-sm);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.mls3-tree__actions {
	display: flex;
	gap: var(--mls3-space-1);
	align-items: center;
	min-height: 20px;
}

.mls3-tree__action {
	display: flex;
	gap: 6px;
	align-items: center;
	padding: 3px var(--mls3-space-2);
	color: var(--mls3-accent);
	font: inherit;
	font-size: var(--mls3-size-sm);
	white-space: nowrap;
	background: none;
	border: 1px solid transparent;
	border-radius: var(--mls3-radius-sm);
	opacity: 0;
	cursor: pointer;
	transition: opacity var(--mls3-dur) var(--mls3-ease), background var(--mls3-dur) var(--mls3-ease);
}

.mls3-tree__row:hover .mls3-tree__action,
.mls3-tree__row:focus-visible .mls3-tree__action,
.mls3-tree__action:focus-visible {
	border-color: var(--mls3-border);
	opacity: 1;
}

/* A selected folder keeps its button visible, so the state is readable without hovering. */
.mls3-tree__action.is-on {
	color: var(--mls3-accent-fg);
	background: var(--mls3-accent);
	border-color: var(--mls3-accent);
	opacity: 1;
}

.mls3-tree__action svg {
	width: 14px;
	height: 14px;
}

.mls3-tree__spin {
	animation: mls3-spin 800ms linear infinite;
}

/* Empty, error and load more */

.mls3-tree__state {
	display: flex;
	flex-direction: column;
	gap: var(--mls3-space-2);
	align-items: center;
	padding: var(--mls3-space-4) var(--mls3-space-4) calc(var(--mls3-space-4) * 1.5);
	text-align: center;
}

.mls3-tree__state-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	color: var(--mls3-muted);
	background: var(--mls3-surface);
	border-radius: 50%;
}

.mls3-tree__state-icon svg {
	width: 20px;
	height: 20px;
}

.mls3-tree__state.is-error .mls3-tree__state-icon {
	color: var(--mls3-danger);
}

.mls3-tree__state-title {
	color: var(--mls3-fg);
	font-weight: 600;
}

.mls3-tree__state-text {
	max-width: 42ch;
	color: var(--mls3-muted);
	font-size: var(--mls3-size-sm);
}

/* Inside an open folder the same card shrinks to one quiet line. */
.mls3-tree__state.is-inline {
	flex-direction: row;
	gap: var(--mls3-space-2);
	justify-content: flex-start;
	padding: var(--mls3-space-2) var(--mls3-space-3);
	margin-inline-start: var(--mls3-space-2);
	text-align: start;
}

.mls3-tree__state.is-inline .mls3-tree__state-icon {
	width: 18px;
	height: 18px;
	background: none;
}

.mls3-tree__state.is-inline .mls3-tree__state-icon svg {
	width: 15px;
	height: 15px;
}

.mls3-tree__state.is-inline .mls3-tree__state-title {
	color: var(--mls3-muted);
	font-size: var(--mls3-size-sm);
	font-weight: 400;
}

.mls3-tree__state.is-inline .mls3-tree__state-text {
	display: none;
}

.mls3-tree__more-row {
	display: flex;
	justify-content: center;
	padding: var(--mls3-space-2);
}

.mls3-tree__retry,
.mls3-tree__more {
	padding: 5px var(--mls3-space-3);
	color: var(--mls3-fg);
	font: inherit;
	font-size: var(--mls3-size-sm);
	background: var(--mls3-bg);
	border: 1px solid var(--mls3-border);
	border-radius: var(--mls3-radius-sm);
	cursor: pointer;
	transition: background var(--mls3-dur) var(--mls3-ease);
}

.mls3-tree__retry:hover,
.mls3-tree__more:hover {
	background: var(--mls3-row-hover);
}

.mls3-tree__skeleton {
	height: var(--mls3-row-h);
	margin: 2px var(--mls3-space-2);
	background: linear-gradient(90deg, var(--mls3-skeleton) 25%, var(--mls3-row-hover) 50%, var(--mls3-skeleton) 75%);
	background-size: 200% 100%;
	border-radius: var(--mls3-radius-sm);
	animation: mls3-shimmer 1200ms linear infinite;
}

.mls3-tree__sink {
	display: none;
}

.mls3-tree__hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	white-space: nowrap;
	border: 0;
	clip-path: inset(50%);
}

@keyframes mls3-shimmer {
	from {
		background-position: 200% 0;
	}

	to {
		background-position: -200% 0;
	}
}

@keyframes mls3-spin {
	to {
		transform: rotate(360deg);
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.mls3-tree *,
	.mls3-tree *::before {
		transition: none !important;
		animation: none !important;
	}
}

@media ( max-width: 600px ) {
	.mls3-tree__meta {
		display: none;
	}

	.mls3-tree__row {
		grid-template-columns: 24px 22px minmax(0, 1fr) auto;
	}

	.mls3-tree__action {
		opacity: 1;
	}

	.mls3-tree__children {
		margin-inline-start: 14px;
		padding-inline-start: 12px;
	}
}

/* The strip above the search bar, and the bucket it says the tree is showing */

.mls3-tree__tools {
	flex: 0 0 auto;
}

.mls3-tree__tools[hidden] {
	display: none;
}

.mls3-bucket-bar {
	display: flex;
	gap: 8px;
	align-items: center;
	padding: var(--mls3-space-3) 20px;
	font-size: var(--mls3-size-sm);
}

.mls3-bucket-bar__icon {
	display: inline-flex;
	width: 16px;
	height: 16px;
	color: var(--mls3-muted);
}

.mls3-bucket-bar__icon svg {
	width: 100%;
	height: 100%;
}

.mls3-bucket-bar__name {
	font-weight: 600;
}

.mls3-bucket-bar__label {
	color: var(--mls3-muted);
}

.mls3-bucket-bar__select {
	min-height: 34px;
	margin: 0;
	padding-block: 0;
	padding-inline: 12px 28px;
	color: var(--mls3-fg);
	font: inherit;
	font-size: var(--mls3-size);
	font-weight: 600;
	line-height: 1;
	background-color: var(--mls3-bg);
	border: 1px solid var(--mls3-border-strong);
	border-radius: 999px;
	box-shadow: none;
}

.mls3-bucket-bar__select:hover {
	border-color: var(--mls3-muted);
}

.mls3-bucket-bar__select:focus {
	outline: 0;
	border-color: var(--mls3-accent);
	box-shadow: 0 0 0 3px var(--mls3-accent-soft);
}
