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

$content-max-width: theming.$content-max-width;
$content-border-inner-padding: theming.$padding-3;

$box-bottom-margin: 2vh;
$box-padding: theming.$padding-4;
$box-max-width: theming.$box-max-width;

$max-small-content-container-width: calc($content-max-width / 3);
$max-medium-content-container-width: calc($content-max-width / 2);
$max-large-content-container-width: calc($content-max-width / 1.337);
$max-content-container-width: $content-max-width;

$pit-padding: theming.$padding-4;

$content-container-padding: theming.$padding-4;
$content-container-padding-small-screen: theming.$padding-2;

$scroll-content-bottom-padding: 42px;

$dbx-content-pit-floating-button-margin: 8px;

$dbx-border-opacity-default: 20%;

@mixin core() {
  /// @dbx-utility content-border
  /// @intent dashed-border content frame — pads the inner content and draws a 3px dashed border via `--dbx-border-color` / `--dbx-border-opacity`
  /// @role layout
  /// @see-also dbx-content-elevate, dbx-content-pit
  .dbx-content-border {
    padding: $content-border-inner-padding;
  }

  /// @dbx-utility content-elevate
  /// @intent padded content surface lifted above its surroundings — the mirror of `.dbx-content-pit`. Per Material 3, elevation is communicated primarily with color (the brightest `surface-bright` tone, always lighter than the pit's `surface-dim` in both light and dark) plus a soft lift shadow for protection against the background, so it reads as raised and stays clearly distinct from the recessed pit. Tonal by default — a low-opacity wash of the active dbxColor over `surface-bright`; rounded by default, opt out with `.dbx-corners-none`. Override `--dbx-content-elevate-tone` (percentage) to tune the wash, `--dbx-content-elevate-bg` to replace the background outright, or `--dbx-content-elevate-shadow` to retune/remove (`none`) the shadow.
  /// @role layout
  /// @see-also dbx-content-border, dbx-content-pit, dbx-corners-none
  .dbx-content-elevate {
    padding: $content-border-inner-padding;
  }

  // Elevate rounds by default. Kept OUT of the `.dbx-content-elevate` rule and
  // wrapped in `:where()` so specificity stays at 0 — any single-class utility
  // (`.dbx-corners-none`, `.dbx-corners-large`, or an app class) overrides it.
  :where(.dbx-content-elevate) {
    border-radius: theming.$dbx-content-pit-rounded-border-radius;
  }

  /// @dbx-utility content-box
  /// @intent centered box — auto-margined max-width content surface with a `padding-4` inset and `2vh` bottom margin (compose with `.dbx-content-box-wide` to remove the max-width)
  /// @role layout
  /// @see-also dbx-content-container, dbx-prompt-box
  .dbx-content-box {
    margin: auto;
    padding: $box-padding;
    margin-bottom: $box-bottom-margin;
    max-width: $box-max-width;

    &.dbx-content-box-wide {
      max-width: unset;
    }
  }

  /// @dbx-utility content-pit
  /// @intent recessed surface pit ("negative elevation") — a semi-transparent tonal wash of the active dbxColor over `--mat-sys-surface-dim` (the dimmest/greyest M3 surface, the opposite end of the dim/bright pair from `.dbx-content-elevate`) so the lighter surface behind shows through, with a `padding-4` inset, used to visually nest content (e.g. logs, JSON, quoted blocks); rounded by default, opt out with `.dbx-corners-none`. Draws a thin 1px edge derived from its own background (a translucent ink of the active dbxColor + `on-surface` laid over the fill), so the edge follows dbxColor and background overrides — tune it with `--dbx-content-pit-border-width` (`0` removes it), `--dbx-content-pit-border-tone` (percentage), or `--dbx-content-pit-border-color`
  /// @role layout
  /// @see-also dbx-content-pit-scrollable, dbx-content-border, dbx-content-elevate, dbx-corners-none
  .dbx-content-pit {
    padding: $pit-padding;
  }

  // Pits round by default. Kept OUT of the `.dbx-content-pit` rule and wrapped
  // in `:where()` so specificity stays at 0 — any single-class utility
  // (`.dbx-corners-none`, `.dbx-corners-large`, or an app class) overrides it.
  :where(.dbx-content-pit) {
    border-radius: theming.$dbx-content-pit-rounded-border-radius;
  }

  /// @dbx-utility content-pit-rounded
  /// @intent rounded modifier for `.dbx-content-pit` — applies the `theming.$dbx-content-pit-rounded-border-radius` corner radius
  /// @role layout
  /// @parent content-pit
  /// @see-also dbx-content-pit, dbx-corners-none
  /// @deprecated Pits round by default now; this modifier is a harmless back-compat alias emitting the same radius. To square a pit use `.dbx-corners-none`.
  .dbx-content-pit-rounded {
    border-radius: theming.$dbx-content-pit-rounded-border-radius;
  }

  .dbx-content-pit > .dbx-label-block > .dbx-label {
    opacity: 0.66; // increase opacity slightly to make it easier to read against background
  }

  /// @dbx-utility content-pit-scrollable
  /// @intent scrollable modifier for `.dbx-content-pit` — turns the pit into a fixed frame that clips an inner `.dbx-content-pit-scrollable-content` wrapper; the wrapper (not the frame) scrolls, so the padded/cornered surface never shifts. Drive the height via the `[scrollable]` input (which writes `--dbx-content-pit-scrollable-max-height`) or fall back to `theming.$dbx-content-pit-scrollable-max-height`.
  /// @role layout
  /// @parent content-pit
  /// @see-also dbx-content-pit, dbx-content-pit-scrollable-content
  .dbx-content-pit-scrollable {
    // Fixed frame that clips its scrolling child. Keeping the pit's padding here
    // and the overflow on the inner wrapper (rather than both on this box) avoids
    // the Chrome scroll-anchor / overscroll shift that moves the whole pit when
    // the scroll reaches its top or bottom.
    overflow: hidden;
    max-width: 100%;
  }

  /// @dbx-utility content-pit-scrollable-content
  /// @intent inner scroll region for a scrollable `.dbx-content-pit` — wrap the pit body in this element when using `[scrollable]`; it owns the height cap + `overflow-y` so the pit frame stays put. The cap reads `--dbx-content-pit-scrollable-max-height` (published per-pit by `dbxContentPit`; `none` when the pit isn't scrollable).
  /// @role layout
  /// @parent content-pit-scrollable
  /// @see-also dbx-content-pit, dbx-content-pit-scrollable
  .dbx-content-pit .dbx-content-pit-scrollable-content {
    max-height: theming.$dbx-content-pit-scrollable-max-height;
    max-width: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
    overflow-anchor: none;

    // Negate the pit's vertical padding so the scroll region spans the full pit
    // height, then re-add it as padding here — the inset now scrolls with the
    // content so it can scroll flush to the pit's top and bottom edges, instead
    // of being clipped by a static padding band.
    margin-top: calc(-1 * #{$pit-padding});
    margin-bottom: calc(-1 * #{$pit-padding});
    padding-top: $pit-padding;
    padding-bottom: $pit-padding;
  }

  /// @dbx-utility content-pit-floating-button
  /// @intent floats a button (typically a `dbx-button`) to the top-right of a `.dbx-content-pit` using `position: sticky` so it stays visible while the pit scrolls — used for inline pit actions like expand/collapse or copy
  /// @role layout
  /// @parent content-pit
  /// @see-also dbx-content-pit, dbx-content-pit-scrollable
  .dbx-content-pit-floating-button {
    float: right;
    position: sticky;
    top: $dbx-content-pit-floating-button-margin;
    z-index: 10;
    margin-right: $dbx-content-pit-floating-button-margin;
    margin-bottom: $dbx-content-pit-floating-button-margin;
  }

  // In a scrollable pit the floating button lives inside the inner scroll region
  // so `position: sticky` anchors to it; pin it flush to the top of that region.
  .dbx-content-pit-scrollable-content > .dbx-content-pit-floating-button {
    top: 0;
  }

  .dbx-app-page {
    @include theming.app-height();
    overflow: hidden;
  }

  .dbx-content,
  .dbx-content-page {
    //dbx-content page always has page height
    @include theming.page-height();
  }

  .dbx-content .dbx-content,
  // if a child of another dbx-content, give it content height instead of page height.
  .dbx-content-page .dbx-content,
  .dbx-content-without-content-navbar {
    @include theming.content-height();
  }

  .dbx-content.dbx-content-auto-height {
    height: 100% !important;
  }

  /// @dbx-utility content-scroll-lock
  /// @intent locks a region to `height: 100%` with `overflow: hidden` so its children can scroll independently of the page — wrap potentially-infinite-height content (calendars, virtual lists) and let the inner element handle its own `overflow: scroll`
  /// @role layout
  /// @see-also dbx-content, dbx-content-page, dbx-scroll-content
  .dbx-content-scroll-lock {
    height: 100%;
    overflow: hidden;
    padding: 0 var(--dbx-padding-1); // Override padding
  }

  /// @dbx-utility content-container
  /// @intent centered, padded content container with width-class and padding-class modifiers
  /// @role layout
  .dbx-content-container {
    margin: auto;
    padding: 0 $content-container-padding;

    // NOTE: the order of these classes matters.

    // padding
    &.container-padding-none {
      padding: 0;
    }

    &.container-padding-min {
      padding: 0 var(--dbx-padding-1);
    }

    &.container-padding-small {
      padding: 0 calc($content-container-padding / 3);
    }

    &.container-top-padding-none {
      padding-top: 0;
    }

    &.container-top-padding-min {
      padding-top: var(--dbx-padding-1);
    }

    &.container-top-padding-small {
      padding-top: var(--dbx-padding-2);
    }

    &.container-top-padding-normal {
      padding-top: var(--dbx-padding-3);
    }

    // width
    &.container-small {
      max-width: $max-small-content-container-width;
    }

    &.container-medium {
      max-width: $max-medium-content-container-width;
    }

    &.container-large {
      max-width: $max-large-content-container-width;
    }

    &.container-wide {
      max-width: $max-content-container-width;
    }

    // type
    &.normal-container-type {
      // No restriction.
    }

    &.content-container-type {
      // @include fillContentWithAppPageHeaderHeight();
      overflow-x: hidden;
      overflow-y: auto;
    }
  }

  .dbx-content-container-header-padded {
    padding: $content-container-padding-small-screen;
  }

  /// @dbx-utility scroll-content
  /// @intent adds a small bottom padding (~42px) to a scrollable content region so the last item doesn't sit flush against the bottom edge of the viewport — apply to the scrolling element itself (typically a `.dbx-content-container` rendered inside a `dbx-two-column-right`, `dbx-content-page`, or any host whose body overflows)
  /// @role spacing
  /// @see-also dbx-content-container, dbx-content-page, dbx-content-pit-scrollable
  .dbx-scroll-content {
    padding-bottom: var(--dbx-scroll-content-bottom-padding, #{$scroll-content-bottom-padding});
  }

  // Recessed surface ("negative elevation"): the pit reads as a tonal step below the surfaces it
  // nests in. It sits on `surface-dim` — the dimmest/greyest M3 surface tone — so it reads as a
  // grey recess in light mode and the darkest surface in dark mode, the opposite end of the
  // dim/bright pair from `.dbx-content-elevate`. (`surface-dim`/`surface-bright` are the one M3
  // pairing whose light/dark luminance ordering is stable, so the pit is reliably dimmer than the
  // elevate in both themes — the container ladder flips and can't guarantee that.) Tonal by
  // default — a low-opacity wash of the active dbxColor (`--dbx-bg-color-current`, primary by
  // default, driven by an ancestor/host `[dbxColor]`) laid over `surface-dim`, so the pit both
  // steps down a tone AND picks up the color context, instead of being a flat grey. That dim wash is
  // then rendered semi-transparent (`--dbx-content-pit-opacity`, default 50%) so the lighter surface
  // behind it shows through — the pit reads as a soft, airy recess rather than a heavy grey block,
  // while keeping its grey/dim character so it stays clearly dimmer than the elevate's
  // `surface-bright`. Override `--dbx-content-pit-tone` (percentage) to tune the wash strength,
  // `--dbx-content-pit-opacity` to make the recess lighter (lower %, more transparent) or heavier
  // (higher %), or set `--dbx-content-pit-bg` to replace the background outright (e.g. on a painted
  // surface where the tonal wash would clash).
  .dbx-content-pit {
    background: var(--dbx-content-pit-bg, color-mix(in srgb, color-mix(in srgb, #{theming.$dbx-bg-color} var(--dbx-content-pit-tone, 8%), var(--mat-sys-surface-dim)) var(--dbx-content-pit-opacity, 50%), transparent));
  }

  // Pit edge: a thin border that is a tonal step off the pit's own background rather than a fixed
  // grey — the elevate stays borderless, its bright fill + lift shadow already set it apart. The
  // border color is a translucent "ink" — the active dbxColor (`--dbx-bg-color-current`) blended
  // half-and-half with `--mat-sys-on-surface` — at `--dbx-content-pit-border-tone` (default 8%).
  // Because the background paints under the border (the default `border-box` clip), the edge renders
  // as that ink laid over the pit's actual fill, so it tracks every background change: an applied
  // `[dbxColor]` tints the edge more strongly than the fill, a `--dbx-content-pit-bg` override is
  // followed automatically, and `on-surface` flips the step darker in light themes and lighter in
  // dark themes. Override `--dbx-content-pit-border-width` for thickness (`0` removes it),
  // `--dbx-content-pit-border-tone` for strength, or `--dbx-content-pit-border-color` to replace the
  // color outright. Kept in `:where()` so specificity stays at 0 — any single-class border utility
  // (`.dbx-color-border`, `.dbx-content-border`) or app class overrides it.
  :where(.dbx-content-pit) {
    border: var(--dbx-content-pit-border-width, 1px) solid var(--dbx-content-pit-border-color, color-mix(in srgb, color-mix(in srgb, #{theming.$dbx-bg-color} 50%, var(--mat-sys-on-surface)) var(--dbx-content-pit-border-tone, 8%), transparent));
  }

  // Elevated surface ("positive elevation"): the tonal mirror of the pit. It sits on
  // `surface-bright` — the brightest M3 surface tone — so it reads lighter than its surroundings
  // (and always lighter than the pit's `surface-dim`, in BOTH themes, since dim/bright are the one
  // M3 pairing with a stable luminance ordering). It also carries a soft M3 shadow: per M3 the lift
  // is communicated primarily with color, and the subtle shadow is the sanctioned "protection
  // against a background" that sells the raise. Tonal by default — a low-opacity wash of the active
  // dbxColor (`--dbx-bg-color-current`, primary by default, driven by an ancestor/host `[dbxColor]`)
  // over `surface-bright`. Override `--dbx-content-elevate-tone` (percentage) to tune the wash,
  // `--dbx-content-elevate-bg` to replace the background outright, or `--dbx-content-elevate-shadow`
  // to retune/remove (`none`) the lift shadow.
  .dbx-content-elevate {
    background: var(--dbx-content-elevate-bg, color-mix(in srgb, #{theming.$dbx-bg-color} var(--dbx-content-elevate-tone, 8%), var(--mat-sys-surface-bright)));
    box-shadow: var(--dbx-content-elevate-shadow, var(--mat-sys-level1));
  }

  .dbx-content-border {
    // Faint dashed frame — keeps its own low opacity locally while sharing the global
    // border base color. The computed --dbx-border-color-current re-blends with this
    // overridden opacity at the point of use.
    --dbx-border-opacity: #{$dbx-border-opacity-default};
    border: 3px dashed var(--dbx-border-color-current);
  }
}

@mixin responsive($theme-config) {
  .dbx-content-container {
    @include theming.if-small-screen($theme-config) {
      // reduce all paddings down.
      &,
      &.container-padding-min,
      &.container-padding-small {
        padding: 0 $content-container-padding-small-screen;
      }

      // no padding does not gain padding.
      &.container-padding-none {
        padding: 0;
      }
    }
  }
}

@mixin theme($theme-config) {
  @include responsive($theme-config);
}
