/* 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/extensions/newtab/content-src/styles/_variables.scss) */
  --tabpanel-background-color: #f9f9fb;
  @media (-moz-content-prefers-color-scheme: dark) {
    --tabpanel-background-color: #2b2a33;
  }
  &[privatebrowsingmode="temporary"] {
    --tabpanel-background-color: linear-gradient(45deg, #722291 0%, #45278d 50%, #393473 100%) !important;
  }
}

@media -moz-pref("browser.nova.enabled") {
  #navigator-toolbox {
    will-change: background-color;
    transition: background-color var(--inactive-window-transition);
    margin-block-start: var(--chrome-window-gap);
    margin-block-end: var(--chrome-window-gap);
    margin-inline: var(--chrome-window-gap);
    overflow: hidden;
  }

  #browser {
    display: flex;
    box-sizing: border-box;
    padding: var(--chrome-window-gap);
    padding-block-start: 0;
    gap: var(--chrome-window-gap);
  }

  #tabbrowser-tabbox {
    flex: 1;
    box-sizing: border-box;
  }

  /* AI window splitter and box use visibility:collapse, not display:none, so
   * they are separated by flexbox gaps even when invisible. Override in nova
   * mode so the gaps disappear. This means that the AI window frame won't be
   * properly preserved when hidden in nova mode; to be addressed in a future
   * patch. See bug2033594. */
  #ai-window-splitter[collapsed],
  #ai-window-box[collapsed] {
    display: none;
  }

  /* Match the .browserContainer of any tab panel that is not a split-view
   * panel. This covers the initial state, the state after split-view is fully
   * dissolved, and the suspended state — where #tabbrowser-tabpanels still
   * has [splitview] (because suspended split-view panels remain in the
   * tabbox) but the currently-selected tab is a non-split-view one. Without
   * this, the visible tab loses its rounded corners until split-view is
   * fully dissolved. */
  #tabbrowser-tabpanels > :not(.split-view-panel) .browserContainer {
    border-radius: var(--chrome-block-radius);
    overflow: clip;
    outline: none;
    box-shadow: none;
    border: 1px solid var(--chrome-content-separator-color);
  }

  /* Splitter between split-view panels. The active panel's 2px focus outline
   * extends into the splitter margin on the active panel's side, so we widen
   * that side's margin to 3px (2px outline + 1px clear) and keep the other
   * side at 1px. See the :has() rules below for the asymmetric overrides. */
  #tabbrowser-tabpanels[splitview] .split-view-splitter {
    background-color: transparent;
    border: none;
    border-radius: var(--border-radius-large);
    min-width: auto;
    min-height: auto;
    width: 4px;
    margin-inline: 1px;
    transition: background-color 0.5s ease-in-out;

    &:hover {
      background-color: var(--focus-outline-color);
    }
  }

  /* When column-0 is selected, its right outline extends into the splitter's
   * inline-start margin: widen that side to 3px (2px outline + 1px clear). */
  #tabbrowser-tabpanels[splitview]:has(.split-view-panel[column="0"].deck-selected) .split-view-splitter {
    margin-inline-start: 3px;
  }

  /* When column-1 is selected, its left outline extends into the splitter's
   * inline-end margin: widen that side to 3px (2px outline + 1px clear). */
  #tabbrowser-tabpanels[splitview]:has(.split-view-panel[column="1"].deck-selected) .split-view-splitter {
    margin-inline-end: 3px;
  }
}

#navigator-toolbox {
  border-bottom: 0.01px solid var(--chrome-content-separator-color);

  @media -moz-pref("sidebar.revamp") {
    /* This reserves space for the content area outline */
    border-bottom-color: var(--toolbar-background-color);
  }

  @media -moz-pref("sidebar.verticalTabs") {
    border-bottom-style: none;
  }

  @media -moz-pref("browser.nova.enabled") {
    border-bottom: 1px solid var(--chrome-content-separator-color);
  }
}

/* Needed to ensure #sidebar-wrapper is full height when vertical tabs are not enabled */
#browser {
  position: relative;
}

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

