@layer components {
  /* Dialog Component
     ========================================================================== */

  :is(.dialog) {
    --speed: 150ms;

    container-type: inline-size;
    /* font-size: var(--font-small-responsive); */

    border: 0;
    opacity: 0;
    /* position: fixed; */
    inset: 0;
    margin: auto;
    width: calc(100vw - 2rem);
    max-width: 800px;
    max-height: 80vh;
    min-height: 200px;
    overflow-y: auto;
    transform: translateY(50%);
    transition:
      display var(--speed) allow-discrete,
      opacity var(--speed),
      overlay var(--speed) allow-discrete,
      transform var(--speed);

    &::backdrop {
      background-color: rgba(107, 114, 128, 0.7);
      backdrop-filter: blur(4px);
      opacity: 0;
      transition:
        display var(--speed) allow-discrete,
        opacity var(--speed),
        overlay var(--speed) allow-discrete;
    }

    /* :popover-open covers dialogs shown via the native popover API (popovertarget
       buttons, no JS); showModal() sets [open] instead. Same appearance either way. */
    &[open],
    &:popover-open {
      opacity: 1;
      transform: translateY(0);

      &::backdrop {
        opacity: 1;
      }
    }

    @starting-style {
      &[open],
      &:popover-open {
        opacity: 0;
        transform: translateY(50%);
      }

      &[open]::backdrop,
      &:popover-open::backdrop {
        opacity: 0;
      }
    }
  }

  .dialog__cancel-btn {
    position: absolute;
    top: 0.1rem;
    right: 0.5rem;

    i {
      font-size: 2rem;
    }
  }

  .dialog--wide {
    max-width: 1000px;
  }

  /* Confirm dialog: hugs its content instead of the 800×200 content-dialog frame.
     One spacing system — padding on the box, a single gap between message and
     actions — so a one-line confirm reads clean. Individual views can still pass
     richer content into .dialog__content. */
  .dialog--confirm {
    width: min(32rem, calc(100vw - 2rem));
    min-height: auto;

    .dialog__content {
      display: flex;
      flex-direction: column;
      gap: var(--block-space-double);
    }

    .dialog__message {
      margin: 0;
    }

    .dialog__actions {
      display: flex;
      justify-content: flex-end;
      gap: var(--inline-space);
    }
  }

  /* Lock page scroll while any modal dialog is open. The lock must live on html,
     not body: the reset gives html overflow-x hidden, which makes html the
     viewport scroller, so overflow set on body never propagates to the viewport.
     A hidden scroll container keeps its scroll offset, so the page stays put. */
  html:has(dialog[open]) {
    overflow: hidden;
  }
}
