Fix z-index issues

Change-Id: Ib21b96872be939ed0129c9a590376c5988f1e840
diff --git a/ui/src/assets/home_page.scss b/ui/src/assets/home_page.scss
index c85fce7..9876e62 100644
--- a/ui/src/assets/home_page.scss
+++ b/ui/src/assets/home_page.scss
@@ -84,7 +84,6 @@
         width: calc(var(--chan-width) * var(--chan-num));
         height: 40px;
         line-height: 40px;
-        z-index: 0;
         user-select: none;
       }
 
@@ -95,7 +94,7 @@
         width: var(--chan-width);
         height: 100%;
         color: white;
-        z-index: 2;
+        z-index: 1;
         text-transform: uppercase;
         font-size: 16px;
         font-family: var(--pf-font-compact);
@@ -112,7 +111,6 @@
         );
         top: 0;
         left: 0;
-        z-index: 1;
         border-radius: inherit;
         @include transition(0.2s);
       }
diff --git a/ui/src/assets/sidebar.scss b/ui/src/assets/sidebar.scss
index 1b95074..870a358 100644
--- a/ui/src/assets/sidebar.scss
+++ b/ui/src/assets/sidebar.scss
@@ -18,7 +18,6 @@
   --sidebar-padding-bottom: 40px;
   --sidebar-timing: 0.15s;
   grid-area: sidebar;
-  z-index: 4;
   background-color: #262f3c;
   overflow: hidden;
   width: var(--sidebar-width);
@@ -48,9 +47,6 @@
       height: 36px;
       margin-top: 4px;
     }