@media (not -moz-pref("sidebar.verticalTabs")) and (not -moz-pref("browser.nova.enabled")) {
  #browser {
    background-color: var(--toolbar-background-color);
    color: var(--toolbar-text-color);
  }
}

#tabbrowser-tabbox {
  position: relative;
  z-index: var(--browser-area-z-index-tabbox);
  margin: 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;

  /* We want to be able to show the frame color behind the clipped radiused corner */
  background: var(--tabpanel-background-color);

  @media -moz-pref("sidebar.revamp") {
    outline: 0.01px solid var(--chrome-content-separator-color);
    box-shadow: var(--content-area-shadow);
  }

  @media -moz-pref("sidebar.revamp") and -moz-pref("sidebar.revamp.round-content-area") {
    overflow: clip;

    @media not -moz-pref("browser.nova.enabled") {
      :root:not([inDOMFullscreen]) #tabbrowser-tabbox[sidebar-shown] & {
        @media -moz-pref("sidebar.position_start") {
          border-start-start-radius: var(--border-radius-medium);
        }
        @media not -moz-pref("sidebar.position_start") {
          border-start-end-radius: var(--border-radius-medium);
        }
      }

      :root[ai-window]:not([inDOMFullscreen]) & {
        border-start-start-radius: var(--border-radius-medium);
        border-start-end-radius: var(--border-radius-medium);
      }
    }
  }
}

.browserSidebarContainer {
  position: absolute;
  inset: 0;
  anchor-scope: --browser-with-dialog;
}

.sidebar-browser-stack {
  flex: 1;
}

.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;
  display: flex;

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

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

  /* Exclude browsers with smartwindow-content attribute which inherit
     color-scheme from chrome to follow the browser theme */
  browser[type="content"]:not([smartwindow-content]) {
    color-scheme: env(-moz-content-preferred-color-scheme);
  }

  browser[tabDialogShowing] {
    -moz-user-focus: none !important;
    /* Used to position .dialogStack on top of this <browser> element so it doesn't overlap
       the DevTools toolbox */
    anchor-name: --browser-with-dialog;
  }

  .split-view-panel {
    --panel-min-width: 140px;
    min-width: var(--panel-min-width);
    max-width: calc(100% - var(--panel-min-width));
    flex: 1;
    width: 49.4%;
  }

  &[splitview] {
    /* Split-view panels without split-view-panel-active are dormant (a non-split-view
       tab is selected). Hide them from the flex layout without stripping their sizing
       attributes, so they re-enter at the correct size when reactivated. */
    .split-view-panel:not(.split-view-panel-active) {
      display: none;
    }

    .split-view-panel.split-view-panel-active {
      margin: var(--space-xsmall);
      position: relative;
      width: unset;

      @media -moz-pref("browser.nova.enabled") and -moz-pref("sidebar.revamp") {
        margin: var(--chrome-window-gap);
      }
    }

    /* Ensure any dialogs are clipped in an inactive/not-selected panel. */
    :root:not([inDOMFullscreen]) & > .split-view-panel:not(.deck-selected) {
      overflow: clip;
    }

    /* Ensure split view panels can display in fullscreen mode */
    :root[inDOMFullscreen] & > .split-view-panel-active:not(.deck-selected) {
      -moz-subtree-hidden-only-visually: 1;
    }

    :root[inDOMFullscreen] & > .split-view-splitter {
      display: none;
    }

    :root[inDOMFullscreen] & > .split-view-panel-active.deck-selected {
      margin: 0;
      position: absolute;
      max-width: none;
      width: 100% !important;

      & > .browserContainer {
        border-radius: 0;
      }
    }

    .split-view-panel {
      .browserContainer {
        border-radius: var(--border-radius-medium);
        overflow: clip;
      }

      /* The selected panel's dialogs need to sit above the non-selected tab panels. */
      &.deck-selected > .browserContainer {
        z-index: 1;
        outline: var(--focus-outline);
      }
    }

    .split-view-panel[column="0"] {
      order: 0;
      margin-inline-end: 0;

      @media not (-moz-platform: macos) {
        z-index: 1;
      }

      @media -moz-pref("browser.nova.enabled") {
        #tabbrowser-tabbox:is([sidebar-shown], [sidebar-panel-open]) & {
          margin-inline-start: 0;
        }
      }
    }

    .split-view-splitter {
      order: 1;
      flex: none;
      -moz-user-focus: normal;
      border-color: transparent;

      &:focus-visible {
        outline: auto;
      }
    }

    .split-view-panel[column="1"] {
      order: 2;
      margin-inline-start: 0;
    }

    /* Panels with a custom width shouldn't grow. */
    .split-view-panel[width] {
      flex: none;

      @media not (prefers-reduced-motion) {
        transition: width 50ms ease-out;
      }
    }

    /* Display split view footer within inactive panels. */
    .split-view-panel:not(.deck-selected) > .browserContainer > .browserStack > split-view-footer {
      display: flex;

      &[hidden] {
        display: none;
      }
    }
  }
}

