/* ===========================================================================
   Department-tree component styles. All `.dt-*` rules.
   M-A: layout differences live here, not in Razor @if (IsMobile) branches.
   data-style attribute selectors enable future per-viewport overrides
   (forward-compat for M-A → M-D).
   =========================================================================== */

.dt-tree {
    width: 100%;

    /* ── CSS variable surface ───────────────────────────────────────────
       The dept tree is fully tunable via CSS custom properties. Each
       consumer rule reads its var with a fallback default — so callers
       OVERRIDE by setting the var on ANY ANCESTOR of <DepartmentTree>:

         <div style="--dt-name-font-size: 13px">
             <DepartmentTree ... />
         </div>

       … or page-scoped:

         .org-tree-body { --dt-name-font-size: 13px;
                          --dt-name-font-weight: 500; }

       … or globally:

         :root { --dt-name-font-size: 16px; }

       IMPORTANT: declarations are NOT placed on .dt-tree itself, because
       .dt-tree sits INSIDE the wrapper — a declaration here would shadow
       the wrapper's override (CSS custom property cascade resolves to
       the closest ancestor declaration, which would be .dt-tree). The
       defaults live in the var() fallback at each consumer site instead.

       Available vars (default in parentheses):
         · --dt-font-family               (inherit)
         · --dt-name-font-size            (14px)
         · --dt-name-font-weight          (500 — medium, not bold)
         · --dt-name-font-weight-selected (700 — applied via [data-selected])
         · --dt-count-font-size           (11px)
         · --dt-head-font-size            (12px)
         · --dt-head-count-font-size      (10px)
         · --dt-emp-font-size             (12px)
         · --dt-emp-font-weight           (500 — same as dept name; bump to 600+ for emphasis)
         · --dt-emp-job-font-size         (11px)
         · --dt-emp-chip-font-size        (10px — chip text inside inline employee rows)
         · --dt-emp-avatar-size           (20px)
         · --dt-emp-row-padding-y         (1px — vertical padding on each inline row)
         · --dt-emp-row-gap               (6px — between elements within a row)
         · --dt-emp-row-border            (1px solid var(--mud-palette-divider) — edge around each inline row)
         · --dt-chevron-border            (1px solid var(--mud-palette-divider))
         · --dt-chevron-bg                (var(--mud-palette-surface))
         · --dt-name-line-grow            (1 — pill fills row; set 0 for narrow pill)
         · --dt-empty-head-row-height     (0 — empty head row collapsed; set 4px+ for legacy strip)
         · --dt-empty-head-row-border     (0 — set to 1px solid for legacy divider)
       ─────────────────────────────────────────────────────────────────── */
}

/* Pre-paint hide while dynamicTreeIndent.apply is in flight. Without this, the
   tree first renders at MudTreeView's default --app-tree-indent then jumps to
   the calculated value when the JS interop round-trip lands — perceptible as a
   flash on slow networks and on first page load. visibility:hidden keeps the
   layout box reserved (so the page doesn't shift when reveal happens) but
   suppresses the paint. The component sets _indentApplied=true once the first
   apply call returns and StateHasChanged removes this class. */
.dt-root.dt-indent-pending .mud-treeview {
    visibility: hidden;
}

/* ── Dev gallery (/dev/dept-tree-gallery) ────────────────────────────────── */
.gallery-title-row {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}
.gallery-recipe {
    margin: 4px 0 12px;
    padding: 8px 10px;
    background: var(--mud-palette-surface);
    border-left: 3px solid var(--mud-palette-primary);
    border-radius: 4px;
    font-family: 'Cascadia Code', Consolas, monospace;
    font-size: 12px;
    color: var(--mud-palette-text-secondary);
    overflow-x: auto;
    white-space: pre-wrap;
}
.gallery-renders {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    align-items: flex-start;
}
.gallery-render-col {
    flex: 1 1 320px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
/* Mobile column targets ~360px (typical small-phone portrait minus padding)
   on wide viewports. flex-shrink: 1 + min-width: 0 lets it compress when
   the parent itself is narrower than 360px (e.g. when the gallery is opened
   on a real phone) — without this, the fixed 360px would overflow the page
   and force a horizontal scrollbar with content cut on the right. The
   dynamic-indent JS measures the actual rendered width on each render, so
   the tree inside still fits regardless of how far the column compresses. */
.gallery-render-col-mobile {
    flex: 0 1 360px;
    max-width: 360px;
    min-width: 0;
}
.gallery-render-label {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--mud-palette-text-secondary);
    font-weight: 600;
}
.gallery-render {
    border: 1px dashed var(--mud-palette-lines-default);
    border-radius: 6px;
    padding: 8px;
    background: var(--mud-palette-background-grey);
}

