@use '../../style/theming';

// MARK: Variables
$list-item-padded-min-height: 42px;

// MARK: Mixin
@mixin core() {
  .dbx-list {
    overflow: hidden;
    height: 100%;

    // `--dbx-list-item-border-radius` (medium default) is the "how round" knob for the corners that
    // actually round — the first row's top, the last row's bottom, and any hovered/selected/activated
    // row. Interior corners stay square so the rows read as one connected group (see the per-position
    // and per-state rules below). `.dbx-list-square-items` zeroes the token and the style-demo
    // `list-corner-*` levers re-point it, so both keep working. The more specific
    // `.dbx-list-card-items-list` item rules deliberately win for card lists.
    //
    // IMPORTANT: do NOT declare `--dbx-list-item-border-radius` here — the style-demo levers set it on
    // an ancestor, and a local declaration would shadow that inherited value (killing the levers).
    // Instead resolve it once (with the medium fallback) into a private var the rules below consume;
    // referencing it here still reads the inherited lever value, so the levers keep control.
    --dbx-list-item-radius-resolved: var(--dbx-list-item-border-radius, var(--mat-sys-corner-medium, 12px));

    // Hairline gap between rows. Default 1px.
    --dbx-list-item-spacing: 1px;

    // Selected (selection list) / activated (nav list) row tone. Defaults to the M3 primary container
    // tone instead of the grey `--mat-sys-secondary-container` Material ships, with an on-tone for the
    // row's text + icons.
    --dbx-list-item-selected-color: var(--mat-sys-primary-container);
    --dbx-list-item-selected-on-color: var(--mat-sys-on-primary-container);

    // Active route (nav/value list `dbx-anchor-active`) row tone. A `dbx-anchor` row marks the active
    // route with its own `dbx-anchor-active` class rather than Material's `.mdc-list-item--activated`, so
    // it carries its own tone token here. Defaults to the selected/activated tone above (so an active
    // route reads the same as a selected row out of the box), but can be retargeted independently — e.g.
    // set `--dbx-list-item-active-color` on the list host — to give active routes a distinct color.
    --dbx-list-item-active-color: var(--dbx-list-item-selected-color);
    --dbx-list-item-active-on-color: var(--dbx-list-item-selected-on-color);

    // Rows are square by default; their corners round per-position / per-state below.
    --mat-list-active-indicator-shape: 0;
    --mat-list-list-item-container-shape: 0;

    // Selected (selection-list `--selected`) + activated (nav-list `--activated`) rows pick up the
    // primary tone rather than the grey default.
    --mat-list-list-item-selected-container-color: var(--dbx-list-item-selected-color);
    --mat-list-active-indicator-color: var(--dbx-list-item-selected-color);

    // Soften the hover state-layer so hovering doesn't grey-out as heavily (M3 default is 0.08).
    --mat-list-list-item-hover-state-layer-opacity: var(--dbx-list-item-hover-state-layer-opacity, 0.04);

    .mat-mdc-list-item {
      // Focus ring follows the row's own (per-position / per-state) shape token.
      --mat-focus-indicator-border-radius: var(--mat-list-list-item-container-shape);
      // Hairline gap between rows; the trailing row's gap is stripped by the :last-of-type / :only-of-type rules.
      margin-bottom: var(--dbx-list-item-spacing);
    }

    // Angular Material's `.mat-mdc-nav-list .mat-mdc-list-item` rule pins `border-radius` to
    // `--mat-list-active-indicator-shape` (which we set to 0 for square-by-default rows), so it would
    // otherwise ignore the per-position / per-state `--mat-list-list-item-container-shape` we set below
    // and leave nav/value-list rows square. Redeclare `border-radius` from the container-shape token at
    // higher specificity so those rows round too. (Selection-list `<mat-list-option>` rows have no
    // nav-list ancestor and already honor the container-shape token directly.)
    .dbx-list-view .mat-mdc-list-item {
      border-radius: var(--mat-list-list-item-container-shape);
    }

    // Connected-group corner shaping. The list rows are square by default (token = 0 above); here we
    // round only the outer corners of the group and any row in an interactive/selected state.
    //
    // Selection list (`<mat-selection-list>` > `<mat-list-option>` siblings). NOTE: the element's CSS
    // class is `.mat-mdc-selection-list` (there is no `.mat-selection-list` class), so match the host
    // by its element/tag name instead.
    mat-selection-list > .dbx-list-view-item:first-of-type {
      --mat-list-list-item-container-shape: var(--dbx-list-item-radius-resolved) var(--dbx-list-item-radius-resolved) 0 0;
    }

    mat-selection-list > .dbx-list-view-item:last-of-type {
      --mat-list-list-item-container-shape: 0 0 var(--dbx-list-item-radius-resolved) var(--dbx-list-item-radius-resolved);
      margin-bottom: 0;
    }

    mat-selection-list > .dbx-list-view-item:only-of-type {
      --mat-list-list-item-container-shape: var(--dbx-list-item-radius-resolved);
    }

    // Value/nav list (`dbx-list-view-content-group` > `dbx-anchor` rows). First/last is resolved per
    // group, so a grouped list reads as one connected block per group; a single-group list rounds the
    // whole list. Header/footer are `div`s, so `:first/last-of-type` of `dbx-anchor` is correct.
    .dbx-list-view-group-content > dbx-anchor:first-of-type .dbx-list-view-item {
      --mat-list-list-item-container-shape: var(--dbx-list-item-radius-resolved) var(--dbx-list-item-radius-resolved) 0 0;
    }

    .dbx-list-view-group-content > dbx-anchor:last-of-type .dbx-list-view-item {
      --mat-list-list-item-container-shape: 0 0 var(--dbx-list-item-radius-resolved) var(--dbx-list-item-radius-resolved);
    }

    .dbx-list-view-group-content > dbx-anchor:last-of-type .dbx-list-view-item.mat-mdc-list-item {
      margin-bottom: 0;
    }

    .dbx-list-view-group-content > dbx-anchor:only-of-type .dbx-list-view-item {
      --mat-list-list-item-container-shape: var(--dbx-list-item-radius-resolved);
    }

    // Any hovered / focused / selected / activated / active-route row rounds all four corners. These must
    // out-specify the per-position first/last/only rules above — and the value-list ones
    // (`.dbx-list-view-group-content > dbx-anchor:first-of-type .dbx-list-view-item`) carry an element +
    // pseudo-class, landing at (0,3,1). A bare `.dbx-list-view .mat-mdc-list-item` state selector is only
    // (0,3,0), so it would LOSE and leave the outer corner square — e.g. the active first row keeping a
    // square bottom. Qualifying each row with `.dbx-list-view-item` raises these to (0,4,0) so the
    // all-corners shape wins (every `.dbx-list-view` row — value-list `<a mat-list-item>` and selection
    // `<mat-list-option>` alike — carries that class). `.dbx-anchor-active` covers nav/value-list rows
    // whose active route is signaled by `dbx-anchor` — it never adds Material's `.mdc-list-item--activated`,
    // so without this the active (un-hovered) row would otherwise fall back to the square per-position shape.
    .dbx-list-view .dbx-list-view-item.mat-mdc-list-item:hover,
    .dbx-list-view .dbx-list-view-item.mat-mdc-list-item:focus,
    .dbx-list-view .dbx-anchor-active .dbx-list-view-item.mat-mdc-list-item,
    .dbx-list-view .dbx-list-view-item.mat-mdc-list-item.mdc-list-item--selected,
    .dbx-list-view .dbx-list-view-item.mat-mdc-list-item.mdc-list-item--activated,
    .dbx-list-view .dbx-list-view-item.mat-mdc-list-item[aria-selected='true'] {
      --mat-list-list-item-container-shape: var(--dbx-list-item-radius-resolved);
    }

    // Paint the selected / activated row with the primary tone, and set an on-tone `color` so the
    // injected row content stays legible (Material only recolors its own `.mdc-list-item__primary-text`
    // / `__start`).
    //
    // A multi-select `mat-list-option` conveys selection via `aria-selected` + its checkbox — it does
    // NOT get the `.mdc-list-item--selected` class (Material only adds that in single-select mode), and
    // it never paints `--mat-list-list-item-selected-container-color`. So match `[aria-selected='true']`
    // too and drive the tint through `--mat-list-list-item-container-color` (the row's own background
    // token), which paints every selected row regardless of the missing class. Nav rows use
    // `.mdc-list-item--activated`.
    .dbx-list-view .mat-mdc-list-item.mdc-list-item--selected,
    .dbx-list-view .mat-mdc-list-item.mdc-list-item--activated,
    .dbx-list-view .mat-mdc-list-item[aria-selected='true'] {
      --mat-list-list-item-container-color: var(--dbx-list-item-selected-color);
      color: var(--dbx-list-item-selected-on-color);
    }

    // Active-route row tone (a `dbx-anchor` row whose route is active) is painted in `_anchorlist.scss`,
    // which targets both `.dbx-anchor-list` and `.dbx-list-view` nav lists via the
    // `--dbx-anchor-list-item-active-color` token. That token defaults to `--dbx-list-item-active-color`
    // (defined above), so a value list's active route matches its selected tone out of the box; the
    // sidenav overrides the token for its accent treatment. Only the corner shape is handled here (above).
  }

  // dbx-anchor-list (nav) rows default to an M3 medium corner via their OWN
  // `--dbx-anchor-list-item-border-radius` token — separate from `.dbx-list` so the style-demo
  // `anchor-list-corner-*` levers control anchor lists independently. `.dbx-list-square-items`
  // zeroes this token too. The `.dbx-anchor-list` class lives on the inner `mat-nav-list`.
  .dbx-anchor-list {
    --mat-list-active-indicator-shape: var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px));
    --mat-list-list-item-container-shape: var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px));

    .mat-mdc-list-item {
      --mat-focus-indicator-border-radius: var(--mat-list-list-item-container-shape);
    }
  }

  // Sidenav anchor-list rows sit flush against the left drawer edge, so only the RIGHT corners round — the
  // radius is composed into a `0 r r 0` shorthand (top-left / top-right / bottom-right / bottom-left),
  // leaving the left corners square. The "how round" radius defaults to the regular anchor-list radius
  // (`--dbx-anchor-list-item-border-radius`) so the sidenav tracks the `anchor-list-corner-*` lever by default,
  // but `--dbx-sidenav-anchor-list-item-border-radius` overrides it for sidenav-specific tuning.
  //
  // Scoped to EVERY anchor list inside a sidenav drawer (`.dbx-sidenav .mat-drawer .dbx-anchor-list`), not
  // just the `[anchors]` list (`.dbx-sidenav-anchor-list`): a separate `<dbx-anchor-list>` dropped into a
  // `[top]` / `[bottom]` content slot must round the same way, otherwise it falls back to the generic
  // all-corners `.dbx-anchor-list` radius and reads as floating full-radius pills beside the flush main
  // rows. Higher specificity than `.dbx-anchor-list`, so it wins for any inner nav-list inside a sidenav.
  .dbx-sidenav .mat-drawer .dbx-anchor-list {
    --mat-list-active-indicator-shape: 0 var(--dbx-sidenav-anchor-list-item-border-radius, var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px))) var(--dbx-sidenav-anchor-list-item-border-radius, var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px))) 0;
    --mat-list-list-item-container-shape: 0 var(--dbx-sidenav-anchor-list-item-border-radius, var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px))) var(--dbx-sidenav-anchor-list-item-border-radius, var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px))) 0;
  }

  // MDC's two-line + leading-icon variant sizes the primary-text baseline-spacer `::before` to 32px, taller than
  // the 28px the two-line (no-leading-icon) rule uses, which over-tall the title box and pushes the title/hint
  // group off-center in dbx-anchor custom-anchor rows (reads as top-aligned). Pin the spacer back to 28px within
  // anchor lists so the rows center vertically (selection lists, which keep MDC's structure, are untouched).
  .dbx-anchor-list .mdc-list-item--with-leading-icon.mdc-list-item--with-two-lines .mdc-list-item__primary-text::before {
    height: 28px;
  }

  .dbx-list-empty-content {
    text-align: center;
    // Breathing room around the empty-state content so it doesn't sit flush against its container.
    // Override point (`--dbx-list-empty-content-padding`) defaults to the global `--dbx-padding-2` spacing token.
    padding: var(--dbx-list-empty-content-padding, var(--dbx-padding-2));
  }

  .dbx-list-content {
    // The list's own scroll container. Override point (`--dbx-list-content-max-height`) caps the scroll
    // area at a fixed height — set it on the list wrapper host (or any ancestor) when the list sizes to its
    // rows (e.g. with `.dbx-list-auto-height`) and should scroll past a limit instead of growing.
    max-height: var(--dbx-list-content-max-height, 100%);
    overflow: auto;
    box-sizing: border-box;

    &.dbx-list-padded {
      padding-bottom: 8px;
    }

    .mat-mdc-list-base {
      padding-top: 0;
    }

    &.dbx-list-content-hidden {
      display: none;
    }
  }

  .dbx-list-content-box {
    padding: 4px;
  }

  .dbx-list-view {
    // --mat-list-list-item-leading-icon-start-space: 16px;
    --mat-list-list-item-leading-icon-end-space: 8px;

    .mat-mdc-list-base .dbx-list-view-item.mat-mdc-list-item {
      height: 100%; // inherit height from embedded items

      .mdc-list-item__content {
        user-select: none;
      }

      .mdc-list-item__content > .mat-mdc-list-item-unscoped-content.mdc-list-item__primary-text {
        white-space: normal;

        line-height: unset;
        font-size: unset;
        letter-spacing: unset;
      }

      &.mdc-list-item--with-leading-icon,
      &.mat-mdc-list-item-with-avatar {
        min-height: 56px;

        .mat-mdc-list-item-content {
          min-height: 56px;
        }
      }
    }

    .mat-selection-list.mat-mdc-list-base .dbx-list-view-item.mat-mdc-list-item .mat-mdc-list-item-content .mat-mdc-list-text {
      padding: 0; // kill padding on item in .mat-mdc-list-text for selection view, to match 0 padding in non-selection view
    }
  }

  /// @dbx-utility list-view-no-meta-padding
  /// @intent strip the leading + trailing padding around `mdc-list-item--with-trailing-meta` rows so meta-only items hug their container
  /// @role spacing
  .dbx-list-view-no-meta-padding {
    .mdc-list-item--with-trailing-meta.mdc-list-item {
      padding-left: 4px;
      padding-right: 0;
    }

    .mdc-list-item--with-trailing-meta .mdc-list-item__end {
      margin-left: 0;
      margin-right: 0;
    }
  }

  .dbx-list-view-group {
    .dbx-list-view-group-header {
      .dbx-list-two-line-item .dbx-list-two-line-item-with-icon {
        padding: var(--dbx-padding-1) 0; // override the padding when there is an icon
      }
    }
  }

  /// @dbx-utility list-sticky-headers
  /// @intent pin `.dbx-list-view-group-header` rows to the top of the list while scrolling
  /// @role state
  .dbx-list-sticky-headers {
    .dbx-list-view-group .dbx-list-view-group-header,
    .dbx-list-view-group.dbx-list-view-group-header {
      z-index: 100;
      position: sticky;
      top: 0;
    }
  }

  .dbx-list-view-item {
    dbx-injection {
      width: 100%;
    }
  }

  /// @dbx-utility list-item-padded
  /// @intent baseline padded list-row spacing — guarantees `min-height` plus a tight 2px/6px padding pair
  /// @role spacing
  /// @see-also dbx-list-item-padded-thick, dbx-list-item-p0
  .dbx-list-item-padded {
    min-height: var(--dbx-list-item-padded-min-height, #{$list-item-padded-min-height});
    padding: var(--dbx-padding-1) var(--dbx-padding-2);
  }

  /// @dbx-utility list-item-padded-thick
  /// @intent thicker padded list-row spacing — same `min-height` as `.dbx-list-item-padded` with the workspace `theming.$padding-3` token
  /// @role spacing
  /// @see-also dbx-list-item-padded
  .dbx-list-item-padded-thick {
    min-height: var(--dbx-list-item-padded-min-height, #{$list-item-padded-min-height});
    padding: theming.$padding-3;
  }

  // No side padding if the parent list component has the dbx-list-no-item-padding class.
  .dbx-list-no-item-padding .dbx-list-item-padded {
    padding-left: 0;
    padding-right: 0;
  }

  // Card-style list — each row becomes a tinted, rounded surface that lives
  // on the actual `.mat-mdc-list-item`, not on a nested template `<div>`.
  // Apply this modifier as the host class on the list wrapper component so
  // the visible card boundary, the hover/focus state-layer, and the click
  // ripple all line up with one another — the inner item template is then
  // free to focus on content layout.
  //
  // Defaults flow through Material system tokens; both are overridable per
  // instance via CSS custom properties:
  //   --dbx-list-item-card-background     → `--mat-sys-surface-container`
  //   --dbx-list-item-card-border-radius  → `--mat-sys-corner-large`,
  //     falling back to `calc(--mat-chip-container-shape-radius * 2)` when
  //     the host theme doesn't emit the M3 shape tokens.
  // Spacing between cards is exposed as `--dbx-list-card-items-list-gap`
  // (default `8px`).
  /// @dbx-utility list-card-items-list
  /// @intent render each list row as a tinted, rounded card surface with a configurable inter-card gap
  /// @role layout
  .dbx-list-card-items-list {
    --dbx-list-card-items-list-gap: 8px;

    .dbx-list-view-item.mat-mdc-list-item {
      --mat-list-list-item-container-color: var(--dbx-list-item-card-background, var(--mat-sys-surface-container));
      --mat-list-list-item-container-shape: var(--dbx-list-item-card-border-radius, var(--mat-sys-corner-large, calc(var(--mat-chip-container-shape-radius) * 2)));
      // Override Angular Material's `.mat-mdc-nav-list .mat-mdc-list-item`
      // rule, which pins `border-radius` (and the focus-indicator radius) to
      // `var(--mat-list-active-indicator-shape, …)` and would otherwise win
      // out — leaving the card almost square. Redeclaring both here applies
      // our card shape directly without relying solely on the token.
      border-radius: var(--mat-list-list-item-container-shape);
      --mat-focus-indicator-border-radius: var(--mat-list-list-item-container-shape);
      margin-bottom: var(--dbx-list-card-items-list-gap);
    }

    // Keep every card a fully-rounded standalone surface — defeat the connected-list per-position /
    // per-state corner shaping defined on `.dbx-list` (those rules out-specify the card item rule
    // above). Re-scoping under `.dbx-list` adds the card-ancestor class so these always win.
    .dbx-list .dbx-list-view-group-content > dbx-anchor .dbx-list-view-item.mat-mdc-list-item,
    .dbx-list mat-selection-list > .dbx-list-view-item.mat-mdc-list-item,
    .dbx-list .dbx-list-view .mat-mdc-list-item:hover,
    .dbx-list .dbx-list-view .mat-mdc-list-item:focus,
    .dbx-list .dbx-list-view .mat-mdc-list-item.mdc-list-item--selected,
    .dbx-list .dbx-list-view .mat-mdc-list-item.mdc-list-item--activated {
      --mat-list-list-item-container-shape: var(--dbx-list-item-card-border-radius, var(--mat-sys-corner-large, calc(var(--mat-chip-container-shape-radius) * 2)));
    }

    // Strip the trailing card's bottom gap. The nav-list path wraps each
    // item in a `<dbx-anchor>`; the selection-list path renders
    // `<mat-list-option>` siblings directly under `<mat-selection-list>`.
    dbx-anchor:last-of-type .dbx-list-view-item.mat-mdc-list-item,
    .dbx-list-view-item.mat-mdc-list-option:last-of-type {
      margin-bottom: 0;
    }
  }

  // A separator (a list view's `separatorConfig`) supplies its own vertical spacing, so the row right
  // before it drops its bottom gap (the card-list gap, or the hairline row spacing). Otherwise the
  // separator sits closer to the row below it than to the row above it.
  .dbx-list .dbx-list-view-group-content > dbx-anchor:has(+ .dbx-list-view-item-separator) .dbx-list-view-item.mat-mdc-list-item,
  .dbx-list mat-selection-list > .dbx-list-view-item:has(+ .dbx-list-view-item-separator) {
    margin-bottom: 0;
  }

  // Opts a list out of the default medium-rounded rows back to square (0). Custom properties inherit, so
  // applying this on a `dbx-list` / `dbx-anchor-list` host (or any ancestor) squares selection and nav rows
  // alike by zeroing both the `.dbx-list` (`--dbx-list-item-border-radius`) and `.dbx-anchor-list`
  // (`--dbx-anchor-list-item-border-radius`) row tokens. The sidenav keeps its own token; the card-list
  // (`.dbx-list-card-items-list`) item rule is more specific and keeps its own shape.
  /// @dbx-utility list-square-items
  /// @intent opts a `.dbx-list` / `.dbx-anchor-list` out of the default medium-rounded rows back to square (0 radius) by zeroing their row radius tokens
  /// @role layout
  /// @see-also dbx-list-card-items-list
  .dbx-list-square-items {
    --dbx-list-item-border-radius: 0;
    --dbx-anchor-list-item-border-radius: 0;
  }

  // When the tile is the leading icon in a two-line list item, override the
  // default `.item-icon` flat spacing with tile-appropriate margins. The
  // base `.dbx-icon-tile` rule lives in `_text.scss` next to its component.
  .dbx-list-two-line-item .item-icon.dbx-icon-tile {
    padding: var(--dbx-icon-tile-padding, 8px);
    margin: 0 var(--dbx-padding-3) 0 0;
  }

  /// @dbx-utility list-two-line-item
  /// @intent two-line list-row layout — flex row with a left column (title + details) and an optional right slot, paired with nested `.item-icon` / `.item-left` / `.item-right` / `.item-title` / `.item-details` / `.item-details-footnote` helpers
  /// @role layout
  /// @see-also dbx-list-item-padded
  .dbx-list-two-line-item {
    // item broken into a left and right, and up to two rows on the left with 1 row on the right.
    display: flex;
    flex-direction: row;
    align-items: center;

    .item-icon {
      padding: 0 16px;
      margin-right: 4px;
    }

    .item-left {
      display: flex;
      flex-direction: column;
      flex: 1 1 auto;
      min-width: 0;
    }

    .item-right {
      display: flex;
      align-items: center;
      margin-left: 16px;
    }

    .item-title {
      font-size: 0.8em;
      font-weight: bold;
      opacity: 0.8;
    }

    .item-details {
      font-size: 0.8em;
    }

    .item-details-footnote {
      padding: 3px 0;
      font-size: 0.75em;
      opacity: 0.8;
    }
  }

  // Detail list-row layout — a bold title followed by any number of secondary lines, framed by a
  // leading slot (icon tile, or a full-height `.item-leading-block`) and a trailing slot (button,
  // text action, …). The row supplies its own padding, so pair it with `dbx-list-item-p0` on the
  // value-list view. A view's built-in meta (e.g. the `DbxListViewMetaIconComponent` chevron) still
  // renders after the trailing slot.
  //
  // Override points (all inherit, so set them on the row, the list wrapper host, or any ancestor):
  //   --dbx-list-detail-item-padding            → row padding (`--dbx-padding-3`)
  //   --dbx-list-detail-item-gap                → gap between leading / content / trailing (`--dbx-padding-3`)
  //   --dbx-list-detail-item-line-gap           → gap between the title and each line (2px)
  //   --dbx-list-detail-item-line-icon-size     → leading `<mat-icon>` size inside `.item-line` (18px)
  //   --dbx-list-detail-item-leading-block-width → `.item-leading-block` minimum width (112px)
  //   --dbx-list-detail-item-divider-color      → `.item-trailing-divided` hairline (`--mat-sys-outline-variant`)
  /// @dbx-utility list-detail-item
  /// @intent detail list-row layout — flex row of a leading slot, a content column (bold `.item-title` + `.item-line` rows with optional leading icons) and a trailing slot, paired with nested `.item-leading` / `.item-leading-block` / `.item-content` / `.item-title` / `.item-line` / `.item-trailing` / `.item-trailing-divided` helpers; the row pads itself, so pair with `dbx-list-item-p0` on the view
  /// @role layout
  /// @see-also dbx-list-two-line-item, dbx-list-item-p0, dbx-list-detail-item-highlight
  .dbx-list-detail-item {
    --dbx-list-detail-item-padding-resolved: var(--dbx-list-detail-item-padding, var(--dbx-padding-3));

    display: flex;
    flex-direction: row;
    align-items: stretch;
    gap: var(--dbx-list-detail-item-gap, var(--dbx-padding-3));
    min-width: 0;
    padding: var(--dbx-list-detail-item-padding-resolved);
    box-sizing: border-box;

    .item-leading {
      flex: none;
      align-self: center;
    }

    .item-content {
      display: flex;
      flex-direction: column;
      justify-content: center;
      gap: var(--dbx-list-detail-item-line-gap, 2px);
      flex: 1 1 auto;
      min-width: 0;
    }

    .item-title {
      font: var(--mat-sys-title-medium);
      font-weight: 600;
      color: var(--mat-sys-on-surface);
    }

    .item-line {
      display: flex;
      align-items: center;
      gap: var(--dbx-padding-1);
      font: var(--mat-sys-body-medium);
      color: var(--mat-sys-on-surface-variant);

      > .mat-icon {
        flex: none;
        width: var(--dbx-list-detail-item-line-icon-size, 18px);
        height: var(--dbx-list-detail-item-line-icon-size, 18px);
        font-size: var(--dbx-list-detail-item-line-icon-size, 18px);
      }
    }

    .item-trailing {
      display: flex;
      flex: none;
      align-items: center;
    }
  }

  /// @dbx-utility list-detail-item-leading-block
  /// @intent full-height leading column for a `.dbx-list-detail-item` (e.g. a weekday / date / status block) — bleeds out to the row's top, bottom and start edges so a `[dbxColor]` + `.dbx-color-bg` wash fills the row edge; never shrinks below `--dbx-list-detail-item-leading-block-width` (112px), so every row's block stays the same width and only grows when its own content is wider
  /// @role layout
  /// @parent list-detail-item
  /// @see-also dbx-list-detail-item, dbx-color-bg
  .dbx-list-detail-item .item-leading-block {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    align-self: stretch;
    gap: var(--dbx-padding-1);
    // Don't let the flex row shrink the block toward its content width on narrow views, which gives each
    // row a different width; it only grows past the minimum when its own content is wider.
    flex: none;
    min-width: var(--dbx-list-detail-item-leading-block-width, 112px);
    margin: calc(-1 * var(--dbx-list-detail-item-padding-resolved)) 0 calc(-1 * var(--dbx-list-detail-item-padding-resolved)) calc(-1 * var(--dbx-list-detail-item-padding-resolved));
    padding: var(--dbx-list-detail-item-padding-resolved);
    box-sizing: border-box;
  }

  /// @dbx-utility list-detail-item-trailing-divided
  /// @intent trailing slot of a `.dbx-list-detail-item` set off from the content by a hairline start border — for a trailing button column; recolor via `--dbx-list-detail-item-divider-color`
  /// @role layout
  /// @parent list-detail-item
  /// @see-also dbx-list-detail-item
  .dbx-list-detail-item .item-trailing-divided {
    align-self: stretch;
    padding-left: var(--dbx-list-detail-item-gap, var(--dbx-padding-3));
    border-left: 1px solid var(--dbx-list-detail-item-divider-color, var(--mat-sys-outline-variant));
  }

  // A "…" marker between two runs of `.dbx-list-detail-item` rows — e.g. before a date that doesn't
  // follow the previous row. Render it from a list view's `separatorConfig` (the list injects the
  // separator component between the two rows, outside the list rows), so it never picks up row hover /
  // ripple / card styling. Its `.item-leading` column shares `--dbx-list-detail-item-leading-block-width`,
  // so the marker icon lines up under an `.item-leading-block` column. The space above and below it is
  // `--dbx-list-detail-item-gap-marker-padding` (`--dbx-padding-3`); the row before a separator drops its
  // own bottom gap, so the marker stays centered between the two rows.
  /// @dbx-utility list-detail-item-gap
  /// @intent non-interactive "…" gap marker between runs of `.dbx-list-detail-item` rows (e.g. non-consecutive dates) — a compact muted row whose `.item-leading` column lines up with `.item-leading-block`; render it as the separator component of a list view's `separatorConfig` so it sits between rows without row styling
  /// @role layout
  /// @parent list-detail-item
  /// @see-also dbx-list-detail-item, dbx-list-detail-item-leading-block
  .dbx-list-detail-item-gap {
    display: flex;
    align-items: center;
    gap: var(--dbx-list-detail-item-gap, var(--dbx-padding-3));
    // Equal space above and below so the marker sits centered between the two rows.
    padding: var(--dbx-list-detail-item-gap-marker-padding, var(--dbx-padding-3)) 0;
    font: var(--mat-sys-label-medium);
    color: var(--mat-sys-on-surface-variant);

    .item-leading {
      display: flex;
      flex: none;
      justify-content: center;
      width: var(--dbx-list-detail-item-leading-block-width, 112px);
    }
  }

  /// @dbx-utility list-detail-item-highlight
  /// @intent flag a `.dbx-list-detail-item` row as urgent — a rounded tonal wash of `--dbx-list-detail-item-highlight-color` (default `--dbx-notice-color`) at `--dbx-list-detail-item-highlight-tone` (default 14%); inside a `.dbx-list` the hosting list row paints the wash instead, so it also spans the view's built-in meta slot (e.g. the chevron)
  /// @role state
  /// @parent list-detail-item
  /// @see-also dbx-list-detail-item
  .dbx-list-detail-item-highlight {
    background: color-mix(in srgb, var(--dbx-list-detail-item-highlight-color, var(--dbx-notice-color)) var(--dbx-list-detail-item-highlight-tone, 14%), transparent);
    border-radius: var(--mat-sys-corner-medium, 12px);
  }

  // Inside a list row the wash has to cover the whole row — including the view's meta slot, which
  // renders outside the item template — so the hosting `.mat-mdc-list-item` paints it via `:has()` and
  // the item itself stays clear. Qualified with `.dbx-list .dbx-list-view` so it ties the hover/focus
  // corner rule and wins by source order.
  .dbx-list-view-item .dbx-list-detail-item-highlight {
    background: none;
  }

  .dbx-list .dbx-list-view .dbx-list-view-item.mat-mdc-list-item:has(.dbx-list-detail-item-highlight) {
    --mat-list-list-item-container-color: color-mix(in srgb, var(--dbx-list-detail-item-highlight-color, var(--dbx-notice-color)) var(--dbx-list-detail-item-highlight-tone, 14%), transparent);
    --mat-list-list-item-container-shape: var(--dbx-list-item-radius-resolved);
  }

  /// @dbx-utility list-no-hover-effects
  /// @intent disable hover cursor + state-layer opacity on list items inside a `.dbx-list`
  /// @role state
  .dbx-list-no-hover-effects .dbx-list > .dbx-list-content .dbx-list-view .mat-mdc-list-item {
    cursor: unset;

    &:hover {
      --mat-list-list-item-hover-state-layer-opacity: 0;
    }
  }

  /// @dbx-utility list-no-item-padding
  /// @intent zero the padding on every list row in a `.dbx-list` — container-scope complement to `dbx-list-item-p0`
  /// @role spacing
  /// @see-also dbx-list-item-p0
  .dbx-list-no-item-padding .dbx-list > .dbx-list-content .dbx-list-view .mat-mdc-list-item {
    padding: 0;
  }

  // `.dbx-list` defaults to `height: 100%` so it fills a fixed-height scroll
  // container. When a list instead flows inline with other content (e.g. card
  // content rendered below it), that percentage resolves against the stretched
  // ancestor and pushes the trailing content out of the card. This modifier
  // lets the list size to its rows.
  /// @dbx-utility list-auto-height
  /// @intent size a `.dbx-list` to its rows instead of filling its container — apply on the list wrapper host when content flows below the list (the default `height: 100%` would push that content out of a stretched card)
  /// @role layout
  /// @see-also list-no-hover-effects, list-no-item-padding
  .dbx-list-auto-height .dbx-list {
    height: auto;
  }

  // Zeros all padding on the underlying Material list item. Per-item utility
  // (apply as host class on the value-list view) for templates that supply
  // their own padding/leading element — e.g. a `.dbx-icon-tile` in a
  // `.dbx-list-two-line-item-with-icon` — where Material's default item
  // padding would otherwise double up. Complements the container-scope
  // `.dbx-list-no-item-padding`, which zeros the same `.mat-mdc-list-item`
  // padding for every row in the list.
  /// @dbx-utility list-item-p0
  /// @intent zero all padding on the host `.mat-mdc-list-item` — per-item complement to `.dbx-list-no-item-padding` for templates that supply their own padding/leading element
  /// @role spacing
  /// @see-also dbx-list-no-item-padding
  .dbx-list-item-p0 .mat-mdc-list-item.mdc-list-item {
    padding: 0;
  }

  .dbx-list-content .dbx-list-view .mat-mdc-list-base .mat-mdc-list-item .mat-divider {
    position: unset; // do not touch the divider in dbx-list
  }

  // Accordion list view renders as a card with a rounded TOP. The rounded frame lives on the scroll
  // VIEWPORT (`.dbx-list-content`) so it clips the scrolling content — including panels that scroll BEHIND a
  // sticky group header — which stops them bleeding through the rounded corner. (A rounded ancestor can't
  // clip a composited `position: sticky` element in Chrome, so each group header additionally rounds its OWN
  // top corners below.) Only the top corners are rounded — the bottom stays square so the last panel's
  // elevation shadow isn't clipped by a rounded bottom edge. Scoped with `:has()` so only accordion lists
  // get framed.
  .dbx-list-content:has(.dbx-list-accordion-view) {
    border-top-left-radius: var(--dbx-list-accordion-view-border-radius, var(--mat-sys-corner-medium, 12px));
    border-top-right-radius: var(--dbx-list-accordion-view-border-radius, var(--mat-sys-corner-medium, 12px));
  }

  .dbx-list-accordion-view {
    // Breathing-room margin (`--dbx-list-accordion-view-margin`, default `--dbx-padding-1` / 2px) so the
    // card sits inset from its container and its walls stay visible — flush against the container the card's
    // edges read as cut off. `padding-bottom` leaves room below the last panel so its elevation shadow shows
    // instead of being clipped at the scroll edge.
    display: block;
    margin: var(--dbx-list-accordion-view-margin, var(--dbx-padding-1));
    padding-bottom: var(--dbx-list-accordion-view-bottom-space, var(--dbx-padding-2));
    --dbx-list-accordion-view-radius-resolved: var(--dbx-list-accordion-view-border-radius, var(--mat-sys-corner-medium, 12px));
    --mat-expansion-container-shape: 0px;

    // Round the top corners of the first entry (the very top of the card) AND of every group header. Group
    // headers are sticky — when one pins at the rounded top corner, the scroll frame's clip would otherwise
    // shave that header's square corner (and its border) flat, so each header rounds its OWN top corners to
    // follow the curve. `overflow: hidden` clips the header's content/border to those corners.
    mat-accordion > :first-child,
    .dbx-list-view-group-header {
      border-top-left-radius: var(--dbx-list-accordion-view-radius-resolved);
      border-top-right-radius: var(--dbx-list-accordion-view-radius-resolved);
      overflow: hidden;
    }

    // Box every group header with the same hairline the two-column view uses (`1px solid
    // var(--dbx-divider-color)`) rather than the heavier/darker `--mat-divider-*`; the shorthand overrides
    // the bottom divider on the base `.dbx-list-view-group-header` rule so all four sides match. The `-1px`
    // margin pulls the header out so its border overlaps the adjacent panel edges (no doubled hairline / gap).
    .dbx-list-view-group-header {
      margin: -1px;
      border: 1px solid var(--dbx-divider-color);
    }
  }

  .dbx-list-view-group-header {
    background: var(--dbx-list-view-group-header-background, var(--mat-sidenav-content-background-color));

    --mat-divider-width: 2px;
    border-bottom-style: solid;
    border-bottom-color: var(--mat-divider-color);
    border-bottom-width: var(--mat-divider-width);
  }
}

@mixin theme($theme-config) {
}