-    &::before {
-      z-index: 10;
-    }
     &.pf-sidebar__channel--canary::before,
     &.pf-sidebar__channel--autopush::before {
       display: block;
@@ -72,7 +68,7 @@
   }
   .pf-sidebar-button {
     position: fixed;
-    z-index: 5;
+    z-index: 2; // Needs to show above the topbar which has z-index: 1.
     background-color: #262f3c;
     height: var(--topbar-height);
     left: calc(var(--sidebar-width) - 50px);
@@ -338,7 +334,6 @@
   top: 20px;
   transform: rotate(-45deg);
   width: 200px;
-  z-index: 5;
 
   a {
     color: white;
diff --git a/ui/src/assets/topbar.scss b/ui/src/assets/topbar.scss
index 1f9468e..1e9b3b4 100644
--- a/ui/src/assets/topbar.scss
+++ b/ui/src/assets/topbar.scss
@@ -14,13 +14,10 @@
 
 @import "theme";
 
-@mixin omnibox-width() {
-}
-
 .pf-topbar {
   grid-area: topbar;
   position: relative;
-  z-index: 3;
+  z-index: 1; // Topbar shadow should show above page content.
   overflow: visible;
   background-color: var(--pf-color-background-secondary);
   box-shadow: $box-shadow-1;
diff --git a/ui/src/assets/widgets/details_shell.scss b/ui/src/assets/widgets/details_shell.scss
index 0a13d37..a341155 100644
--- a/ui/src/assets/widgets/details_shell.scss
+++ b/ui/src/assets/widgets/details_shell.scss
@@ -20,7 +20,7 @@
   font-family: var(--pf-font-compact);
 
   .pf-header-bar {
-    z-index: 1;
+    z-index: 1; // Ensure drop shadow is above page content
 
     display: flex;
     flex-direction: row;
diff --git a/ui/src/assets/widgets/modal.scss b/ui/src/assets/widgets/modal.scss
index b1efa9a..db949eb 100644
--- a/ui/src/assets/widgets/modal.scss
+++ b/ui/src/assets/widgets/modal.scss
@@ -40,7 +40,6 @@
 
 .pf-modal-backdrop {
   position: absolute;
-  z-index: 99;
   background-color: rgba(0, 0, 0, 0.6);
   top: 0;
   left: 0;
@@ -58,7 +57,6 @@
 
 .pf-modal-dialog {
   position: absolute;
-  z-index: 100;
   background-color: var(--pf-color-background);
   margin: auto;
   min-width: 25vw;
diff --git a/ui/src/assets/widgets/popup.scss b/ui/src/assets/widgets/popup.scss
index 824b48f..ba4412f 100644
--- a/ui/src/assets/widgets/popup.scss
+++ b/ui/src/assets/widgets/popup.scss
@@ -16,7 +16,6 @@
 
 .pf-popup-portal {
   position: absolute;
-  z-index: 10; // Hack to show popups over certain other elements
 
   // When width = 0 it can cause layout issues in popup content, so we give this
   // element some width manually
diff --git a/ui/src/assets/widgets/tooltip.scss b/ui/src/assets/widgets/tooltip.scss
index 22973a1..ea19afb 100644
--- a/ui/src/assets/widgets/tooltip.scss
+++ b/ui/src/assets/widgets/tooltip.scss
@@ -18,7 +18,6 @@
   position: absolute;
   background: var(--pf-color-background);
 
-  z-index: 10;
   padding: 2px 6px;
   border-radius: $border-radius;
   border: solid 1px var(--pf-color-border);
diff --git a/ui/src/assets/widgets/ui_main.scss b/ui/src/assets/widgets/ui_main.scss
index e58e56e..f3c0775 100644
--- a/ui/src/assets/widgets/ui_main.scss
+++ b/ui/src/assets/widgets/ui_main.scss
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 .pf-ui-main {
+  isolation: isolate; // Create a new stacking context to avoid z-index issues.
   display: grid;
   grid-template-areas:
     "sidebar topbar"
@@ -33,6 +34,7 @@
   }
 
   &__page-container {
+    isolation: isolate; // Create a new stacking context to avoid z-index issues.
     grid-area: page;
     overflow: auto;
   }
diff --git a/ui/src/frontend/index.ts b/ui/src/frontend/index.ts
index 3760946..2e91dbc 100644
--- a/ui/src/frontend/index.ts
+++ b/ui/src/frontend/index.ts
@@ -37,7 +37,7 @@
 import {maybeOpenTraceFromRoute} from './trace_url_handler';
 import {renderViewerPage} from './viewer_page/viewer_page';
 import {HttpRpcEngine} from '../trace_processor/http_rpc_engine';
-import {showModal} from '../widgets/modal';
+import {renderModalOverlay, showModal} from '../widgets/modal';
 import {IdleDetector} from './idle_detector';
 import {IdleDetectorWindow} from './idle_detector_interface';
 import {AppImpl} from '../core/app_impl';
@@ -290,6 +290,7 @@
         m(OverlayContainer, {fillParent: true}, [
           m(UiMain, {key: themeSetting.get()}),
         ]),
+        renderModalOverlay(),
       ]),
   });
 
diff --git a/ui/src/frontend/sidebar.ts b/ui/src/frontend/sidebar.ts
index 9ef23e6..a04183a 100644
--- a/ui/src/frontend/sidebar.ts
+++ b/ui/src/frontend/sidebar.ts
@@ -386,7 +386,6 @@
           this._redrawWhileAnimating.stop();
         },
       },
-      shouldShowHiringBanner() ? m(HiringBanner) : null,
       m(
         `header.pf-sidebar__channel--${getCurrentChannel()}`,
         m(`img[src=${assetSrc('assets/brand.png')}].pf-sidebar__brand`),
@@ -406,6 +405,7 @@
           m(SidebarFooter, attrs),
         ),
       ),
+      shouldShowHiringBanner() && m(HiringBanner),
     );
   }
 
diff --git a/ui/src/frontend/ui_main.ts b/ui/src/frontend/ui_main.ts
index ef137f1..b322bfd 100644
--- a/ui/src/frontend/ui_main.ts
+++ b/ui/src/frontend/ui_main.ts
@@ -21,7 +21,7 @@
 import {Command} from '../public/command';
 import {HotkeyConfig, HotkeyContext} from '../widgets/hotkey_context';
 import {HotkeyGlyphs} from '../widgets/hotkey_glyphs';
-import {maybeRenderFullscreenModalDialog, showModal} from '../widgets/modal';
+import {showModal} from '../widgets/modal';
 import {CookieConsent} from '../core/cookie_consent';
 import {toggleHelp} from './help_modal';
 import {Omnibox, OmniboxOption} from './omnibox';
@@ -775,7 +775,6 @@
         }),
         m('.pf-ui-main__page-container', app.pages.renderPageForCurrentRoute()),
         m(CookieConsent),
-        maybeRenderFullscreenModalDialog(),
         showStatusBarFlag.get() && renderStatusBar(app.trace),
         app.perfDebugging.renderPerfStats(),
       ),