/* Suppress MudTreeViewItem's native expand arrow — replaced by the Pattern A
   .dt-col-chevron button rendered inside <DepartmentTreeRow>. MudBlazor's
   internal expand state is driven by the controlled Expanded/ExpandedChanged
   binding on <MudTreeViewItem>, so hiding the arrow visually does not break
   keyboard expand/collapse — our chevron writes to the same _expandedIds
   HashSet that flows back into MudBlazor via the controlled binding. */
.dt-tree .mud-treeview-item-arrow { display: none !important; }

.dt-row {
    display: flex;
    align-items: stretch;
    gap: 6px;
    border-radius: 6px;
    min-height: 32px;
    padding: 1px 4px;
    /* min-width:0 lets the row shrink below its intrinsic content width when
       the cumulative MudTreeView indent narrows the available space at deep
       depths. Without this, the row defaults to min-width:auto (intrinsic
       content) and pushes past the panel's right edge. The .dt-name's
       text-overflow:ellipsis + the count chip's flex-shrink: 1 handle the
       actual content truncation cleanly. */
    min-width: 0;
}
/* Allow the count chip to shrink below MudChip's default 32px min-width when
   the row is squeezed. At deep depths on narrow phones, the chip absorbs
   some of the squeeze (numbers stay visible at a smaller chip footprint)
   and the rest comes from name ellipsization. */
.dt-count-chip.mud-chip {
    min-width: 0 !important;
    flex-shrink: 1 !important;
    /* Pin font to the dept-tree vars rather than MudChip's defaults so the
       count chip stays consistent with the rest of the tree across all
       RowStyle presets. */
    font-family: var(--dt-font-family, inherit) !important;
    font-size: var(--dt-count-font-size, 11px) !important;
    /* Override MudChip's 32-px min-height so the chip doesn't dominate the
       row vertically. Keeps the chip pill compact across all presets. */
    min-height: auto !important;
    height: auto !important;
    padding: 1px 8px !important;
    /* Suppress MudChip's inherited line-height (~1.5) — at 11-px font that
       added ~5 px of phantom vertical space around the text. line-height:1
       collapses the chip to its true content height. */
    line-height: 1 !important;
}
/* MudChip wraps text in two inner spans (.mud-chip-content + .mud-chip-label).
   Both inherit MudBlazor's defaults — strip their padding/margin/line-height
   so the chip's effective height equals just the icon + text + 1-px padding,
   matching Plain's <span class="dt-count-text"> bare-span height. */
.dt-count-chip .mud-chip-content,
.dt-count-chip .mud-chip-label {
    padding: 0 !important;
    margin: 0 !important;
    line-height: 1 !important;
}
/* Shrink the chip's leading icon (Diversity3 glyph) so it matches the
   surrounding text height. MudChip Size.Small ships a ~20-px icon, which
   would otherwise dominate the row vertically and make PlainWithCountChip /
   ChipLabel / ChipLabelWithHead taller than Plain. AccentBar + Plain hide
   the icon entirely via a separate rule, so this only affects styles that
   show it. */
.dt-count-chip .mud-chip-icon {
    font-size: 14px !important;
    width: 14px !important;
    height: 14px !important;
    line-height: 1 !important;
    margin: 0 2px 0 0 !important;
}
.dt-count-chip .mud-chip-icon svg {
    width: 14px !important;
    height: 14px !important;
}

/* Chevron — bordered surface square by default. Override the two CSS vars
   above on any ancestor to switch back to the legacy flat look. The fixed
   24-px height + align-self: center keeps the chevron a consistent square
   inside taller rows (e.g. ChipLabelWithHead at 32 px). */
.dt-col-chevron {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    min-width: 24px;
    height: 24px;
    align-self: center;
    background: var(--dt-chevron-bg, var(--mud-palette-surface));
    border: var(--dt-chevron-border, 1px solid var(--mud-palette-divider));
    cursor: pointer;
    border-radius: 4px;
    color: var(--dt-color, var(--mud-palette-text-secondary));
    transition: background-color 120ms ease, border-color 120ms ease;
}
.dt-col-chevron:hover {
    background: color-mix(in srgb, var(--mud-palette-primary) 10%, var(--mud-palette-surface));
    border-color: color-mix(in srgb, var(--mud-palette-primary) 50%, var(--mud-palette-divider));
}
/* Leaf placeholder — same width slot for alignment, but no border / no fill. */
.dt-col-chevron-leaf {
    width: 24px;
    min-width: 24px;
    background: transparent;
    border-color: transparent;
}

