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

// MARK: Variables
$icon-spacing: var(--dbx-padding-2);
$chip-spacing: var(--dbx-padding-1);
$hint-opacity: 0.8;
$faint-opacity: 0.54;
$note-opacity: 0.7;
$mat-hint-opacity: 0.54; // Opacity to mirror mat-hint
$dbx-label-padded-padding: var(--dbx-padding-2);
$dbx-detail-block-bottom-padding: var(--dbx-padding-3);
$dbx-detail-block-content-offset: 30px;
$click-to-copy-icon-size: 18px;
$dbx-click-to-copy-field-icon-size: 18px;
$dbx-click-to-copy-field-monospace-font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
$dbx-click-to-copy-field-monospace-font-size: 13px;
// tints over whatever surface the field sits on, so it reads the same in a dialog, a page, light, and dark
$dbx-click-to-copy-field-background: color-mix(in srgb, var(--mat-sys-on-surface) 4%, transparent);
$dbx-detail-block-big-header-icon-size: 18px;
$dbx-detail-block-tile-size: 28px;
$dbx-detail-block-tile-icon-size: 16px;
$dbx-detail-block-tile-shape: 50%;
$dbx-detail-block-tile-font-size: 15px;
$dbx-detail-block-tile-line-height: 20px;
$dbx-detail-block-tile-label-font-size: 11px;
$dbx-detail-block-tile-label-line-height: 15px;
$dbx-detail-block-tile-label-font-weight: 600;
$dbx-detail-block-tile-label-letter-spacing: 0.1em;
$dbx-detail-block-tile-label-gap: 2px;
$dbx-detail-block-tile-value-font-weight: 700;
$dbx-detail-block-tile-hint-font-size: 13px;
$dbx-detail-block-tile-hint-line-height: 18px;
$dbx-icon-tile-default-icon-size: 24px;
$dbx-step-block-badge-size: 32px;
$dbx-step-block-gap: 16px;
$dbx-step-block-padding: 16px;
$dbx-step-block-badge-font-size: 14px;
$dbx-step-block-badge-icon-size: 18px;
$dbx-step-block-header-font-weight: 500;
$dbx-step-block-badge-font-weight: 600;

// MARK: Internal
// The `.dbx-icon-tile` body, shared with surfaces that make an element an icon tile without the class (the
// `.dbx-detail-block-tile` header icon), so they compose it by setting the `--dbx-icon-tile-*` variables.
@mixin icon-tile-body() {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--dbx-icon-tile-border-radius, var(--mat-sys-corner-medium, 12px));
  padding: var(--dbx-icon-tile-padding, 8px);
  width: var(--dbx-icon-tile-width);
  height: var(--dbx-icon-tile-height);
  min-width: var(--dbx-icon-tile-min-width);
  font-size: var(--dbx-icon-tile-font-size);
  font-weight: var(--dbx-icon-tile-font-weight);

  .mat-icon {
    width: var(--dbx-icon-tile-icon-size, $dbx-icon-tile-default-icon-size);
    height: var(--dbx-icon-tile-icon-size, $dbx-icon-tile-default-icon-size);
    font-size: var(--dbx-icon-tile-icon-size, $dbx-icon-tile-default-icon-size);
  }
}

