Loading page…
Loading page…
Every client app inherits one non-visual shell boundary and one portal destination for transient UI. The design system owns that geometry; each app still owns its own toast queue, dialog state, and application services.
AppShellRoot establishes the shell stacking context and mounts data-slot='app-notification-layer'. It does not create a toast, dialog, query, authentication, or application-state provider.
import { AppShellRoot, ToastProvider } from "@coldharbor/ui";
import { ClientDialogProvider } from "@/providers/client-dialog-provider";
<AppShellRoot data-brand="titan">
<ToastProvider>
<ClientDialogProvider>{children}</ClientDialogProvider>
</ToastProvider>
</AppShellRoot>--ch-layer-chrome--ch-layer-popup--ch-layer-toastShared toasts, dialogs, sheets, drawers, popovers, menus, selects, tooltips, command palettes, and motion overlays all resolve the notification layer. Their state remains independent; only their DOM destination and stacking boundary are shared.
<div data-slot="app-shell-root">
{/* app chrome and routed content */}
<div data-slot="app-notification-layer" />
</div>UniversalAppShell already includes AppShellRoot, so wallet-style and sidebar-shell consumers inherit the portal layer automatically. Custom shells mount AppShellRoot once around their app-owned providers, as Treasury does.
<UniversalAppShell
appName="Wallet"
title="Portfolio"
navigation={navigation}
>
{children}
</UniversalAppShell>