/* Selected row — driven by SelectedId match. Coloured outline matches the
   row's --dt-color so the selected tint reads as "this dept" rather than
   a generic palette accent. Used by /orgchart-graph dept list. */
.dt-row[data-selected="true"] {
    background: color-mix(in srgb, var(--dt-color) 14%, transparent);
    outline: 1px solid color-mix(in srgb, var(--dt-color) 60%, transparent);
}

.dt-col-main {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.dt-name-line {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 2px 6px;
    min-width: 0;
    /* When --dt-name-line-grow is 1 (default), the name-line stretches to
       fill any extra vertical space inside .dt-col-main (which itself
       stretches to row height). When the dt-head-row sibling is also
       present, the head row claims its own content size and there's no
       extra space to grow into — flex-grow has no visible effect. */
    flex-grow: var(--dt-name-line-grow, 1);
}

.dt-icon {
    color: var(--dt-color, var(--mud-palette-text-secondary));
    flex-shrink: 0;
}

.dt-name {
    font-family: var(--dt-font-family, inherit);
    font-size: var(--dt-name-font-size, 14px);
    font-weight: var(--dt-name-font-weight, 600);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}

.dt-count-text {
    font-family: var(--dt-font-family, inherit);
    font-size: var(--dt-count-font-size, 11px);
    color: var(--mud-palette-text-secondary);
    flex-shrink: 0;
}

.dt-count-chip {
    margin-left: auto;
    flex-shrink: 0;
}

/* ─── ChipLabel + ChipLabelWithHead — coloured pill ─── */
.dt-row[data-style="chip-label"] .dt-col-main,
.dt-row[data-style="chip-label-with-head"] .dt-col-main {
    border: 1px solid var(--mud-palette-divider);
    border-radius: 6px;
    overflow: hidden;
}
.dt-row[data-style="chip-label"] .dt-name-line,
.dt-row[data-style="chip-label-with-head"] .dt-name-line {
    background: var(--dt-color, var(--mud-palette-primary));
    color: white;
    padding: 2px 8px;
    /* Font controlled by .dt-name and the .dt-tree CSS vars. */
}
.dt-row[data-style="chip-label"] .dt-name,
.dt-row[data-style="chip-label-with-head"] .dt-name { color: white; }
.dt-row[data-style="chip-label"] .dt-icon,
.dt-row[data-style="chip-label-with-head"] .dt-icon { color: white; }

/* ChipLabel + ChipLabelWithHead: count chip on the coloured pill — match the
   dept name text colour (white) so the chip reads as part of the same surface.
   Border uses semi-transparent white so the chip's outline is visible against
   any --dt-color background. For ChipLabelWithHead, the head sub-row below
   stays name-only (no count duplicated there). */
.dt-row[data-style="chip-label"] .dt-count-chip.mud-chip,
.dt-row[data-style="chip-label-with-head"] .dt-count-chip.mud-chip {
    color: white !important;
    border-color: rgba(255, 255, 255, 0.55) !important;
    background: transparent !important;
}
.dt-row[data-style="chip-label"] .dt-count-chip .mud-chip-icon,
.dt-row[data-style="chip-label-with-head"] .dt-count-chip .mud-chip-icon {
    color: white !important;
}

/* Head sub-row */
.dt-head-row {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 1px 8px;
    font-family: var(--dt-font-family, inherit);
    font-size: var(--dt-head-font-size, 12px);
    color: var(--mud-palette-text-secondary);
    border-top: 1px solid var(--mud-palette-divider);
    white-space: nowrap;
    min-height: 20px;
}
/* Empty head sub-row — rendered in DOM but visually collapsed by default.
   The two CSS vars above let a caller opt into the legacy narrow-strip look
   ("two stacked chips" with a thin white band below the coloured pill).
   .dt-head-row.dt-head-row-empty has specificity (0,2,0) so it wins over
   the base .dt-head-row min-height/padding/border-top rule above. */
.dt-head-row.dt-head-row-empty {
    min-height: var(--dt-empty-head-row-height, 0) !important;
    height: var(--dt-empty-head-row-height, 0);
    padding: 0 !important;
    border-top: var(--dt-empty-head-row-border, 0);
    overflow: hidden;
}
.dt-head-name { font-weight: 700; color: var(--mud-palette-text-primary); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.dt-head-vacant { color: var(--mud-palette-warning); font-weight: 700; }
.dt-head-you { color: var(--mud-palette-success); font-weight: 700; }
.dt-count-icon-text {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    font-size: var(--dt-head-count-font-size, 10px);
    opacity: 0.85;
    margin-left: auto;
    flex-shrink: 0;
}

/* ─── Right slot ─── */
.dt-col-end {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

/* ─── Header / Footer slots ─── */
.dt-header { padding: 4px 0; }
.dt-footer { padding: 4px 0; }

/* ─── Inline employee rows (EmployeeMode = Inline) ───
   The .dt-emp-list flex-column container guarantees vertical stacking of
   employee rows AND anchors them to the top of the available content area
   (align-self: flex-start) — without this, MudTreeView's BodyContent flex
   parent vertically centers the list when the dept row is taller than the
   list, making the list visually drift toward the row's middle.

   Each .dt-emp-row uses flex-wrap: nowrap so its contents stay on a single
   line — name and job get text-overflow: ellipsis when the row is too narrow.
   Avatar and chips have flex-shrink: 0 so they're never compressed.

   Typography defaults (--dt-emp-*) match the dept-line system: smaller and
   lighter than the dept name to keep the inline list visually subordinate
   to its parent row. Override on any ancestor via the standard CSS-var
   pattern. */
.dt-emp-list {
    display: flex;
    flex-direction: column;
    align-self: flex-start;
    flex: 1;
    min-width: 0;
}

/* Inline-card layout: dept pill (.dt-col-main) on the left + employee list
   (.dt-emp-list) on the right, wrapped in a single rounded outer border.
   Used when DepartmentTree's EmployeeMode = Inline. The chevron sits OUTSIDE
   this card on the far left of .dt-row. */
.dt-row-inline-card {
    display: flex;
    flex-direction: row;
    /* Both children's first row (pill + first emp-row) are forced to the
       same exact height via height: var(--dt-inline-row-height) below — so
       top-anchoring the columns produces perfect center alignment for those
       first rows. Subsequent emp-rows in the list flow below; the dept
       column stays at its first-row height anchored to the top. */
    align-items: flex-start;
    flex: 1;
    min-width: 0;
    border: 1px solid var(--mud-palette-divider);
    border-radius: 6px;
    padding: 4px;                  /* internal breathing room so chips don't touch outer border */
    gap: 4px;                      /* between dept column and emp-list */
}
/* When .dt-row contains an inline card, the row is tall (the card spans all
   the employee rows). The chevron's default align-self: center would drift
   it toward the row's vertical middle. Anchor it to the top so it lines up
   with the dept pill (which is also top-anchored inside the card). Scoped
   via :has() to apply only when an inline card is present — non-Inline
   presets keep the chevron's center alignment. */
.dt-row:has(> .dt-row-inline-card) > .dt-col-chevron {
    align-self: flex-start;
}
.dt-row-inline-card > .dt-col-main {
    /* Drop dt-col-main's own border + radius — each chip-like child handles
       its own visible edge. flex: 0 0 auto sizes the column to its content.
       align-items: flex-start pins the name-line to the top of the column. */
    border: none !important;
    border-radius: 0 !important;
    flex: 0 0 auto;
    flex-direction: row;
    align-items: flex-start;
}
/* Both the dept pill and the inline employee rows share an EXACT (not min)
   height so their boxes are pixel-identical. The height is computed from
   the number of lines the content needs — desktop wraps to 1 line, mobile
   wraps to 2 lines (name + chips on line 1, ID + job on line 2). The
   formula: line-count × line-height + 2 × padding + breathing-room.

   On a 12-px font (--dt-emp-font-size default) with a 1.15 line-height
   multiplier (glyph height + small ascender/descender margin), 1 line is
   ~14 px and 2 lines are ~28 px. Plus 2 × 2 px padding-y + 4 px breathing
   gives 22 px (1-line) or 36 px (2-line). Round up to 28 / 40 for slightly
   more comfort. The single --dt-inline-row-height var lets a caller
   override with a literal value; --dt-inline-row-line-count = 2 in mobile
   triggers the multi-line formula. */
.dt-row-inline-card > .dt-col-main .dt-name-line,
.dt-row-inline-card .dt-emp-row {
    --_dt-row-h-formula: calc(
        var(--dt-inline-row-line-count, 1) * var(--dt-emp-font-size, 12px) * 1.4
        + 2 * var(--dt-emp-row-padding-y, 2px)
        + 8px
    );
    /* DEMO-14 (2026-04-28): dropped fixed `height:` and kept only `min-height:`.
       The original `height` was for pixel-perfect dept-pill ↔ first-emp-row
       alignment, but when an employee has many profile chips that wrap to 3+
       lines on a phone the fixed height clipped the trailing chips and they
       rendered on top of each other. Variable row height is the correct
       behaviour when content wraps; the alignment intent is preserved by the
       formula's --dt-inline-row-line-count which still drives the minimum. */
    min-height: var(--dt-inline-row-height, var(--_dt-row-h-formula));
    border-radius: 4px;
    box-shadow: inset 0 0 0 1px var(--mud-palette-divider);
}
/* All chips and icons inside the inline card are constrained to fit within
   the fixed row height. Without this, MudChip's Size.Small min-height: 32px
   default + the Diversity3 / dept icons at 1.25rem expand the rows past the
   target height. */
.dt-row-inline-card .mud-chip {
    /* DEMO-14 follow-up: text was clipping the top of the pill. 26 px with
       a normalised font-size and forced flex-centering at every nested
       level (chip → chip-content → chip-label) puts the glyph baseline in
       the visual centre. */
    min-height: auto !important;
    height: 26px !important;
    max-height: 26px !important;
    line-height: 1 !important;
    padding: 0 10px !important;
    font-size: 11px !important;
    display: inline-flex !important;
    align-items: center !important;
    box-sizing: border-box !important;
}
.dt-row-inline-card .mud-chip-content,
.dt-row-inline-card .mud-chip-label {
    padding: 0 !important;
    margin: 0 !important;
    line-height: 1 !important;
    height: 100% !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}
.dt-row-inline-card .mud-chip-icon {
    font-size: 12px !important;
    width: 12px !important;
    height: 12px !important;
    line-height: 1 !important;
    margin: 0 2px 0 0 !important;
}
.dt-row-inline-card .mud-chip-icon svg {
    width: 12px !important;
    height: 12px !important;
}
/* Cap icon and avatar sizes inside the card */
.dt-row-inline-card .dt-icon,
.dt-row-inline-card > .dt-col-main .dt-name-line .mud-icon {
    font-size: 16px !important;
    width: 16px !important;
    height: 16px !important;
}
/* For ChipLabel / ChipLabelWithHead, the dept pill has a coloured background
   that already provides visual "weight" — a gray inset shadow on top would
   look muddy. Use semi-transparent white instead, matching the count chip's
   border treatment on the same coloured surface. */
.dt-row[data-style="chip-label"] .dt-row-inline-card > .dt-col-main .dt-name-line,
.dt-row[data-style="chip-label-with-head"] .dt-row-inline-card > .dt-col-main .dt-name-line {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35);
}
.dt-row-inline-card > .dt-col-main .dt-name-line {
    flex-grow: 0;
    align-self: flex-start;
}

/* Mobile-only line-break sentinel inside .dt-emp-content. Hidden on desktop
   (display: none). On mobile, it becomes a flex-basis: 100% / height: 0
   element that forces a wrap point in the flex container — name + chips
   stay on line 1, everything after the break wraps to line 2. */
.dt-emp-row-break {
    display: none;
    flex-basis: 100%;
    height: 0;
}
.dt-row-inline-card > .dt-emp-list {
    /* Employee list takes the rest of the card. gap between consecutive
       emp-rows so each one reads as a discrete chip rather than stacked
       attached blocks. */
    flex: 1;
    min-width: 0;
    margin-left: 0;
    gap: 4px;
}
/* Emp-row's padding matches the pill's chip-label `padding: 2px 8px` so
   their interior content boxes are pixel-identical. The visible border is
   shared with the pill via the rule above (box-shadow: inset). */
.dt-row-inline-card .dt-emp-row {
    border: none !important;
    padding: 2px 8px;
}
/* line-height: 1 on the dept name and emp name fixes a subtle vertical
   offset: with default line-height (~1.5), text glyphs sit centered within
   a tall line-box, but their visible centers are slightly above box center
   due to font ascender/descender geometry. line-height: 1 collapses the
   line-box to glyph height so text centers truly = box centers. */
.dt-row-inline-card .dt-name,
.dt-row-inline-card .dt-emp-name {
    line-height: 1;
}

/* Mobile responsive: on narrow viewports the card stacks vertically — dept
   pill on top, employees below. Each chip carries its own border (via box-
   shadow: inset on the dept pill and emp-rows), so no extra dividers needed
   between dept area and emp-list. Same DOM, no Razor changes — just
   flex-direction swap.

   Width sizing rules (the headache):
   - Children of column-flex parent default to align-items: stretch (= full
     card width). We override to flex-start so the dept pill and emp-list
     hug their content horizontally.
   - max-width: 100% on dept-col-main is critical: at deep indents, the
     pill's intrinsic content width can exceed the card width, and without
     a max cap the pill overflows past the card's right edge. The cap +
     min-width: 0 on .dt-name-line lets .dt-name's text-overflow: ellipsis
     engage.
   - Each .dt-emp-row uses width: fit-content; max-width: 100% so it hugs
     its wrapped content but never exceeds card width — so single-employee
     rows are narrow, multi-line wrapped rows expand to their max-line width.
   - The line-break sentinel between chips and job activates here, forcing
     line 1 = name + chips, line 2 = ID + job (order: 1 on .dt-emp-job
     places it AFTER the slot's default order 0, so ID renders before job).
   Same selectors mirrored on .dt-mobile-preview for gallery-side preview. */
@media (max-width: 600px) {
    .dt-row-inline-card {
        flex-direction: column;
        --dt-inline-row-line-count: 2;     /* recompute height for 2-line content */
        /* Card sizes to its widest child's intrinsic content width (not the
           full row width). Override base flex: 1 so the card doesn't grow,
           and align-self: flex-start anchors it to the row's start. With both
           children (.dt-col-main and .dt-emp-list) using align-items: stretch
           (overrides the desktop base's flex-start, which would horizontally
           start-align children in column flex and leave the pill narrower
           than the list), they BOTH end up at the card width — which equals
           max(pill content, widest emp-row content). Net effect: dept pill
           and every emp-row chip share an identical width on mobile. */
        flex: 0 1 auto;
        align-self: flex-start;
        align-items: stretch;
        max-width: 100%;
    }
    .dt-row-inline-card > .dt-col-main {
        max-width: 100%;                   /* clamp at card width so deep-indent names ellipsize */
        /* align-self defaults to stretch — pill fills the (content-sized) card */
    }
    /* The visible pill border lives on .dt-name-line (via box-shadow: inset),
       not on .dt-col-main (which has border: none). The base inline-card
       override at line ~508 sets flex-grow: 0 on the name-line, so on mobile
       the name-line stays content-sized inside a stretched col-main — leaving
       invisible empty space to the right of the visible pill. Force flex-grow: 1
       here so the name-line fills col-main horizontally, making the pill's
       visible width match the card width (= emp-row width). */
    .dt-row-inline-card > .dt-col-main .dt-name-line {
        flex-grow: 1;
    }
    .dt-row-inline-card .dt-emp-list {
        margin-left: 0 !important;
        max-width: 100%;
        /* align-self defaults to stretch — list fills the card; align-items
           defaults to stretch — every emp-row fills the list. So all emp-rows
           are equal width = card width = widest sibling content. */
    }
    .dt-row-inline-card .dt-emp-row {
        align-items: center;
        padding-left: 6px;
    }
    .dt-row-inline-card .dt-emp-content {
        flex-wrap: wrap;
        row-gap: 0;          /* tight wrapping — line 2 sits flush below line 1 */
    }
    .dt-row-inline-card .dt-emp-row-break {
        display: block;
    }
    .dt-row-inline-card .dt-emp-job {
        order: 1;   /* place job after slot on line 2 */
    }
}
/* .dt-mobile-preview opt-in twin so the gallery's mobile column gets the
   stacked layout regardless of viewport. Keep in sync with the @media block
   above. */
.dt-mobile-preview .dt-row-inline-card {
    flex-direction: column;
    --dt-inline-row-line-count: 2;
    flex: 0 1 auto;
    align-self: flex-start;
    align-items: stretch;
    max-width: 100%;
}
.dt-mobile-preview .dt-row-inline-card > .dt-col-main {
    max-width: 100%;
}
.dt-mobile-preview .dt-row-inline-card > .dt-col-main .dt-name-line {
    flex-grow: 1;
}
.dt-mobile-preview .dt-row-inline-card .dt-emp-list {
    margin-left: 0 !important;
    max-width: 100%;
}
.dt-mobile-preview .dt-row-inline-card .dt-emp-row {
    align-items: center;
    padding-left: 6px;
}
.dt-mobile-preview .dt-row-inline-card .dt-emp-content {
    flex-wrap: wrap;
    row-gap: 0;
}
.dt-mobile-preview .dt-row-inline-card .dt-emp-row-break {
    display: block;
}
.dt-mobile-preview .dt-row-inline-card .dt-emp-job {
    order: 1;
}
.dt-emp-row {
    display: flex;
    align-items: center;
    gap: var(--dt-emp-row-gap, 6px);
    flex-wrap: nowrap;
    padding: var(--dt-emp-row-padding-y, 1px) 6px;
    font-family: var(--dt-font-family, inherit);
    font-size: var(--dt-emp-font-size, 12px);
    font-weight: var(--dt-emp-font-weight, 500);
    border: var(--dt-emp-row-border, 1px solid var(--mud-palette-divider));
    border-radius: 4px;
    min-width: 0;
}
.dt-emp-row.is-me {
    background: color-mix(in srgb, var(--mud-palette-primary) 7%, transparent);
}
.dt-emp-row.inactive { opacity: 0.5; }
/* Content wrapper inside .dt-emp-row — sits to the right of the avatar.
   Desktop: single-line flex with horizontal layout (matches old behaviour).
   Mobile: flex-wrap kicks in below to flow content over multiple lines. */
.dt-emp-content {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: var(--dt-emp-row-gap, 6px);
    flex: 1;
    min-width: 0;
}
/* Avatar doesn't shrink — keeps its 20-px slot regardless of viewport. */
.dt-emp-row > .mud-avatar,
.dt-emp-row > [class*="avatar"] {
    flex-shrink: 0;
}
/* Inside the content wrapper: chips don't shrink, name and job absorb
   the squeeze (with ellipsis on desktop, wrap to next line on mobile). */
.dt-emp-content > *:not(.dt-emp-name):not(.dt-emp-job) {
    flex-shrink: 0;
}
.dt-emp-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    flex-shrink: 1;
}
.dt-emp-job {
    color: var(--mud-palette-text-secondary);
    font-size: var(--dt-emp-job-font-size, 11px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    flex-shrink: 2;   /* job truncates twice as fast as name when both must shrink */
}
/* Chips inside inline employee rows — smaller font + tighter padding to match
   the row's reduced font density. Flex-shrink: 0 (inherited from the
   not(.dt-emp-name):not(.dt-emp-job) rule above) keeps them at content size. */
.dt-emp-row .mud-chip {
    font-size: var(--dt-emp-chip-font-size, 10px) !important;
    min-height: auto !important;
    height: auto !important;
    padding: 0 6px !important;
    line-height: 1 !important;
}
.dt-emp-row .mud-chip-content,
.dt-emp-row .mud-chip-label {
    padding: 0 !important;
    margin: 0 !important;
    line-height: 1 !important;
}

/* ─── Plain + AccentBar — shared compact row look ─── */
/* These two presets share the compact 28px row, bordered chevron,
   transparent body, 12.5px font, and flat grey number pill. AccentBar adds
   a 3px coloured left bar on .dt-col-main as its distinguishing feature;
   Plain has no bar. The data-style selector specificity (0,2,0) wins over
   the mobile @media block (0,1,0) below — both presets stay compact at
   every viewport. */

/* Compact row dimensions — shared by Plain, PlainWithCountChip, and AccentBar.
   The rest of the compact look (bordered chevron, transparent body, flat pill,
   smaller font) is Plain+AccentBar-only because PlainWithCountChip keeps the
   default chevron + outlined MudChip count as its visual identity. */
.dt-row[data-style="accent-bar"],
.dt-row[data-style="plain"],
.dt-row[data-style="plain-count-chip"] {
    min-height: 24px;
    padding: 1px 4px;
    gap: 4px;
}
/* Chevron rules now live with the global .dt-col-chevron block above —
   the bordered square is the default for every preset. */

/* Main column: shared transparent body + 4px radius. */
.dt-row[data-style="accent-bar"] .dt-col-main,
.dt-row[data-style="plain"] .dt-col-main {
    border-radius: 4px;
    overflow: visible;
    background: transparent;
}
/* AccentBar-only — coloured 3px left bar. Plain skips this. */
.dt-row[data-style="accent-bar"] .dt-col-main {
    border: 1px solid transparent;
    border-left: 3px solid var(--dt-color, var(--mud-palette-divider));
}

/* Plain-family compact name-line — pin padding here at higher specificity
   (0,2,0) than the mobile @media .dt-name-line padding (0,1,0) so the
   tighter 2px-vertical padding survives on mobile. Without
   plain-count-chip in this selector, that style fell back to the base
   .dt-name-line { padding: 2px 6px } on desktop but was overridden to
   4px 8px on mobile, making the row visibly taller on phones. */
.dt-row[data-style="accent-bar"] .dt-name-line,
.dt-row[data-style="plain"] .dt-name-line,
.dt-row[data-style="plain-count-chip"] .dt-name-line {
    background: transparent;
    color: var(--mud-palette-text-primary);
    padding: 2px 6px;
    /* Font controlled by .dt-name and the .dt-tree CSS vars. */
}
.dt-row[data-style="accent-bar"] .dt-name,
.dt-row[data-style="plain"] .dt-name,
.dt-row[data-style="plain-count-chip"] .dt-name {
    color: var(--mud-palette-text-primary);
}
.dt-row[data-style="accent-bar"] .dt-icon,
.dt-row[data-style="plain"] .dt-icon {
    color: var(--dt-color, var(--mud-palette-text-secondary));
    font-size: 16px !important;
    width: 16px !important;
    height: 16px !important;
}

/* Hover — both presets tint .dt-col-main with --dt-color. */
.dt-row[data-style="accent-bar"]:hover .dt-col-main,
.dt-row[data-style="plain"]:hover .dt-col-main {
    background: color-mix(in srgb, var(--dt-color, var(--mud-palette-primary)) 8%, transparent);
}

/* Selected row — drop the global outline/tint, use --dt-color tinted bg.
   AccentBar additionally thickens its left bar (3 → 4 px) and brightens it. */
.dt-row[data-style="accent-bar"][data-selected="true"],
.dt-row[data-style="plain"][data-selected="true"] {
    background: transparent;
    outline: none;
}
.dt-row[data-style="accent-bar"][data-selected="true"] .dt-col-main,
.dt-row[data-style="plain"][data-selected="true"] .dt-col-main {
    background: color-mix(in srgb, var(--dt-color, var(--mud-palette-primary)) 16%, transparent);
}
.dt-row[data-style="accent-bar"][data-selected="true"] .dt-col-main {
    border-left-width: 4px;
    border-color: color-mix(in srgb, var(--dt-color, var(--mud-palette-primary)) 60%, transparent);
}
/* Selected-row name weight applies uniformly across all RowStyle presets.
   The default bump (500 → 700) signals selection without changing layout.
   Override --dt-name-font-weight-selected on .dt-tree to suppress the bump
   (set it equal to --dt-name-font-weight) or change its strength. */
.dt-row[data-selected="true"] .dt-name {
    font-weight: var(--dt-name-font-weight-selected, 700);
}

/* Count display — flat grey number pill, shared by all three Plain-family
   presets so they all sit at the same vertical height. AccentBar + Plain
   hide the icon (number-only); PlainWithCountChip keeps the icon visible
   (that's the preset's identity), but the chip's outlined chrome is replaced
   with an inset box-shadow so the edge is visible without taking layout space.

   display: inline-flex + align-items: center centers the icon and label
   vertically inside the chip — different font-sizes (icon 14px, label 11px)
   would otherwise stack by baseline (inline-block default) and drift apart. */
.dt-row[data-style="accent-bar"] .dt-count-chip.mud-chip,
.dt-row[data-style="plain"] .dt-count-text,
.dt-row[data-style="plain-count-chip"] .dt-count-chip.mud-chip {
    display: inline-flex !important;
    align-items: center !important;
    background: color-mix(in srgb, var(--mud-palette-text-primary) 6%, transparent) !important;
    border: none !important;
    height: auto !important;
    padding: 1px 6px !important;
    border-radius: 8px !important;
    font-size: 11px !important;
    color: var(--mud-palette-text-secondary) !important;
    margin: 0 4px 0 auto !important;
}
/* Edge for PlainWithCountChip — drawn via inset box-shadow so it sits at
   the chip's edge without contributing to height (unlike a real border).
   AccentBar + Plain skip the edge by design. */
.dt-row[data-style="plain-count-chip"] .dt-count-chip.mud-chip {
    box-shadow: inset 0 0 0 1px var(--mud-palette-divider) !important;
}
.dt-row[data-style="accent-bar"] .dt-count-chip .mud-chip-icon {
    display: none !important;
}

/* ─── Mobile portrait (≤ 600 px) ─── */
/* Row min-height + chevron width are intentionally NOT overridden here —
   the same dimensions used on desktop apply on mobile so the coloured pill
   (ChipLabel / ChipLabelWithHead) stays the same height across viewports.
   Other mobile adaptations (font padding tightening, employee-row margin)
   stay so narrow viewports get appropriate density. */
@media (max-width: 600px) {
    .dt-row { gap: 2px; }
    .dt-name-line { padding: 4px 8px; }
    .dt-emp-list { margin-left: 16px; }
    .dt-emp-row { gap: 4px; }
}

/* ─── Mobile preview class — opt-in twin of the @media (max-width:600px) block.
   Used by /dev/dept-tree-gallery to show desktop + mobile renderings side by
   side at any viewport. Mirrors the media query's effects but fires purely on
   .dt-mobile-preview ancestry. Keep in sync with the media query above. */
.dt-mobile-preview .dt-row { gap: 2px; }
.dt-mobile-preview .dt-name-line { padding: 4px 8px; }
.dt-mobile-preview .dt-emp-list { margin-left: 16px; }
.dt-mobile-preview .dt-emp-row { gap: 4px; }