// MARK: Mixin
@mixin core() {
  /// @dbx-utility small
  /// @intent reduced font-size text — 0.8em of inherited size
  /// @role text
  .dbx-small,
  .dbx-clear-hint {
    font-size: 0.8em;
  }

  /// @dbx-utility label-padded
  /// @intent padded label — adds 6px bottom padding under a label header
  /// @role spacing
  /// @see-also label-block
  .dbx-label-padded {
    padding-bottom: $dbx-label-padded-padding;
  }

  /// @dbx-utility text-center
  /// @intent horizontally centered text
  /// @role text
  .text-center,
  .dbx-text-center {
    text-align: center;
  }

  /// @dbx-utility u
  /// @intent underlined text decoration
  /// @role text
  .dbx-u {
    text-decoration: underline;
  }

  .text-left {
    text-align: left;
  }

  .dbx-json,
  .prettyjson {
    white-space: pre-wrap !important;
  }

  .dbx-linkify {
    white-space: pre-wrap;
  }

  /// @dbx-utility iframe
  /// @intent fill-parent iframe with no border — `height: 100%; width: 100%; border: none`
  /// @role layout
  .dbx-iframe {
    height: 100%;
    width: 100%;
    border: none;
  }

  /// @dbx-utility label-block
  /// @intent block-level label wrapper — `<dbx-label-block>` body that emits a header line with 3px vertical padding
  /// @role layout
  /// @component DbxLabelBlockComponent
  /// @scope component-class
  /// @see-also detail-block, label-padded
  .dbx-label-block {
    display: block;
    padding: 3px 0;
  }

  .dbx-detail-block-header {
    display: flex;
    align-items: center;

    .mat-icon {
      padding-right: var(--dbx-padding-2);
      flex-shrink: 0; // do not allow shrinking
    }

    .dbx-anchor-a {
      text-decoration: underline;
    }

    padding-bottom: $dbx-detail-block-bottom-padding;
  }

  .dbx-detail-block-header-no-icon {
    padding-left: var(--dbx-detail-block-content-offset, #{$dbx-detail-block-content-offset});
  }

  .dbx-detail-line {
    display: block;
    padding-top: 3px;
  }

  .dbx-detail-block-header-label {
    padding-right: var(--dbx-padding-1);
  }

  .dbx-detail-block-header.dbx-detail-block-header-align {
    .dbx-detail-block-header-label {
      white-space: pre;
    }
  }

  /// @dbx-utility detail-block
  /// @intent labeled detail surface — `<dbx-detail-block>` body that places an icon + header above offset content (`.dbx-detail-block-header` + `.dbx-detail-block-content`). Compose with `.dbx-detail-block-big-header` for a larger title and `.dbx-detail-block-header-align` to wrap the header content (e.g. when an aligned `[header]` slot is supplied).
  /// @role layout
  /// @component DbxDetailBlockComponent
  /// @scope component-class
  /// @see-also label-block, step-block
  .dbx-detail-block {
    display: block;

    .dbx-detail-block-header {
      padding-bottom: var(--dbx-padding-1);

      .dbx-detail-block-header-label {
        font-weight: 400;
      }
    }

    .dbx-detail-block-content {
      opacity: 0.8;
      font-size: 0.9em;
      padding-left: var(--dbx-detail-block-content-offset, #{$dbx-detail-block-content-offset});
    }

    padding-bottom: $dbx-detail-block-bottom-padding;
  }

  .dbx-detail-block.dbx-detail-block-big-header {
    .dbx-detail-block-header {
      font-size: 1.18em;

      .mat-icon {
        padding-left: 3px;
        height: $dbx-detail-block-big-header-icon-size;
        width: $dbx-detail-block-big-header-icon-size;
        font-size: $dbx-detail-block-big-header-icon-size;
      }
    }
  }

  // Tile styling for `<dbx-detail-block>`. The component only provides the structure (header row + content); this
  // class restyles that same structure: the header's icon moves into a round tile beside the block, the header label
  // becomes a small uppercase label, and the `[header]` slot content wraps onto its own line below the label so it
  // reads as the block's value. Child combinators keep a nested (untiled) detail block inside the content untouched.
  /// @dbx-utility detail-block-tile
  /// @intent tile-styled detail block — add to a `<dbx-detail-block>` to draw its icon in a round tile beside the content, show the header as a small uppercase label, and show the `[header]` slot and body content as full-strength text below it. Pair with `.dbx-detail-block-tile-value` / `.dbx-detail-block-tile-hint` for the bold value and muted secondary lines, and with `[dbxColor]` (plus `[dbxColorTone]` for a tonal tile) to color the tile and label. Customize via the `--dbx-detail-block-tile-*` CSS variables.
  /// @role layout
  /// @parent detail-block
  /// @see-also detail-block-tile-value, detail-block-tile-hint, icon-tile
  .dbx-detail-block-tile {
    position: relative;
    min-height: var(--dbx-detail-block-tile-size, #{$dbx-detail-block-tile-size});
    padding-left: calc(var(--dbx-detail-block-tile-size, #{$dbx-detail-block-tile-size}) + var(--dbx-detail-block-tile-gap, var(--dbx-padding-3)));
    padding-bottom: var(--dbx-detail-block-tile-padding-bottom, var(--dbx-padding-4));
    font-size: $dbx-detail-block-tile-font-size;
    line-height: $dbx-detail-block-tile-line-height;
    color: var(--dbx-detail-block-tile-text-color, var(--mat-sys-on-surface));

    > .dbx-detail-block-header {
      flex-wrap: wrap;
      padding: 0; // the tile column replaces both the bottom padding and the no-icon offset

      // the header icon is the tile itself: it composes the `.dbx-icon-tile` body through the `--dbx-icon-tile-*`
      // variables, the same way `.dbx-step-block-badge` does, and pins it to the top of the tile column
      > .mat-icon {
        --dbx-icon-tile-padding: 0;
        --dbx-icon-tile-border-radius: var(--dbx-detail-block-tile-shape, #{$dbx-detail-block-tile-shape});
        --dbx-icon-tile-width: var(--dbx-detail-block-tile-size, #{$dbx-detail-block-tile-size});
        --dbx-icon-tile-height: var(--dbx-detail-block-tile-size, #{$dbx-detail-block-tile-size});
        --dbx-icon-tile-min-width: var(--dbx-detail-block-tile-size, #{$dbx-detail-block-tile-size});
        --dbx-icon-tile-font-size: var(--dbx-detail-block-tile-icon-size, #{$dbx-detail-block-tile-icon-size});
        position: absolute;
        top: 0;
        left: 0;
        background: var(--dbx-detail-block-tile-background, var(--mat-sys-surface-container-high));
        color: var(--dbx-detail-block-tile-icon-color, var(--mat-sys-on-surface-variant));
        @include icon-tile-body();
      }

      > .dbx-detail-block-header-label {
        flex-basis: 100%;
        padding: 0 0 $dbx-detail-block-tile-label-gap;
        font-size: $dbx-detail-block-tile-label-font-size;
        line-height: $dbx-detail-block-tile-label-line-height;
        font-weight: $dbx-detail-block-tile-label-font-weight;
        letter-spacing: $dbx-detail-block-tile-label-letter-spacing;
        text-transform: uppercase;
        color: var(--dbx-detail-block-tile-label-color, var(--mat-sys-outline));
      }
    }

    // without a label, the `[header]` slot content is the first line, so center it on the tile
    > .dbx-detail-block-header:not(:has(> .dbx-detail-block-header-label)) {
      min-height: var(--dbx-detail-block-tile-size, #{$dbx-detail-block-tile-size});
    }

    // an aligned header keeps its `[header]` content on the label's line, pushed to the right
    > .dbx-detail-block-header.dbx-detail-block-header-align {
      flex-wrap: nowrap;

      > .dbx-detail-block-header-label {
        flex-basis: auto;
        padding-bottom: 0;
      }
    }

    > .dbx-detail-block-content {
      padding-left: 0;
      opacity: 1;
      font-size: inherit;
    }
  }

  // Colored tile. `[dbxColor]` only provides the color tokens (and the `.dbx-color` marker); the tile paints from them
  // here, the same model (and `:not(.dbx-default)` guard) as `.dbx-icon-tile.dbx-color`. The block's text keeps
  // `--dbx-detail-block-tile-text-color` so only the tile and the label take the color.
  .dbx-detail-block-tile.dbx-color:not(.dbx-default) {
    --dbx-detail-block-tile-label-color: var(#{theming.$dbx-bg-color-var});
    color: var(--dbx-detail-block-tile-text-color, var(--mat-sys-on-surface)); // outranks the global `.dbx-color-tonal` text color

    > .dbx-detail-block-header > .mat-icon {
      @include style.dbx-color-surface();
    }

    &.dbx-color-tonal > .dbx-detail-block-header > .mat-icon {
      color: var(#{theming.$dbx-bg-color-var});
    }
  }

  /// @dbx-utility detail-block-tile-value
  /// @intent bold value line inside a `.dbx-detail-block-tile` — the headline fact under the label (a date range, a time span, a name)
  /// @role text
  /// @parent detail-block-tile
  /// @see-also detail-block-tile-hint
  .dbx-detail-block-tile-value {
    display: block;
    font-weight: $dbx-detail-block-tile-value-font-weight;
  }

  /// @dbx-utility detail-block-tile-hint
  /// @intent muted secondary line inside a `.dbx-detail-block-tile` — smaller supporting text under the value (an address, a day count, a timezone)
  /// @role text
  /// @parent detail-block-tile
  /// @see-also detail-block-tile-value
  .dbx-detail-block-tile-hint {
    display: block;
    font-size: $dbx-detail-block-tile-hint-font-size;
    line-height: $dbx-detail-block-tile-hint-line-height;
    color: var(--dbx-detail-block-tile-hint-color, var(--mat-sys-on-surface-variant));
  }

  /// @dbx-utility step-block
  /// @intent step row — `<dbx-step-block>` body that lays out a numbered/iconic badge alongside content with a configurable `--dbx-step-block-gap` and `--dbx-step-block-padding`
  /// @role layout
  /// @component DbxStepBlockComponent
  /// @scope component-class
  /// @see-also step-block-badge, detail-block
  .dbx-step-block {
    display: flex;
    flex-direction: row;
    gap: var(--dbx-step-block-gap, #{$dbx-step-block-gap});
    align-items: flex-start;
    padding: var(--dbx-step-block-padding, #{$dbx-step-block-padding}) 0;
  }

  .dbx-step-block.dbx-step-block-center {
    align-items: center;
  }

  // Reusable rounded, padded icon container. Composable with any leading-icon
  // slot and works with `[dbxColor]` for tinted backgrounds. Decoupled from
  // the list layout — usable wherever a leading icon tile is wanted.
  // Also exposed via the `<dbx-icon-tile>` component (DbxIconTileComponent)
  // and the `[dbxIconTile]` directive (DbxIconTileDirective). All sizing,
  // padding, radius, font, and inner icon size are exposed as CSS variables
  // so consumer surfaces (e.g. `.dbx-step-block-badge`) can compose by
  // setting variables instead of rewriting rules. Host-level vars (width /
  // height / min-width / font-size / font-weight) have no fallback so an
  // unset variable produces an invalid declaration the browser ignores —
  // the tile then falls back to natural (auto / inherited) sizing. The
  // inner `.mat-icon` falls back to Material's own 24px default so
  // overriding our selector doesn't shrink the glyph.
  /// @dbx-utility icon-tile
  /// @intent rounded, padded icon container — the visible body of `<dbx-icon-tile>` / `[dbxIconTile]`. Customize via the `--dbx-icon-tile-*` CSS variables.
  /// @role layout
  /// @component DbxIconTileComponent
  /// @scope component-class
  .dbx-icon-tile {
    @include icon-tile-body();
  }

  // Colored tile surface. `[dbxColor]` only provides the color tokens (and the
  // `.dbx-color` marker); the tile itself paints from them here, scoped on the
  // marker so a tile inside a `[dbxColor]` page section doesn't repaint from
  // inherited tokens. Mirrors the `mat-card.dbx-color` model.
  // `:not(.dbx-default)` guard: `[dbxColor]` always adds the `.dbx-color` marker,
  // and a nullish color resolves to the `dbx-default` token class (which sets no
  // `--dbx-bg-color-current`), so the guard keeps an uncolored tile from painting.
  .dbx-icon-tile.dbx-color:not(.dbx-default) {
    @include style.dbx-color-surface();

    &.dbx-color-tonal {
      color: var(#{theming.$dbx-bg-color-var});
    }
  }

  // Round modifier — turns the rounded-square tile into a circle. Pair
  // with explicit width/height (or square content) to keep it true round.
  /// @dbx-utility icon-tile-round
  /// @intent round modifier — turns `.dbx-icon-tile` into a circle (pair with explicit width/height to keep it true round)
  /// @role layout
  /// @parent icon-tile
  /// @see-also icon-tile
  .dbx-icon-tile-round {
    border-radius: 50%;
  }

  // Composes `.dbx-icon-tile` — the badge is a fixed-size circle (or
  // square via `--dbx-step-block-badge-shape`) sized through the tile's
  // CSS variables. Padding is reset to 0 because the badge sizes by
  // explicit width/height, not by content + padding.
  /// @dbx-utility step-block-badge
  /// @intent fixed-size badge inside `<dbx-step-block>` — composes `.dbx-icon-tile` and exposes the `--dbx-step-block-badge-*` CSS variables for shape, size, font-size, font-weight, and inner icon size.
  /// @role layout
  /// @component DbxStepBlockComponent
  /// @scope component-class
  /// @see-also icon-tile
  .dbx-step-block-badge {
    --dbx-icon-tile-padding: 0;
    --dbx-icon-tile-border-radius: var(--dbx-step-block-badge-shape, 50%);
    --dbx-icon-tile-width: var(--dbx-step-block-badge-size, #{$dbx-step-block-badge-size});
    --dbx-icon-tile-height: var(--dbx-step-block-badge-size, #{$dbx-step-block-badge-size});
    --dbx-icon-tile-min-width: var(--dbx-step-block-badge-size, #{$dbx-step-block-badge-size});
    --dbx-icon-tile-font-size: var(--dbx-step-block-badge-font-size, var(--mat-sys-label-large-size, #{$dbx-step-block-badge-font-size}));
    --dbx-icon-tile-font-weight: var(--dbx-step-block-badge-font-weight, #{$dbx-step-block-badge-font-weight});
    --dbx-icon-tile-icon-size: var(--dbx-step-block-badge-icon-size, #{$dbx-step-block-badge-icon-size});
  }

  .dbx-step-block-header {
    display: flex;
    align-items: center;
    font-weight: var(--dbx-step-block-header-font-weight, #{$dbx-step-block-header-font-weight});
  }

  .dbx-step-block-header-label {
    padding-right: 4px;
  }

  .dbx-step-block-hint {
    display: block;
    font-size: var(--dbx-step-block-hint-font-size, var(--mat-sys-body-small-size));
    opacity: var(--dbx-step-block-hint-opacity, #{$hint-opacity});
  }

  /// @dbx-utility text-no-overflow
  /// @intent opt out of single-line truncation — wrap content and show overflow
  /// @role text
  /// @see-also dbx-text-truncate
  .dbx-text-no-overflow {
    white-space: pre-wrap !important;
    overflow: visible !important;
    text-overflow: unset !important;
  }

  /// @dbx-utility text-truncate
  /// @intent single-line truncation with ellipsis on any block-level element
  /// @role text
  /// @see-also dbx-flex-fill-0
  /// @anti-use Inside a flex item, pair with .dbx-flex-fill-0 — a default flex item won't shrink below its content's intrinsic width.
  // Single-line truncation with ellipsis. Composable on any block-level
  // element. The flex-child variant requires `min-width: 0` on the
  // truncating element (the default `min-width: auto` prevents a flex item
  // from shrinking below its content width).
  .dbx-text-truncate {
    @include theming.limit-text();
  }

  /// @dbx-utility icon-spacer
  /// @intent right-margin spacer beside an icon — 6px right margin to separate a leading `mat-icon` from text
  /// @role spacing
  /// @see-also chip-spacer, button-spacer
  .dbx-icon-spacer {
    margin-right: $icon-spacing;
  }

  /// @dbx-utility form-description
  /// @intent helper-text styling for a form field description — 75% font size with the standard `mat-form-field` top spacing
  /// @role text
  /// @see-also dbx-hint, dbx-label
  .dbx-form-description {
    font-size: 75%;
    margin-top: 0.6666666667em;
  }

  /// @dbx-utility chip
  /// @intent chip label — `<dbx-chip>` body that lays out an inline-flex chip (label-large text, 7px/12px padding, 32px min-height) with an M3 corner-small radius; override the radius via `--dbx-chip-container-shape` (e.g. set it to `var(--mat-sys-corner-full)` to restore a pill). Compose with `.dbx-chip-small`, `.dbx-chip-block`, or `.dbx-chip-small-text` for size variants
  /// @role layout
  /// @component DbxChipDirective
  /// @scope component-class
  /// @see-also chip-spacer, chip-margin
  .dbx-chip {
    font-size: var(--mat-sys-label-large-size);
    font-weight: var(--mat-sys-label-large-weight);
    position: relative;
    box-sizing: border-box;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    cursor: default;
    padding: 7px 12px;
    min-height: 32px;
    border-radius: var(--dbx-chip-container-shape, var(--mat-chip-container-shape-radius, var(--mat-sys-corner-small, 8px)));
  }

  /// @dbx-utility dot
  /// @intent small round status dot painted from `currentColor` — pair with `[dbxTextColor]` (or any colored text context); size via `--dbx-dot-size`.
  /// @role text
  /// @see-also card-horizontal-header-dot, text-color, chip
  .dbx-dot {
    display: inline-block;
    flex-shrink: 0;
    width: var(--dbx-dot-size, 8px);
    height: var(--dbx-dot-size, 8px);
    border-radius: 50%;
    background: currentColor;
  }

  /// @dbx-utility chip-spacer
  /// @intent right-margin spacer between adjacent chips — 2px right margin
  /// @role spacing
  /// @see-also chip-margin, icon-spacer
  .dbx-chip-spacer {
    margin-right: $chip-spacing;
  }

  // Colored chip surface. `<dbx-chip>` hosts a DbxColorDirective that supplies the
  // color tokens (named `dbx-{color}-bg` token class or inline config vars) and the
  // `.dbx-color` marker; the chip directive supplies `--dbx-color-bg-tone` (default
  // 18 → tonal). Painting happens here from those tokens. `:not(.dbx-default)`
  // guard: the host directive always adds the `.dbx-color` marker, so an uncolored
  // chip (marked `dbx-default`) must not paint. `.dbx-color-tonal` (tone < 100)
  // flips the text to the vibrant color.
  .dbx-chip.dbx-color:not(.dbx-default) {
    @include style.dbx-color-surface(18%);

    &.dbx-color-tonal {
      color: var(#{theming.$dbx-bg-color-var});
    }
  }

  .dbx-chip.dbx-chip-small {
    font-size: var(--mat-sys-label-medium-size);
    padding: 2px 8px;
    min-height: 20px;
  }

  .dbx-chip-small-text .dbx-chip,
  .dbx-chip-small-text.dbx-chip,
  .dbx-chip-small-text.dbx-chip.dbx-chip-small {
    font-size: var(--mat-sys-label-small-size, 10px);
  }

  .dbx-chip.dbx-chip-block {
    border-radius: 0;
  }

  /// @dbx-utility chip-margin
  /// @intent uniform 4px margin around a chip — use when chips wrap onto multiple rows
  /// @role spacing
  /// @see-also chip-spacer
  .dbx-chip-margin {
    margin: 4px;
  }

  .dbx-chip-sublabel {
    margin-left: $icon-spacing;
  }

  /// @dbx-utility us-address
  /// @intent pre-wrapped, line-tightened US-address text — paint the styling on a `<p>` rendered from `unitedStatesAddressString()` (or use the `<dbx-us-address>` component)
  /// @role text
  .dbx-us-address {
    white-space: pre-wrap !important;
    line-height: 1.4;
  }

  /// @dbx-utility modelkey
  /// @intent allow line breaks inside long opaque keys/IDs — `line-break: anywhere`
  /// @role text
  .dbx-modelkey {
    line-break: anywhere;
  }

  .dbx-text-chips-listbox button.mat-mdc-chip-action {
    pointer-events: none; // disable the chip click and selection events.
    user-select: none;
  }

  // override Material's chip styling when a -bg color class is applied
  .dbx-text-chips-listbox mat-chip-option[class*='-bg'] {
    --mat-chip-elevated-selected-container-color: #{theming.$dbx-bg-color};
    --mat-chip-elevated-container-color: #{theming.$dbx-bg-color};
    --mat-chip-selected-label-text-color: #{theming.$dbx-color};
    --mat-chip-label-text-color: #{theming.$dbx-color};
    --mat-chip-with-icon-selected-icon-color: #{theming.$dbx-color};
    --mat-chip-with-icon-icon-color: #{theming.$dbx-color};
  }

  /// @dbx-utility hint
  /// @intent muted hint text — 80% opacity (mirrors mat-form-field hint emphasis)
  /// @role text
  /// @see-also dbx-faint, dbx-note
  .dbx-hint,
  .dbx-clear-hint {
    opacity: $hint-opacity;
  }

  /// @dbx-utility faint
  /// @intent very faint text — 54% opacity (matches mat-hint baseline)
  /// @role text
  /// @see-also dbx-hint, dbx-note
  .dbx-faint {
    opacity: $faint-opacity;
  }

  /// @dbx-utility label
  /// @intent muted form-field label text — 54% opacity (matches `mat-hint`); pair with `<dbx-label-block>` for the standard label-over-content layout
  /// @role text
  /// @see-also label-block, dbx-hint, dbx-form-description
  .dbx-label,
  .dbx-sublabel,
  .dbx-chip-sublabel,
  .dbx-form-description {
    opacity: $mat-hint-opacity;
  }

  /// @dbx-utility note
  /// @intent secondary note text — 70% opacity (between hint and faint)
  /// @role text
  /// @see-also dbx-hint, dbx-faint
  .dbx-note {
    opacity: $note-opacity;
  }

  /// @dbx-utility outlined-text
  /// @intent on-surface-variant text with a thin surface-tinted outline for legibility over imagery
  /// @role text
  .dbx-outlined-text {
    color: var(--mat-sys-on-surface-variant);
    text-shadow:
      -1px -1px 0 color-mix(in srgb, var(--mat-sys-surface) 40%, transparent),
      1px -1px 0 color-mix(in srgb, var(--mat-sys-surface) 40%, transparent),
      -1px 1px 0 color-mix(in srgb, var(--mat-sys-surface) 40%, transparent),
      1px 1px 0 color-mix(in srgb, var(--mat-sys-surface) 40%, transparent);
  }

  /// @dbx-utility nowrap
  /// @intent prevent whitespace wrapping (white-space: nowrap)
  /// @role text
  .dbx-nowrap {
    white-space: nowrap;
  }

  .dbx-number-with-limit {
    padding: var(--dbx-padding-1) var(--dbx-padding-2);

    .dbx-number-with-limit-divider {
      margin: 0 3px;
    }
  }

  // `<dbx-number-with-limit>` applies a ratio-derived `[dbxColor]` (ok/notice/warn)
  // to itself; paint the colored pill from those tokens. The `:not(.dbx-default)`
  // guard keeps the no-limit (uncolored) state from painting.
  .dbx-number-with-limit.dbx-color:not(.dbx-default) {
    @include style.dbx-color-surface();
  }

  .dbx-number-with-limit-rounded {
    border-radius: var(--dbx-number-with-limit-container-shape, var(--mat-sys-corner-medium));
  }

  .dbx-click-to-copy-text-highlighted {
    text-decoration: underline;
  }

  .dbx-label,
  .dbx-sublabel,
  .dbx-chip-sublabel {
    font-size: var(--mat-sys-body-small-size);
  }

  // MARK: M3 type-role utilities
  // Apply the full Material 3 `font` shorthand (size + weight + line-height +
  // tracking + family) for a single type role. Compose with .dbx-uppercase /
  // .dbx-tracked-wide for eyebrow-style chrome.
  /// @dbx-utility text-display-large
  /// @intent Material 3 display-large type role — largest hero/expressive headline
  /// @role text
  .dbx-text-display-large {
    font: var(--mat-sys-display-large);
  }

  /// @dbx-utility text-display-medium
  /// @intent Material 3 display-medium type role — secondary hero headline
  /// @role text
  .dbx-text-display-medium {
    font: var(--mat-sys-display-medium);
  }

  /// @dbx-utility text-display-small
  /// @intent Material 3 display-small type role — compact hero headline
  /// @role text
  .dbx-text-display-small {
    font: var(--mat-sys-display-small);
  }

  /// @dbx-utility text-headline-large
  /// @intent Material 3 headline-large type role — primary section heading
  /// @role text
  .dbx-text-headline-large {
    font: var(--mat-sys-headline-large);
  }

  /// @dbx-utility text-headline-medium
  /// @intent Material 3 headline-medium type role — secondary section heading
  /// @role text
  .dbx-text-headline-medium {
    font: var(--mat-sys-headline-medium);
  }

  /// @dbx-utility text-headline-small
  /// @intent Material 3 headline-small type role — tertiary section heading
  /// @role text
  .dbx-text-headline-small {
    font: var(--mat-sys-headline-small);
  }

  /// @dbx-utility text-title-large
  /// @intent Material 3 title-large type role — prominent UI title
  /// @role text
  .dbx-text-title-large {
    font: var(--mat-sys-title-large);
  }

  /// @dbx-utility text-title-medium
  /// @intent Material 3 title-medium type role — standard UI title
  /// @role text
  .dbx-text-title-medium {
    font: var(--mat-sys-title-medium);
  }

  /// @dbx-utility text-title-small
  /// @intent Material 3 title-small type role — small UI title
  /// @role text
  .dbx-text-title-small {
    font: var(--mat-sys-title-small);
  }

  /// @dbx-utility text-body-large
  /// @intent Material 3 body-large type role — long-form body text
  /// @role text
  .dbx-text-body-large {
    font: var(--mat-sys-body-large);
  }

  /// @dbx-utility text-body-medium
  /// @intent Material 3 body-medium type role — default body text
  /// @role text
  .dbx-text-body-medium {
    font: var(--mat-sys-body-medium);
  }

  /// @dbx-utility text-body-small
  /// @intent Material 3 body-small type role — supporting body text (captions, hints)
  /// @role text
  .dbx-text-body-small {
    font: var(--mat-sys-body-small);
  }

  /// @dbx-utility text-label-large
  /// @intent Material 3 label-large type role — button and tab text
  /// @role text
  .dbx-text-label-large {
    font: var(--mat-sys-label-large);
  }

  /// @dbx-utility text-label-medium
  /// @intent Material 3 label-medium type role — small label text (eyebrows, chips)
  /// @role text
  /// @see-also dbx-uppercase, dbx-tracked-wide
  .dbx-text-label-medium {
    font: var(--mat-sys-label-medium);
  }

  /// @dbx-utility text-label-small
  /// @intent Material 3 label-small type role — smallest label text
  /// @role text
  .dbx-text-label-small {
    font: var(--mat-sys-label-small);
  }

  // MARK: Text transforms
  /// @dbx-utility uppercase
  /// @intent uppercase text transform
  /// @role text
  /// @see-also dbx-lowercase, dbx-tracked-wide
  .dbx-uppercase {
    text-transform: uppercase;
  }

  /// @dbx-utility lowercase
  /// @intent lowercase text transform
  /// @role text
  /// @see-also dbx-uppercase
  .dbx-lowercase {
    text-transform: lowercase;
  }

  // Eyebrow-style letter-spacing — pairs with .dbx-text-label-medium /
  // .dbx-uppercase to render the M3 "overline" pattern (e.g. card eyebrows).
  /// @dbx-utility tracked-wide
  /// @intent eyebrow letter-spacing (0.08em) — pair with dbx-text-label-medium + dbx-uppercase for the M3 overline pattern
  /// @role text
  /// @see-also dbx-uppercase, dbx-text-label-medium
  .dbx-tracked-wide {
    letter-spacing: 0.08em;
  }

  .dbx-click-to-copy-text-icon.mat-icon {
    width: $click-to-copy-icon-size;
    height: $click-to-copy-icon-size;
    font-size: $click-to-copy-icon-size;
    padding-left: 4px;
  }

  // MARK: Click To Copy Field
  /// @dbx-utility click-to-copy-field
  /// @intent read-only copyable field — `<dbx-click-to-copy-field>` body that shows a value (url, id, key, secret) in a bordered, tinted row with an optional leading icon, the copy icon at the end, and a show/hide button for secrets
  /// @role layout
  /// @component DbxClickToCopyFieldComponent
  /// @scope component-class
  /// @see-also click-to-copy-field-monospace
  .dbx-click-to-copy-field {
    display: flex;
    align-items: center;
    padding: var(--dbx-padding-2) var(--dbx-padding-3);
    border: 1px solid var(--mat-sys-outline-variant);
    border-radius: var(--mat-sys-corner-small, 8px);
    background: $dbx-click-to-copy-field-background;

    > .dbx-click-to-copy-text-component {
      display: flex;
      flex: 1 1 auto;
      align-items: center;
      min-width: 0;

      // the click-to-copy content span
      > span {
        display: flex;
        flex: 1 1 auto;
        align-items: center;
        gap: var(--dbx-padding-2);
        min-width: 0;
        cursor: pointer;
      }
    }

    .dbx-click-to-copy-text-icon.mat-icon {
      padding-left: var(--dbx-padding-2);
      color: var(--mat-sys-primary);
      cursor: pointer;
    }
  }

  .dbx-click-to-copy-field-icon.mat-icon {
    flex-shrink: 0;
    width: $dbx-click-to-copy-field-icon-size;
    height: $dbx-click-to-copy-field-icon-size;
    font-size: $dbx-click-to-copy-field-icon-size;
    color: var(--mat-sys-on-surface-variant);
  }

  .dbx-click-to-copy-field-text {
    color: var(--mat-sys-on-surface);
    word-break: break-all;
  }

  // with clickIconToCopyOnly only the icon copies, so the value is selectable text rather than a click target
  .dbx-click-to-copy-field-icon-only > .dbx-click-to-copy-text-component > span {
    cursor: auto;
  }

  /// @dbx-utility click-to-copy-field-monospace
  /// @intent monospace value for `<dbx-click-to-copy-field [monospace]="true">` — urls, ids, keys, and codes
  /// @role text
  /// @component DbxClickToCopyFieldComponent
  /// @scope component-class
  /// @see-also click-to-copy-field
  .dbx-click-to-copy-field-monospace .dbx-click-to-copy-field-text {
    font-family: $dbx-click-to-copy-field-monospace-font-family;
    font-size: $dbx-click-to-copy-field-monospace-font-size;
  }

  // the show/hide button beside a secret's copy icon
  .dbx-click-to-copy-field-reveal {
    display: flex;
    flex-shrink: 0;
    margin: 0 0 0 var(--dbx-padding-2);
    padding: 0;
    border: none;
    border-radius: var(--mat-sys-corner-full, 50%);
    background: none;
    color: var(--mat-sys-on-surface-variant);
    cursor: pointer;

    &:focus-visible {
      outline: 2px solid var(--mat-sys-primary);
      outline-offset: 2px;
    }

    .mat-icon {
      width: $dbx-click-to-copy-field-icon-size;
      height: $dbx-click-to-copy-field-icon-size;
      font-size: $dbx-click-to-copy-field-icon-size;
    }
  }
}

@mixin theme($theme-config) {
}
