/*
Sheet

A Dialog panel docked to an edge of the viewport:

<dialog class="dialog-overlay sheet-overlay">   top layer, transparent
  <div class="sheet-backdrop">                    the dimmed page; fades
  <div class="dialog sheet" data-side="right">    the panel; slides
    .sheet-header > .sheet-title + .sheet-description
    .sheet-body                                   scrolls when content is tall
    .sheet-footer                                 pinned to the bottom
    .dialog-close

The backdrop is its own element so the panel slides at full opacity while
the backdrop fades. Sides: top, right, bottom, left (physical) and start,
end (follow the writing direction). Widths are container tokens; the
radius rounds only the inner edge.
*/

@layer components {

.dialog-overlay.sheet-overlay {
  padding:         0;
  background:      none;
  backdrop-filter: none;
  overflow:        hidden;
}

.dialog-overlay.sheet-overlay[open] {
  display: block;
}

.dialog-overlay.sheet-overlay[data-state] {
  animation: none;
}

.sheet-backdrop {
  position:        fixed;
  inset:           0;
  background:      var(--backdrop);
  backdrop-filter: blur(var(--backdrop-blur));
}

.dialog-overlay.sheet-overlay:not([data-modal="true"]) > .sheet-backdrop {
  display: none;
}

.sheet-backdrop[data-state="open"] {
  animation: sheet-fade-in var(--duration-enter) var(--ease-enter);
}

.sheet-backdrop[data-state="closed"] {
  animation: sheet-fade-out var(--duration-exit) var(--ease-exit) forwards;
}

.dialog.sheet {
  --sheet-width:  var(--container-sm);

  position:       fixed;
  gap:            var(--dialog-gap);
  max-width:      none;
  max-height:     none;
  overflow:       hidden;
  border:         0 solid var(--dialog-border);
  border-radius:  0;
}

.dialog.sheet.is-sm   { --sheet-width: var(--container-xs); }
.dialog.sheet.is-lg   { --sheet-width: var(--container-xl); }
.dialog.sheet.is-xl   { --sheet-width: var(--container-3xl); }
.dialog.sheet.is-full { --sheet-width: 100%; }

/* Inline edges: full height, 75% wide up to the size's width. */
.dialog.sheet[data-side="right"],
.dialog.sheet[data-side="left"],
.dialog.sheet[data-side="start"],
.dialog.sheet[data-side="end"] {
  top:       0;
  bottom:    0;
  width:     75%;
  max-width: var(--sheet-width);
  height:    100%;
}

.dialog.sheet.is-full[data-side] {
  width: 100%;
}

.dialog.sheet[data-side="right"] {
  right:                     0;
  border-left-width:         var(--dialog-border-width);
  border-top-left-radius:    var(--radius-dialog);
  border-bottom-left-radius: var(--radius-dialog);
}

.dialog.sheet[data-side="left"] {
  left:                       0;
  border-right-width:         var(--dialog-border-width);
  border-top-right-radius:    var(--radius-dialog);
  border-bottom-right-radius: var(--radius-dialog);
}

.dialog.sheet[data-side="end"] {
  inset-inline-end:           0;
  border-inline-start-width:  var(--dialog-border-width);
  border-start-start-radius:  var(--radius-dialog);
  border-end-start-radius:    var(--radius-dialog);
}

.dialog.sheet[data-side="start"] {
  inset-inline-start:         0;
  border-inline-end-width:    var(--dialog-border-width);
  border-start-end-radius:    var(--radius-dialog);
  border-end-end-radius:      var(--radius-dialog);
}

/* Block edges: full width, as tall as the content, never past the viewport. */
.dialog.sheet[data-side="top"],
.dialog.sheet[data-side="bottom"] {
  left:       0;
  right:      0;
  width:      100%;
  max-height: calc(100% - var(--space-12));
}

.dialog.sheet[data-side="top"] {
  top:                        0;
  border-bottom-width:        var(--dialog-border-width);
  border-bottom-left-radius:  var(--radius-dialog);
  border-bottom-right-radius: var(--radius-dialog);
}

.dialog.sheet[data-side="bottom"] {
  bottom:                  0;
  border-top-width:        var(--dialog-border-width);
  border-top-left-radius:  var(--radius-dialog);
  border-top-right-radius: var(--radius-dialog);
}

.dialog.sheet .dialog-close {
  top:              calc(var(--dialog-padding) - var(--space-2));
  right:            auto;
  left:             auto;
  inset-inline-end: calc(var(--dialog-padding) - var(--space-2));
}

.sheet-header {
  display:             flex;
  flex-direction:      column;
  gap:                 var(--space-1-5);
  padding-inline-end:  var(--space-8);
}

.dialog.sheet .dialog-header {
  padding-right:      0;
  padding-inline-end: var(--space-8);
}

.sheet-body {
  display:         flex;
  flex-direction:  column;
  gap:             var(--space-3);
  flex:            1 1 auto;
  min-height:      0;
  overflow-y:      auto;
  overscroll-behavior: contain;
  /* Room on all four sides for the focus ring of a field at a scroll
     edge; the negative margin keeps the layout where it was. */
  margin:          calc(var(--space-1) * -1);
  padding:         var(--space-1);
}

/* A body that scrolls is a Tab stop (sheet.ts keepScrollStops). */
.sheet-body:focus-visible {
  outline:    none;
  box-shadow: var(--focus-ring);
}

.sheet-footer {
  display:        flex;
  flex-direction: column;
  gap:            var(--space-2);
  margin-top:     auto;
}

.sheet-footer > .button,
.sheet-footer > .dialog-close-part > .button {
  width: 100%;
}

/* scroll="outside" (Base UI's outside scroll dialog): the panel grows with
   its content and the overlay scrolls it, so the whole sheet moves as one.
   A side sheet is at least the viewport's height; a bottom sheet rises from
   the bottom edge and keeps a gap at the top when it is taller than the
   viewport, a top sheet keeps one at the bottom. */
.dialog-overlay.sheet-overlay.is-scroll-outside {
  overflow-y:          auto;
  overscroll-behavior: contain;
}

.dialog-overlay.sheet-overlay.is-scroll-outside[open] {
  display:        flex;
  flex-direction: column;
}

.sheet-overlay.is-scroll-outside > .dialog.sheet {
  position:   relative;
  inset:      auto;
  flex:       none;
  max-height: none;
  overflow:   visible;
}

.sheet-overlay.is-scroll-outside > .dialog.sheet[data-side="right"],
.sheet-overlay.is-scroll-outside > .dialog.sheet[data-side="left"],
.sheet-overlay.is-scroll-outside > .dialog.sheet[data-side="start"],
.sheet-overlay.is-scroll-outside > .dialog.sheet[data-side="end"] {
  height:     auto;
  min-height: 100%;
}

.sheet-overlay.is-scroll-outside > .dialog.sheet[data-side="right"] { margin-left: auto; }
.sheet-overlay.is-scroll-outside > .dialog.sheet[data-side="left"]  { margin-right: auto; }
.sheet-overlay.is-scroll-outside > .dialog.sheet[data-side="end"]   { margin-inline-start: auto; }
.sheet-overlay.is-scroll-outside > .dialog.sheet[data-side="start"] { margin-inline-end: auto; }

.sheet-overlay.is-scroll-outside > .dialog.sheet[data-side="bottom"] {
  margin-top: auto;
}

.sheet-overlay.is-scroll-outside:has(> .dialog.sheet[data-side="bottom"]) {
  padding-top: var(--space-12);
}

.sheet-overlay.is-scroll-outside:has(> .dialog.sheet[data-side="top"]) {
  padding-bottom: var(--space-12);
}

.sheet-overlay.is-scroll-outside .sheet-body {
  flex:     none;
  overflow: visible;
}

/* Motion */

.dialog.sheet[data-state="open"] {
  animation: sheet-in var(--duration-enter) var(--ease-enter);
}

.dialog.sheet[data-state="closed"] {
  animation: sheet-out var(--duration-exit) var(--ease-exit) forwards;
}

.dialog.sheet[data-side="right"]               { --sheet-from: translateX(100%); }
.dialog.sheet[data-side="left"]                { --sheet-from: translateX(-100%); }
.dialog.sheet[data-side="top"]                 { --sheet-from: translateY(-100%); }
.dialog.sheet[data-side="bottom"]              { --sheet-from: translateY(100%); }
.dialog.sheet[data-side="end"]                 { --sheet-from: translateX(100%); }
.dialog.sheet[data-side="start"]               { --sheet-from: translateX(-100%); }
.dialog.sheet[data-side="end"]:dir(rtl)        { --sheet-from: translateX(-100%); }
.dialog.sheet[data-side="start"]:dir(rtl)      { --sheet-from: translateX(100%); }

@keyframes sheet-in       { from { transform: var(--sheet-from); } }
@keyframes sheet-out      { to   { transform: var(--sheet-from); } }
@keyframes sheet-fade-in  { from { opacity: 0; } }
@keyframes sheet-fade-out { to   { opacity: 0; } }

/* A long unbroken title (a filename, a URL) wraps inside the panel. */
.sheet-title,
.sheet-description {
  min-width:     0;
  overflow-wrap: anywhere;
}

}
