/* components/tree: rows in levels with a chevron column, thin guide lines per level, a tinted selected
   row with a bar at its start, the focus tokens on the focused row. The same rules style the no-script
   markup (<details><summary> as the row) and the scripted one (<li aria-expanded> with a row div); the
   state is the attribute (open, aria-expanded, aria-selected, aria-current), never a class. Geometry
   comes from the tree tokens (row height, indent, gap, each with a compact value), colours from the
   page's colour tokens, so a site colours the tree through its tokens and a dark site gets a dark tree.
   Logical properties throughout, so dir="rtl" mirrors the tree. */
@layer components {
	.dv-tree {
		font-size: var(--font-size-body);
		line-height: var(--font-line-height);
		color: var(--color-text);
	}

	.dv-tree .dv-tree-group {
		margin: 0;
		padding: 0;
		list-style: none;
	}

	/* A nested group: one indent deeper, with a guide line under the parent's chevron. */
	.dv-tree .dv-tree-group .dv-tree-group {
		margin-inline-start: calc(0.25em + var(--tree-indent) / 2);
		padding-inline-start: calc(var(--tree-indent) / 2 - 0.25em);
		border-inline-start: 1px solid var(--tree-guide);
	}

	.dv-tree .dv-tree-item {
		margin: 0;
		padding: 0;
	}

	/* The scripted tree hides a collapsed branch's group; the <details> does it without the script. */
	.dv-tree .dv-tree-item[aria-expanded="false"] > .dv-tree-group {
		display: none;
	}

	/* The row: the chevron's column, the text, the bar at the start that marks the selected row. */
	.dv-tree .dv-tree-row {
		display: flex;
		align-items: center;
		gap: var(--tree-gap);
		min-block-size: var(--tree-row-height);
		padding-inline-end: var(--space-2);
		border-inline-start: 0.25em solid transparent;
		border-radius: var(--radius-panel);
		list-style: none;
		cursor: default;
	}

	.dv-tree .dv-tree-row::-webkit-details-marker {
		display: none;
	}

	.dv-tree .dv-tree-row:hover {
		background: var(--tree-hover-background);
	}

	.dv-tree .dv-tree-label {
		flex: 1 1 auto;
		min-inline-size: 0;
		overflow-wrap: anywhere;
		text-decoration: none;
	}

	.dv-tree .dv-tree-label[href]:hover {
		text-decoration: underline;
	}

	/* The chevron's column: an empty span on a leaf, a button on a branch (the script), the summary's
	   marker without the script. The column is as wide as one indent, so a child's row starts under its
	   parent's text, and as tall as the row: a target of at least 24 by 24 CSS pixels. */
	.dv-tree .dv-tree-toggle {
		display: flex;
		flex: none;
		align-items: center;
		justify-content: center;
		align-self: stretch;
		inline-size: var(--tree-indent);
		margin: 0;
		padding: 0;
		font: inherit;
		color: inherit;
		background: none;
		border: 0;
		cursor: pointer;
	}

	/* The chevron, drawn only on a branch: points to the inline end when collapsed, down when expanded. */
	.dv-tree .dv-tree-branch > .dv-tree-row > .dv-tree-toggle::before,
	.dv-tree .dv-tree-item[aria-expanded] > .dv-tree-row > .dv-tree-toggle::before {
		content: "";
		inline-size: 0.45em;
		block-size: 0.45em;
		border-inline-end: 2px solid;
		border-block-end: 2px solid;
		transform: translateX(-0.15em) rotate(-45deg);
		transition: transform var(--motion-duration) ease-out;
	}

	.dv-tree .dv-tree-branch[open] > .dv-tree-row > .dv-tree-toggle::before,
	.dv-tree .dv-tree-item[aria-expanded="true"] > .dv-tree-row > .dv-tree-toggle::before {
		transform: translateY(-0.15em) rotate(45deg);
	}

	/* Mirrored: the chevron points to the inline end on the other side. */
	.dv-tree:dir(rtl) .dv-tree-branch > .dv-tree-row > .dv-tree-toggle::before,
	.dv-tree:dir(rtl) .dv-tree-item[aria-expanded] > .dv-tree-row > .dv-tree-toggle::before {
		transform: translateX(0.15em) rotate(45deg);
	}

	.dv-tree:dir(rtl) .dv-tree-branch[open] > .dv-tree-row > .dv-tree-toggle::before,
	.dv-tree:dir(rtl) .dv-tree-item[aria-expanded="true"] > .dv-tree-row > .dv-tree-toggle::before {
		transform: translateY(-0.15em) rotate(-45deg);
	}

	/* A branch that is loading its children. */
	.dv-tree .dv-tree-item[aria-busy="true"] > .dv-tree-row > .dv-tree-toggle::before {
		opacity: 0.4;
	}

	/* Selected: a tinted row with the accent bar at its start (also the no-script current node). */
	.dv-tree .dv-tree-item[aria-selected="true"] > .dv-tree-row,
	.dv-tree .dv-tree-row:has(> .dv-tree-label[aria-current]) {
		background: var(--tree-selected-background);
		border-inline-start-color: var(--color-accent);
	}

	/* Focus: the focus tokens on the row only (the item holds its whole branch), inside the row's box so
	   it is never clipped. Selected and focused is this plus the bar; selected without focus is the tint. */
	.dv-tree .dv-tree-item:focus-visible {
		outline: none;
	}

	.dv-tree .dv-tree-item:focus-visible > .dv-tree-row {
		color: var(--color-focus-text);
		background: var(--color-focus-background);
		outline: var(--focus-outline-width) solid var(--color-focus-outline);
		outline-offset: calc(-1 * var(--focus-outline-width));
	}

	.dv-tree .dv-tree-item:focus-visible > .dv-tree-row .dv-tree-label {
		color: inherit;
	}

	/* The live region of lazy loading: one line under the tree, there before it speaks. */
	.dv-tree .dv-tree-status {
		min-block-size: var(--font-line-height);
		margin-block-start: var(--space-1);
		font-size: var(--font-size-small);
	}

	/* Compact: lower rows, a narrower column, a smaller gap. */
	.dv-tree--compact .dv-tree-row {
		gap: var(--tree-gap-compact);
		min-block-size: var(--tree-row-height-compact);
	}

	.dv-tree--compact .dv-tree-toggle {
		inline-size: var(--tree-indent-compact);
	}

	.dv-tree--compact .dv-tree-group .dv-tree-group {
		margin-inline-start: calc(0.25em + var(--tree-indent-compact) / 2);
		padding-inline-start: calc(var(--tree-indent-compact) / 2 - 0.25em);
	}

	/* Forced colours: system colours only; the selected row in Highlight, the guides and the focus visible. */
	@media (forced-colors: active) {
		.dv-tree .dv-tree-group .dv-tree-group {
			border-inline-start-color: GrayText;
		}

		.dv-tree .dv-tree-row {
			forced-color-adjust: none;
			color: CanvasText;
			background: Canvas;
			border-inline-start-color: transparent;
		}

		.dv-tree .dv-tree-row:hover {
			background: Canvas;
			text-decoration: underline;
		}

		.dv-tree .dv-tree-label[href] {
			color: LinkText;
		}

		/* Focus: the outline in the text colour. Selected (after it, so it wins): the system highlight;
		   selected and focused is the highlight with the outline, selected alone the highlight. */
		.dv-tree .dv-tree-item:focus-visible > .dv-tree-row {
			color: CanvasText;
			background: Canvas;
			outline-color: CanvasText;
		}

		.dv-tree .dv-tree-item:focus-visible > .dv-tree-row .dv-tree-label {
			color: CanvasText;
		}

		.dv-tree .dv-tree-item[aria-selected="true"] > .dv-tree-row,
		.dv-tree .dv-tree-row:has(> .dv-tree-label[aria-current]) {
			color: HighlightText;
			background: Highlight;
			border-inline-start-color: Highlight;
		}

		.dv-tree .dv-tree-item[aria-selected="true"] > .dv-tree-row .dv-tree-label,
		.dv-tree .dv-tree-row:has(> .dv-tree-label[aria-current]) .dv-tree-label {
			color: HighlightText;
		}
	}
}