@media -moz-pref("browser.nova.enabled") {
  /* Match the corner radius and separator border of unsplit panels.
   * Skip the border on the active panel so its focus outline can sit flush
   * against the content without a visible gap. */
  #tabbrowser-tabpanels[splitview] .split-view-panel > .browserContainer {
    border-radius: var(--chrome-block-radius);
  }

  #tabbrowser-tabpanels[splitview] .split-view-panel:not(.deck-selected) > .browserContainer {
    border: var(--border-width) solid var(--chrome-content-separator-color);
  }

  /* Align split-view panels with the sidebar's block edges. The surrounding
   * #browser already supplies --chrome-window-gap of padding on the
   * top/bottom, so the panel itself shouldn't add more. */
  #tabbrowser-tabpanels[splitview] .split-view-panel.split-view-panel-active {
    margin-block: 0;
  }
}

/* Split view */

split-view-footer {
  max-width: calc(100% - var(--space-xsmall));
  display: none;
  position: absolute;
  inset-block-end: 0;
  inset-inline-end: 0;

  border-block-start: 1px solid var(--border-color);
  border-inline-start: 1px solid var(--border-color);
  border-start-start-radius: var(--border-radius-medium);
  border-start-end-radius: 0;
  border-end-end-radius: var(--border-radius-medium);
  border-end-start-radius: 0;

  padding-block: var(--space-xxsmall);
  padding-inline: var(--space-small) var(--space-xsmall);

  -moz-context-properties: fill;
  fill: var(--button-icon-fill);
}

.split-view-icon {
  width: var(--icon-size);
  height: var(--icon-size);
}

.split-view-uri {
  overflow: hidden;
  text-overflow: ellipsis;
}

split-view-footer,
.split-view-security-warning {
  align-items: center;
  gap: var(--space-small);
  white-space: nowrap;
}

/* 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="letterboxingStatus"],
  &[type="overLink"] {
    transition:
      opacity 120ms ease-out,
      visibility 120ms;
  }

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

  .browserStack:not(.letterboxingStatus) &[type="letterboxingStatus"],
  .exclude-letterboxing &[type="letterboxingStatus"],
  &[inactive],
  :root[inDOMFullscreen] &:not([type="overLink"]) {
    transition: none;
    opacity: 0;
    visibility: hidden;

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

  @media -moz-pref("browser.tabs.hideStatusPanel") {
    visibility: hidden;
  }

  /* Ensure that this appears on top of the split view footer. */
  .split-view-panel & {
    z-index: 1;
  }
}

#statuspanel-label,
split-view-footer {
  color-scheme: env(-moz-content-preferred-color-scheme);
  background-color: -moz-dialog;
  border-color: ThreeDShadow;
  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-label {
  margin: 0;
  padding: 2px 4px;
  border-width: 1px;
  border-style: none;
  border-top-style: solid;

  @media (-moz-mac-tahoe-theme) {
    /* Slightly increasing the padding to prevent the first letter from partially getting cut off by the large window corner radius. */
    padding: 3px 5px;
  }

  #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: 0.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: 0.3em;
    }
    margin-left: 1em;
  }
}

