# Layout

> Frame’s layout system: the three-panel shell and its parts — PageLayout, HeaderBar, SplitView, side panels, SideCard, ShellGlow and ResizeHandle.

Web page: https://system.beibeidesign.com/layout/

How a whole screen is assembled, and the parts it is assembled from — every surface plugs into one three-panel shell, and each part below carries its spec and a live demo in the same place. Single source: `content/layoutTemplates.tsx`.

### App Shell — Three-Panel Structure

App.tsx

Every WorkPal view composes into a single three-panel shell: **NavPanel** (global navigation), **ConversationPanel** (primary working surface), and **InspectorPanel** (contextual detail). Foundations tokens flow through all three; edit a color once and every panel updates.

NavPanel

260 / 64 px

ConversationPanel

flex-1

InspectorPanel

280 / 504 px

NavPanel 260 / 64 px

Global navigation, view switching, recents, profile

`Sidebar``MiniSidebar`

```
Sidebar · 260px (drag 220–400) · sidebar-bg
MiniSidebar · 64px · collapsed
```

ConversationPanel flex-1

The user’s primary working surface — chat, page content, forms

`ChatPanel``PageLayout (+ any page)`

```
flex-1 · centered content max-w-[863px]
```

InspectorPanel 280 / 504 px

Contextual detail to the right: document, task context, side cards

`DetailPanel``TaskContextPanel``SplitView side`

```
DetailPanel · 504px
TaskContextPanel · 280px
Overlays on narrow viewports
```

**Rule:** a new feature is a *slot* in one of these three panels — never a new top-level chrome element. If you need a new panel primitive, build it in `shared.tsx` and register it under the relevant panel here.

### PageLayout

Master Used in: Wingman 26 · WorkPal 15

Page shell — pinned single-row header (toggle + title + rightSlot/actions) that the filters + body scroll beneath (frosted, like the header on this site) + optional pinned footer. Wraps HeaderBar internally.

#### Library

[field: Search]

Search

All 12 Documents 5 Tasks 7

PageLayout owns the title + filters + scrollable body. Pass a `footer` for a pinned ChatInput.

Demo content row.

Demo content row.

Demo content row.

Demo content row.

Demo content row.

Demo content row.

Demo content row.

Demo content row.

#### Spec

shared.tsx

Canonical page shell. A **pinned single-row header** (sidebar toggle · title · flexible gap · `rightSlot` search/actions · onNewChat · headerRight · onBack) stays pinned at the top as a frosted layer while the body scrolls beneath it, and an optional footer stays pinned to the bottom. The title lives on the pinned row and is `truncate`d to one line — pass a short label, not prose. Edit the spec in `shared.tsx` once — every page updates.

**Pinned header row:** `px-4 sm:px-8 · pt-6 pb-3 · title inline (truncated) · .frosted-header`

**Horizontal pad:** `px-4 sm:px-8`

**Header → body:** `header pb-3 + body pt-3`

**filters → content:** `mb-8`

**maxWidth 'full':** no limit

**maxWidth 'reading':** 863px centered

**maxWidth 'wide':** 1040px centered

Used by · WorkPal

OverviewPage LibraryPage ConnectorsPage DesignSystemPage Onboarding ProjectPage ComingSoonPage

Used by · Wingman

AboutPage AdminObservabilityPage AgentConfirmPage AgentVoicePreviewPage ChatPage CheckoutCompletePage CheckoutPage DateArrangePage DateDetailPage DatesPage DesignSystemPage MatchDetailPage MatchesPage NotFoundPage PrivacySettingsPage ProfilePhotosPage SSOCallbackPage SelfSnapshotPage SettingsPage SignInPage SignUpPage TokenSettingsPage VideoFeedbackPage VideoInvitePage VideoRoomPage

### HeaderBar

Master Used in: Wingman 6 · WorkPal 2

Canonical top toolbar. Sidebar toggle (when closed) + optional left/right slots. Used by every top-level shell.

Toggle sidebar Project · Wingman

Open panel

Page content lives below the header.

#### Spec

shared.tsx

The pinned top row. Bare — as ChatPanel and the Wingman chat/quiz shells use it — it's just the sidebar-toggle button (only when the sidebar is closed) + optional left/right slots. DS-029: the toggle glyph is not fixed; each product supplies it through `NavToggleIconProvider` (WorkPal shows a panel-left icon, Wingman a hamburger). DS-080: PageLayout renders through HeaderBar, passing `title` / `rightSlot` / `widthClass` / `padX` so the page title sits inline on the pinned row; bare consumers pass none of these and render exactly the toolbar they always did.

**Props:** `sidebarOpen`, `onToggleSidebar`, `headerRight`, `title`, `titleAs`, `rightSlot`, `widthClass`, `padX`

Used by · WorkPal

ChatPanel

Used by · Wingman

ChatPage ChatsPage DesignSystemPage OnboardingPage QuizChatPage QuizPage SelfTestChatPage

### SplitView

Master Used in: Wingman 0 · WorkPal 4

Two-column shell that flips inline ↔ overlay based on container width (ResizeObserver, not viewport). Used by ProjectPage, ChatPanel + DetailPanel, TaskContextPanel.

