/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

@namespace html url("http://www.w3.org/1999/xhtml");

:root {
  /* --tabpanel-background-color matches $in-content-page-background in newtab
     (browser/components/newtab/content-src/styles/_variables.scss) */
  --tabpanel-background-color: #F9F9FB;
  @media (-moz-content-prefers-color-scheme: dark) {
    --tabpanel-background-color: #2B2A33;
  }
  &[privatebrowsingmode=temporary] {
    /* Value for --in-content-page-background in aboutPrivateBrowsing.css.
       !important overrides the direct setting of this variable in
       ThemeVariableMap.sys.mjs when the user has a theme that defines
       ntp_background. */
    --tabpanel-background-color: #25003e !important;

    /* stylelint-disable-next-line media-query-no-invalid */
    @media (-moz-bool-pref: "browser.privatebrowsing.felt-privacy-v1") {
      --tabpanel-background-color: linear-gradient(45deg, #722291 0%, #45278D 50%, #393473 100%) !important;
    }
  }
}

#appcontent,
#browser,
#tabbrowser-tabbox,
#tabbrowser-tabpanels,
.browserSidebarContainer {
  /* Allow devtools with large specified width/height to shrink */
  min-width: 0;
  min-height: 0;
}

/* We set large flex on both containers to allow the devtools toolbox to
 * set a flex value itself. We don't want the toolbox to actually take up free
 * space, but we do want it to collapse when the window shrinks, and with
 * flex: 0 it can't.
 *
 * When the toolbox is on the bottom it's a sibling of browserStack, and when
 * it's on the side it's a sibling of browserContainer.
 */
.browserContainer {
  flex: 10000 10000;
  /* To contain the status panel */
  position: relative;

  /* .browserContainer only contains the devtools when docked horizontally */
  min-height: 0;
}

.browserStack {
  flex: 10000 10000;
  /* Prevent shrinking the page content to 0 height and width */
  min-height: 25px;
  min-width: 25px;
}

#tabbrowser-tabpanels {
  appearance: none;
  padding: 0;
  color-scheme: unset;
  background: var(--tabpanel-background-color);

  &[pendingpaint] {
    background-image: url(chrome://browser/skin/tabbrowser/pendingpaint.png);
    background-repeat: no-repeat;
    background-position: center center;
    background-size: 30px;
  }

  browser:is([blank], [pendingpaint]) {
    opacity: 0;
  }

  browser[type=content] {
    color-scheme: env(-moz-content-preferred-color-scheme);
  }

  browser[tabDialogShowing] {
    -moz-user-focus: none !important;
  }
}

/* Status panel */

#statuspanel {
  &:not([hidden]) {
    max-width: calc(100% - 5px);
    pointer-events: none;

    /* Take a bit more space vertically for the mouse tracker to hit us more
     * easily */
    padding-top: 2em;

    position: absolute;
    bottom: 0;
    left: 0;
  }

  &:not([mirror]):-moz-locale-dir(rtl),
  &[mirror]:-moz-locale-dir(ltr) {
    left: auto;
    right: 0;
  }

  &[sizelimit] {
    max-width: 50%;
  }

  &[type=status] {
    min-width: min(23em, 33%);
  }

  &[type=overLink] {
    transition: opacity 120ms ease-out, visibility 120ms;
  }

  &:is([type=overLink], [inactive][previoustype=overLink]) {
    direction: ltr;
  }

  &[inactive],
  :root[inDOMFullscreen] &:not([type=overLink]) {
    transition: none;
    opacity: 0;
    visibility: hidden;

    &[previoustype=overLink] {
      transition: opacity 200ms ease-out, visibility 200ms;
    }
  }

  /* stylelint-disable-next-line media-query-no-invalid */
  @media (-moz-bool-pref: "browser.tabs.hideStatusPanel") {
    visibility: hidden;
  }
}

#statuspanel-label {
  color-scheme: env(-moz-content-preferred-color-scheme);
  margin: 0;
  padding: 2px 4px;
  background-color: -moz-dialog;
  border: 1px none ThreeDShadow;
  border-top-style: solid;
  color: -moz-dialogText;
  text-shadow: none;

  @media (not (prefers-contrast)) and (not (-moz-platform: linux)) {
    background-color: light-dark(#f9f9fa, hsl(240,1%,20%));
    border-color: light-dark(#ddd, hsl(240,1%,40%));
    color: light-dark(#444, rgb(249,249,250));
  }

  #statuspanel:not([mirror]) > &:-moz-locale-dir(ltr),
  #statuspanel[mirror] > &:-moz-locale-dir(rtl) {
    border-right-style: solid;
    /* disabled on Windows for triggering grayscale AA (bug 659213): */
  	@media not (-moz-platform: windows) {
      border-top-right-radius: .3em;
    }
    margin-right: 1em;
  }

  #statuspanel:not([mirror]) > &:-moz-locale-dir(rtl),
  #statuspanel[mirror] > &:-moz-locale-dir(ltr) {
    border-left-style: solid;
    /* disabled on Windows for triggering grayscale AA (bug 659213): */
  	@media not (-moz-platform: windows) {
      border-top-left-radius: .3em;
    }
    margin-left: 1em;
  }
}

/**
 * Dialogs
 */

.dialogStack {
  z-index: var(--browser-stack-z-index-dialog-stack);
  position: absolute;
  inset: 0;

  /* Hide tab-modal dialogs when a window-modal one is up. */
  :root[window-modal-open] .browserStack > &,
  /* For some printing use cases we need to visually hide the dialog before
   * actually closing it / make it disappear from the frame tree. */
  &.temporarilyHidden {
    visibility: hidden;
  }
}