#statuspanel:is([type="letterboxingStatus"], [previoustype="letterboxingStatus"][inactive]) > #statuspanel-label {
  background-image: url("chrome://browser/skin/window.svg");
  background-size: var(--icon-size);
  background-repeat: no-repeat;
  background-position-y: center;
  background-position-x: left var(--space-small);

  &:-moz-locale-dir(rtl) {
    background-position-x: right var(--space-small);
  }

  padding-inline-start: calc(var(--space-small) + var(--icon-size) + var(--space-small));
  -moz-context-properties: fill;
  fill: var(--color-accent-primary);
  @media (forced-colors) {
    fill: var(--icon-color);
  }
}

/**
 * Shortcuts
 */
#selection-shortcut-action-panel {
  --panel-subview-body-padding: 0;
}

#ai-action-button {
  --button-min-height: 34px;
  --button-size-icon: 34px;
  --button-border-radius: 7px;
  margin: 1px;
}

#ask-chat-shortcuts {
  font: menu;
  max-width: 345px;
}

.ask-chat-shortcut-warning {
  margin: var(--panel-menuitem-margin);
  margin-bottom: var(--space-xsmall);
}

.ask-chat-shortcuts-custom-prompt {
  margin: var(--panel-menuitem-margin);
  margin-top: var(--space-small);
}

/**
 * Dialogs
 */

.dialogStack {
  z-index: var(--browser-stack-z-index-dialog-stack);
  position: absolute;
  inset: 0;
  /* --browser-with-dialog set on browser[tabDialogShowing], we want to position the overlay
     only on the top of the <browser> element so it doesn't overlap the DevTools toolbox */
  position-anchor: --browser-with-dialog;
  position-area: center;
  width: 100%;
  height: 100%;

  /* Override the <stack> `grid-area: 1 / 1` rule with an `auto` placement.
   * Otherwise the .dialogStack start edges are placed relative to the
   * center-aligned grid items, rather than the grid's padding area. */
  grid-area: auto;

  /* 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 {
  min-width: 0;
  background-clip: content-box;
  display: flex;
  padding: 0;
  overflow-x: auto;
  outline: 0.5px solid var(--card-border-color);

  /* 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: var(--popup-box-shadow);
    border-radius: var(--border-radius-medium);
  }

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

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

  &[sizeto="available"] {
    width: 100%;
    height: 100%;
    margin: 0;

    /* NOTE(emilio): This is a bit tricky, but basically what we want to do is
     * guarantee a size between 80% (or 90% for height) and 100% of the
     * available space, with some variable spacing when the available space is
     * over 600px. The 2 controls the growth of the margin, with a larger
     * number reaching the 80% width later, effectively. */
    --box-max-width-default: clamp(80%, 100% + (600px - 100%) / 2, 100%);
    --box-max-height-default: clamp(90%, 100% + (600px - 100%) / 2, 100%);
    max-width: var(--box-max-width-requested, var(--box-max-width-default));
    max-height: var(--box-max-height-requested, var(--box-max-height-default));
  }

  :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;

    /* When the dialog is in a splitview, the offset is a little larger */
    .deck-selected.split-view-panel & {
      margin-top: -8px;
    }
  }

  /* Spotlight dialogs are full-size on the content or window area */
  &.spotlightBox {
    max-width: none;
    max-height: none;
  }

  /* 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. */
    inset: 0;
    height: auto;
    width: auto;
    max-height: none;
    max-width: none;

    > .dialogOverlay {
      width: 100%;
      height: 100%;
    }
  }
}

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

/* Radius the backdrop so it doesnt occlude the radiused .browserContainer below it */
:root:not([inDOMFullscreen]) #tabbrowser-tabbox[sidebar-shown] .dialogOverlay[topmost="true"] {
  @media -moz-pref("sidebar.revamp.round-content-area") {
    border-start-end-radius: var(--border-radius-medium);

    @media -moz-pref("sidebar.position_start") {
      border-start-start-radius: var(--border-radius-medium);
      border-start-end-radius: 0;
    }
  }
}

.dialogOverlay[topmost="true"],
#window-modal-dialog::backdrop {
  background-color: var(--background-color-overlay);
}

.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;
}