diff --git a/ui/src/widgets/cursor_tooltip.ts b/ui/src/widgets/cursor_tooltip.ts
index 5fc6c79..031de8b 100644
--- a/ui/src/widgets/cursor_tooltip.ts
+++ b/ui/src/widgets/cursor_tooltip.ts
@@ -65,9 +65,9 @@
         ...rest,
         className: classNames('pf-cursor-tooltip', className),
         onBeforeContentMount: (dom: Element): MountOptions => {
-          const closestModal = dom.closest('.pf-overlay-container');
-          if (closestModal) {
-            return {container: closestModal};
+          const closestContainer = dom.closest('.pf-overlay-container');
+          if (closestContainer) {
+            return {container: closestContainer};
           }
           return {container: undefined};
         },
diff --git a/ui/src/widgets/modal.ts b/ui/src/widgets/modal.ts
index 6a379bd..f332325 100644
--- a/ui/src/widgets/modal.ts
+++ b/ui/src/widgets/modal.ts
@@ -17,6 +17,7 @@
 import {Icon} from './icon';
 import {Button, ButtonVariant} from './button';
 import {Intent} from './common';
+import {OverlayContainer} from './overlay_container';
 
 // This module deals with modal dialogs. Unlike most components, here we want to
 // render the DOM elements outside of the corresponding vdom tree. For instance
@@ -154,24 +155,28 @@
         onkeydown: this.onBackdropKeydown.bind(this, attrs),
         tabIndex: 0,
       },
-      m(
-        `.pf-modal-dialog${align}${customClass}${aria}`,
+      // Create a new overlay context container to ensure popups and tooltips et
+      // al within this modal can be seen.
+      m(OverlayContainer, {fillParent: true}, [
         m(
-          'header',
+          `.pf-modal-dialog${align}${customClass}${aria}`,
           m(
-            '.modal-title',
-            attrs.icon && m(Icon, {icon: attrs.icon}),
-            m('h2', {id: 'mm-title'}, attrs.title),
+            'header',
+            m(
+              '.modal-title',
+              attrs.icon && m(Icon, {icon: attrs.icon}),
+              m('h2', {id: 'mm-title'}, attrs.title),
+            ),
+            m(
+              'button[aria-label=Close Modal]',
+              {onclick: () => closeModal(attrs.key)},
+              m(Icon, {icon: 'close'}),
+            ),
           ),
-          m(
-            'button[aria-label=Close Modal]',
-            {onclick: () => closeModal(attrs.key)},
-            m(Icon, {icon: 'close'}),
-          ),
+          m('main', vnode.children),
+          buttons.length > 0 ? m('footer', buttons) : null,
         ),
-        m('main', vnode.children),
-        buttons.length > 0 ? m('footer', buttons) : null,
-      ),
+      ]),
     );
   }
 
@@ -200,7 +205,7 @@
 // This should be called only by app.ts and nothing else.
 // This generates the modal dialog at the root of the DOM, so it can overlay
 // on top of everything else.
-export function maybeRenderFullscreenModalDialog() {
+export function renderModalOverlay() {
   // We use the generation counter as key to distinguish between: (1) two render
   // passes for the same dialog vs (2) rendering a new dialog that has been
   // created invoking showModal() while another modal dialog was already being
diff --git a/ui/src/widgets/popup.ts b/ui/src/widgets/popup.ts
index f863aed..8c3d113 100644
--- a/ui/src/widgets/popup.ts
+++ b/ui/src/widgets/popup.ts
@@ -181,10 +181,6 @@
         if (closestPopup) {
           return {container: closestPopup};
         }
-        const closestModal = dom.closest('.pf-modal-dialog');
-        if (closestModal) {
-          return {container: closestModal};
-        }
         const closestContainer = dom.closest('.pf-overlay-container');
         if (closestContainer) {
           return {container: closestContainer};
diff --git a/ui/src/widgets/tooltip.ts b/ui/src/widgets/tooltip.ts
index 226e275..90cce06 100644
--- a/ui/src/widgets/tooltip.ts
+++ b/ui/src/widgets/tooltip.ts
@@ -115,10 +115,6 @@
         if (closestPopup) {
           return {container: closestPopup};
         }
-        const closestModal = dom.closest('.pf-overlay-container');
-        if (closestModal) {
-          return {container: closestModal};
-        }
         const closestContainer = dom.closest('.pf-overlay-container');
         if (closestContainer) {
           return {container: closestContainer};