.dialogOverlay {
  align-items: center;
  visibility: hidden;

  &[topmost="true"] {
    z-index: 1;
  }

  .content-prompt-dialog > & {
    display: grid;
    align-items: unset;
    place-content: center;
    /* 90% for 5% top/bottom margins, the document height so that
     * smaller dialogs don't become too big. */
    grid-auto-rows: min(90%, var(--doc-height-px));
  }
}

.dialogBox {
  background-clip: content-box;
  display: flex;
  margin: 0 3vw;
  padding: 0;
  overflow-x: auto;

  /* Ensure that dialog boxes are pixel-snapped, to keep their internal layout
   * consistent, regardless of whether the surrounding layout places them at a
   * fractional position. (This helps prevent arbitrary 1px shifts that could
   * otherwise appear inside of a vertically-centered dialog when the
   * viewport-height changes from being odd to even.) */
  will-change: transform;

  &:not(.spotlightBox) {
    box-shadow: 0 2px 14px 0 rgba(0, 0, 0, 0.2);
    border-radius: 8px;
  }

  /*
   * In High Contrast Mode, this prevents a dialog from visually bleeding into
   * the window behind it, which looks jarring.
   */
  @media (prefers-contrast) {
    outline: 1px solid WindowText;
  }

  &[resizable="true"] {
    resize: both;
    overflow: hidden;
    min-height: 20em;
  }

  &[sizeto="available"] {
    --box-top-px: 0px; /* Overridden using inline style */
    --box-inline-margin: 4px;
    --box-block-margin: 4px;
    --box-ideal-width: 1000;
    --box-ideal-height: 650;
    --box-max-width-margin: calc(100vw - 2 * var(--box-inline-margin));
    --box-max-height-margin: calc(100vh - var(--box-top-px) - var(--box-block-margin));
    --box-max-width-ratio: 70vw;
    --box-max-height-ratio: calc(var(--box-ideal-height) / var(--box-ideal-width) * var(--box-max-width-ratio));
    --box-max-height-requested: 100vh;
    --box-max-width-requested: 100vw;
    --box-max-height-remaining: calc(100vh - var(--box-top-px));

    width: 100vw;
    height: 100vh;
    margin: 0;

    @media (min-width: 550px) {
      --box-inline-margin: min(calc(4px + (100vw - 550px) / 4), 16px);
    }

    @media (min-width: 800px) {
      --box-inline-margin: min(calc(16px + (100vw - 800px) / 4), 32px);
    }

    @media (min-height: 350px) {
      --box-block-margin: min(calc(4px + (100vh - 350px) / 4), 16px);
    }

    @media (min-height: 550px) {
      --box-block-margin: min(calc(16px + (100vh - 550px) / 4), 32px);
    }

    &:not(.spotlightBox) {
      max-width: min(max(var(--box-ideal-width) * 1px, var(--box-max-width-ratio)), var(--box-max-width-margin), var(--box-max-width-requested));
      max-height: min(max(var(--box-ideal-height) * 1px, var(--box-max-height-ratio)), var(--box-max-height-margin), var(--box-max-height-requested), var(--box-max-height-remaining));
    }

    .dialogStack &.spotlightBox {
      /* Tab modal: subtract the navigator toolbox height from the dialog height. */
      height: calc(100vh - var(--box-top-px));
    }
  }

  :not(.content-prompt-dialog) > .dialogOverlay > &:not(.spotlightBox) {
    /* Make dialogs overlap with upper chrome UI. Not necessary for Spotlight
    dialogs that are intended to be centered above the window or content area. */
    margin-top: -5px;
  }

  /* For window-modal dialogs, we allow overlapping the urlbar if the window is
   * small enough. */
  #window-modal-dialog > .dialogOverlay > &:not(.spotlightBox) {
    /* Do not go below 3px (as otherwise the top of the dialog would be
     * adjacent to or clipped by the top of the window), or above the window
     * size. */
    margin-top: clamp(
      3px,
      var(--chrome-offset, 20px) - 5px,
      calc(100vh - var(--subdialog-inner-height) - 5px)
    );
  }
}

#window-modal-dialog {
  overflow: visible;
  padding: 0;
  /* Override default <html:dialog> styles */
  border-width: 0;
  background-color: transparent;
  /* This makes the dialog top-aligned by default (the dialog box will move via
   * margin-top above) */
  bottom: auto;
  /* When showModal() is called on a <dialog>, the <dialog> itself will be
   * focused when there's no content, hence the focus ring. However, this
   * focus ring is not needed because we always setup the content of the dialog
   * after its opened and manually focus an element within it.
   */
  outline: none;

  &.spotlight {
    /* Spotlight window modal dialogs should be equal in size to the window. */
    bottom: revert;
    max-height: 100%;
    max-width: 100%;
  }
}

.dialogFrame {
  margin: 0;
  flex: 1;
  /* Default dialog dimensions */
  width: 34em;
}

.dialogOverlay[topmost="true"],
#window-modal-dialog::backdrop {
  background-color: rgba(28, 27, 34, 0.45);
}

.dialogOverlay[hideContent="true"][topmost="true"] {
  background-color: var(--tabpanel-background-color);
}

/* For the window-modal dialog, the background is supplied by the HTML dialog
 * backdrop, so the dialogOverlay background above "double backgrounds" - so
 * we remove it here: */
#window-modal-dialog > .dialogOverlay[topmost="true"] {
  background-color: transparent;
}