#### Main column

Resize this card horizontally to see the panel collapse to overlay.

Side panel

Close

About

SplitView decides inline ↔ overlay based on container width.

#### Spec

shared.tsx

Main column + collapsible side column. Auto-switches to overlay mode when the CONTAINER is too narrow to fit both inline — DS-029: this used to say "viewport". It is measured with a ResizeObserver on SplitView's own element, which is deliberately agnostic of viewport size, sidebar width and collapsed state.

**Props:** `side`, `sideOpen`, `onCloseSide`, `sideWidth`, `mainMinWidth`

Used by · WorkPal

ProjectPage LibraryPage (detail panel)

Used by · Wingman

DesignSystemPage (showcase)

### SidePanelHeader

Master Used in: Wingman 0 · WorkPal 5

Canonical header row for a side panel. Title + optional children + close button (X or panel-right collapse icon).

Inspector

Close

Collapsible

Close

#### Spec

shared.tsx

Shared header row for any side panel. Unifies close-button size (40px rounded-xl), hover, and typography across every panel.

**Props:** `title`, `onClose`, `closeIcon` ('x' | 'panel-right'), `closeLabel`

Used by · WorkPal

ProjectPage side panel TaskContextPanel DetailPanel

Used by · Wingman

DesignSystemPage (showcase)

### SidePanelBody

Master Used in: Wingman 0 · WorkPal 3

Scrollable conversation inspector body with spacing and an automatic scrollbar.

Install component Copy code [View source](https://github.com/BeibeiZhang/frame-design-system/blob/main/components/side-panel-body.tsx)

Requires React 19, ReactDOM 19, TypeScript and lucide-react 1.14.0. Import frame.css once and use a frame-root wrapper; set its background to var(--color-bg-page) and color to var(--color-text-primary), or supply a matching host surface; add dark to an ancestor for dark mode.

Tested with shadcn 4.21.0, React 19.2.5, Vite 8.0.10 and Tailwind 3.4.19 / 4.3.3. Start with a configured React/Vite shadcn app. Files install into src/components/frame; import its frame.css. For manual copy, save the complete component and stylesheet below. Examples leave optional voice features off; retain the MIT license and third-party notices.

[Required stylesheet: frame.css](https://github.com/BeibeiZhang/frame-design-system/blob/main/styles/frame.css)

```
npx shadcn@4.21.0 add https://raw.githubusercontent.com/BeibeiZhang/frame-design-system/main/registry/side-panel-body.json
```

Copy install command Close

Scrollable body container — pairs with SidePanelHeader. Holds a vertical stack of SideCards.

Side panel

Close

Files

notes.md · 4 KB

Context

#### Spec

shared.tsx

Scrollable body that pairs with `SidePanelHeader` and holds a vertical stack of `SideCard`s. Single source of truth for right-panel L/R padding (px-3) and inter-card gap (gap-4) — switching between project view and task view no longer shifts content horizontally.

**Props:** `children`. Padding / gap are intentionally not configurable — that's the point.

Used by · WorkPal

ProjectPage side panel TaskContextPanel

Used by · Wingman

No pages yet

### SideCard

Master Used in: Wingman 0 · WorkPal 6

Collapsible section inside a right-column side panel — no panel fill, border or radius; sections are separated by a fading 1px rule. Pairs with SidePanelHeader / SidePanelBody.

Instructions

Pre-fetch the user's calendar and reference last week's meeting notes.

Files

#### Spec

shared.tsx

Collapsible section inside a right-column side panel. DS-029: this used to say "card" — it has no panel fill, no border and no radius; sections are separated by a 1px rule along the bottom edge that fades out at both ends (`side-card-divider`, with `last:bg-none` on the final one). Header with title + optional icon + optional add affordance + chevron.

**Props:** `title`, `icon`, `hasAdd`, `defaultOpen`

Used by · WorkPal

ProjectPage (Instructions/Scheduled/Files/Context) TaskContextPanel

Used by · Wingman

DesignSystemPage (showcase)

### ShellGlow

Master Used in: Wingman 1 · WorkPal 1

Dark-mode background glow: one rotating field carrying all three color gradients, turning together around the screen center — never changing brightness, color or size. Mount once per app root — never per `.app-shell-bg` surface — so every dark-mode shell shares one animation clock instead of a second instance rotating out of phase.

Purple · `--shell-glow-purple`

25%

Orange · `--shell-glow-orange`

30%

Blue · `--shell-glow-blue`

20%

% is today's brightness — a ceiling that never changes. The three glows keep their positions relative to each other and rotate together as one field around the screen center, 60 seconds per full turn, clockwise, at a constant speed. prefers-reduced-motion freezes the field at today's rest position (0° = 360°, so the freeze frame is never mid-turn).

### ResizeHandle

Master Used in: Wingman 1 · WorkPal 2

User-draggable column width (useResizableWidth + ResizeHandle). The products' NavPanel defaults to 260px, drags 220–400px and is remembered per product; this demo uses a smaller range. Drag the right edge, or focus it and use ←/→, Home/End; Enter or double-click resets.

Navigation

160px

Main content
