/* TreeView component styling — see docs/requirements/Component-TreeView.md "Visual Design Guide" (V1–V7). */ /* Root list — no list styling. */ .tv-root, .tv-root ul { list-style: none; padding-left: 0; margin: 0; } /* V1 — Row anatomy. Flex container; full-width hit surface; ~32px row. */ .tv-row { display: flex; align-items: center; gap: 0.25rem; padding: 0.25rem 0.5rem; cursor: default; border-radius: 0.25rem; transition: background-color 0.08s linear; } /* V1 — slot widths. Toggle and glyph are always present so labels align across siblings. */ .tv-row .tv-toggle, .tv-row .tv-spacer { flex: 0 0 auto; width: 1.25rem; /* 20px */ display: inline-flex; align-items: center; justify-content: center; cursor: pointer; color: var(--bs-secondary-color); user-select: none; } .tv-row .tv-spacer { cursor: default; } .tv-row .tv-content { flex: 1 1 auto; min-width: 0; /* required so child label can ellipsis-truncate inside a flex item */ display: flex; align-items: center; gap: 0.25rem; } /* V5 — primary label truncation. Consumers add their own bold class for branches. */ .tv-row .tv-label { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* V1 — meta slot right-aligns trailing badges/text against row edge. */ .tv-row .tv-meta { margin-left: auto; display: inline-flex; align-items: center; gap: 0.25rem; flex: 0 0 auto; } /* V4 — glyph slot. Bootstrap Icons render at 1em, inherit text color. */ .tv-row .tv-glyph { flex: 0 0 auto; width: 1.25rem; /* 20px, same slot size as toggle */ display: inline-flex; align-items: center; justify-content: center; } /* V3 — hover. Subtle gray wash; suppressed when row is selected. */ .tv-row:hover:not(.tv-selected) { background-color: var(--bs-tertiary-bg); } /* V3 — selected. Bootstrap utility `bg-primary bg-opacity-10` is the SelectedCssClass default; the .tv-selected hook is provided for consumers that prefer scoped styling. */ .tv-row.tv-selected { background-color: rgba(var(--bs-primary-rgb), 0.1); } /* V3 — keyboard focus. Inset ring composes with hover/selected without layout shift. */ .tv-row:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--bs-primary); } /* V3 — drop-target (valid). Overrides hover/selected. */ .tv-row.tv-drop-target { background-color: rgba(var(--bs-info-rgb), 0.25); } /* V3 — dimmed (e.g. non-droppable while a drag is in progress; reserved for future use). */ .tv-row.tv-dimmed { opacity: 0.5; } /* V2 — guide lines. A pseudo-element overlays the row's depth gutter and draws one vertical line per ancestor depth at 24px intervals. The `--tv-depth` variable is set inline per row; lines never extend into the content area. */ .tv-guides .tv-row { position: relative; } .tv-guides .tv-row::before { content: ""; position: absolute; top: 0; left: 0; bottom: 0; width: calc(var(--tv-depth, 0) * 1.5rem); pointer-events: none; background-image: linear-gradient( to right, transparent calc(0.625rem - 0.5px), var(--bs-border-color) calc(0.625rem - 0.5px), var(--bs-border-color) calc(0.625rem + 0.5px), transparent calc(0.625rem + 0.5px) ); background-size: 1.5rem 100%; background-repeat: repeat-x; } /* Branch chevron rotates on expand via the aria-expanded attribute on the parent treeitem. Consumers using `bi-chevron-right` get the down-rotation for free. */ .tv-row .tv-toggle .bi-chevron-right { transition: transform 0.1s linear; } [role="treeitem"][aria-expanded="true"] > .tv-row .tv-toggle .bi-chevron-right { transform: rotate(90deg); }