Add z-index scale and overview redirect

Introduce a v2 z-1…z-6 stacking scale so portaled
menus sit above in-page media, and redirect the
legacy /overview trust-app URL to home.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-07-20 18:58:12 +02:00
parent 2db37660d3
commit 311639ae98
17 changed files with 117 additions and 19 deletions

View File

@@ -26,12 +26,12 @@ import { tv } from "tailwind-variants/lite";
export const dialog = tv({
slots: {
backdrop: [
"fixed inset-0 z-50 bg-sand-12/40",
"fixed inset-0 z-4 bg-sand-12/40",
"transition-opacity duration-150",
"data-starting-style:opacity-0 data-ending-style:opacity-0",
],
popup: [
"fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2",
"fixed left-1/2 top-1/2 z-5 -translate-x-1/2 -translate-y-1/2",
"flex w-[calc(100vw-2rem)] max-w-[600px] flex-col gap-4",
"max-h-[calc(100vh-2rem)] overflow-y-auto overflow-x-clip",
"rounded-5 border border-sand-6 bg-sand-1 py-6 shadow-6 outline-none",

View File

@@ -25,11 +25,11 @@ import { tv } from "tailwind-variants/lite";
export const drawer = tv({
slots: {
backdrop: [
"fixed inset-0 z-50 bg-sand-12/40",
"fixed inset-0 z-4 bg-sand-12/40",
"transition-opacity duration-200",
"data-starting-style:opacity-0 data-ending-style:opacity-0",
],
viewport: "fixed inset-0 z-50 flex",
viewport: "fixed inset-0 z-5 flex",
popup: [
"relative flex flex-col bg-sand-1 shadow-6 outline-none",
"transition-transform duration-200",

View File

@@ -49,7 +49,8 @@ export function DropdownPopup(props: DropdownPopupProps) {
return (
<Menu.Portal>
<Menu.Positioner side={side} align={align} sideOffset={sideOffset}>
{/* z-3 on the Positioner so the portaled root wins over in-page z-1. */}
<Menu.Positioner className="z-3" side={side} align={align} sideOffset={sideOffset}>
<Menu.Popup className={dropdownPopup({ className })} {...popupProps}>
<DropdownProvider value={{ size, variant, highContrast }}>
{children}

View File

@@ -43,7 +43,8 @@ export function SelectPopup(props: SelectPopupProps) {
return (
<BaseSelect.Portal>
<BaseSelect.Positioner side={side} align={align} sideOffset={sideOffset}>
{/* z-3 on the Positioner so the portaled root wins over in-page z-1. */}
<BaseSelect.Positioner className="z-3" side={side} align={align} sideOffset={sideOffset}>
<BaseSelect.Popup className={selectPopup({ className })} {...popupProps}>
{children}
</BaseSelect.Popup>

View File

@@ -27,7 +27,7 @@ import { tv } from "tailwind-variants/lite";
export const toaster = tv({
slots: {
viewport: [
"fixed bottom-0 right-0 z-60 flex w-[380px] max-w-[calc(100vw-2rem)] flex-col gap-2 p-4",
"fixed bottom-0 right-0 z-6 flex w-[380px] max-w-[calc(100vw-2rem)] flex-col gap-2 p-4",
"outline-none",
],
root: [

View File

@@ -30,6 +30,7 @@
* typography.css Inter font + type scale (text-1…9) + font weights
* radius.css radius scale (rounded-1…6)
* shadows.css elevation scale (shadow-1…6)
* z-index.css stacking scale (z-1…6) by UI layer
*
* Spacing intentionally stays on Tailwind's native scale (not tokenized).
* See contrib/claude/v2-tokens.md for the full usage guide.
@@ -38,3 +39,4 @@
@import "./theme/typography.css";
@import "./theme/radius.css";
@import "./theme/shadows.css";
@import "./theme/z-index.css";

View File

@@ -0,0 +1,56 @@
/* Copyright (c) 2026 Probo Inc <hello@probo.com>.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* ---------------------------------------------------------------------------
* Z-index — stacking scale by UI layer (steps 1–6)
*
* Numbered like color / type / radius / shadow. Each step is a layer role, not
* an arbitrary elevation. Values are spaced so a future mid-layer can land
* between them without renumbering consumers.
*
* Step value Role
* ───── ────── ────────────────────────────────────────────────────────
* 1 1 Local stacking inside a component (media over backdrop)
* 2 10 Sticky / fixed page chrome (top bars, sticky toolbars)
* 3 30 Floating menus (select, dropdown, tooltip, popover)
* 4 40 Overlay backdrops (dimmers under modals / drawers)
* 5 50 Modals and drawers
* 6 60 Toasts / global notifications (always on top)
*
* Put the token on the portaled root that participates in the document
* stacking context (e.g. the Positioner for menus, not only the inner Popup).
* A local z-1 inside the page will otherwise paint above a portaled popup
* that has no z-index of its own.
*
* --z-index-* is reset to initial so the v2 build exposes only this numeric
* scale (not Tailwind's z-10 / z-20 / … defaults). z-auto stays available as
* a static utility.
* ------------------------------------------------------------------------- */
@theme {
--z-index-*: initial;
--z-index-1: 1;
--z-index-2: 10;
--z-index-3: 30;
--z-index-4: 40;
--z-index-5: 50;
--z-index-6: 60;
}