---
title: Layouts
tags: [design-system, layout, ui]
created: 2026-05-23
---

# Layouts

Page-template wrappers in `frontend/src/layouts/`. Each layout encapsulates a header, optional sidebar, content slot, and footer — pages mount inside one and never re-implement chrome.

---

## 1. Layout variants

| Layout | Used for | Header | Sidebar | Footer |
|---|---|---|---|---|
| `auth-centered/` | Sign-in, sign-up, verify, reset-password | Logo only | none | Compact links |
| `auth-split/` | Marketing-leaning auth (sign-up with promo panel) | Logo only | Left visual panel | none |
| `dashboard/` | Every `/dashboard/*` route | Topbar with user menu + notifications + language + settings | Vertical / Mini / Horizontal | none |
| `main/` | Public marketing pages (`shop/`, `post/`, landing) | Marketing nav | none | Full footer |

---

## 2. Dashboard layout

`layouts/dashboard/` is the workhorse. It uses MUI's `LayoutSection` pattern — slots for header, sidebar, main, footer with media-query-aware responsive behavior.

### 2.1 Anatomy

```
┌─────────────────────────────────────────────────────┐
│  TopBar  ─────────────────────────  search  bell ▾ │  ← `header-section`
├─────────┬───────────────────────────────────────────┤
│  Nav    │  Breadcrumbs                              │
│         │  ┌─ Page content (mounted route) ──────┐  │
│  ┌───┐  │  │                                      │  │
│  │ ○ │  │  │                                      │  │
│  └───┘  │  │                                      │  │
│  user   │  │                                      │  │
│  profile│  │                                      │  │
├─────────┴───────────────────────────────────────────┤
│  (optional) Footer slot — unused in dashboard       │
└─────────────────────────────────────────────────────┘
```

### 2.2 Sidebar variants

User can switch via the **Settings Drawer**:

| Variant | Width | Behavior |
|---|---|---|
| `vertical` | 280 px | Default; icon + label, collapsible groups |
| `mini` | 88 px | Icons only; labels in tooltip on hover |
| `horizontal` | full-width below header | Nav as a horizontal menu — main content below |

### 2.3 Topbar

Contains, left-to-right:

- Sidebar toggle button (mobile / mini-mode)
- Logo (mini, shown only when sidebar is collapsed)
- Search (Cmd+K palette) — optional
- Language selector (chip with flag)
- Settings drawer toggle (cog icon)
- Notifications drawer toggle (bell with unread count badge)
- Account dropdown (avatar → profile, sign-out)

### 2.4 Nav configuration

Nav items defined as a tree in a config file (e.g., `layouts/dashboard/config-nav-dashboard.ts`):

```ts
const navData = [
  {
    subheader: 'Overview',
    items: [
      { title: 'Dashboard', path: paths.dashboard.root, icon: ICONS.dashboard },
      { title: 'Chat', path: paths.dashboard.chat, icon: ICONS.chat },
    ],
  },
  {
    subheader: 'Marketplace',
    items: [
      { title: 'Requests', path: paths.dashboard.request.root, icon: ICONS.request,
        roles: ['buyer', 'admin'] },
      { title: 'Templates', path: paths.dashboard.template.root, icon: ICONS.template,
        roles: ['seller', 'admin'] },
      // ...
    ],
  },
  // ...
];
```

Each `items[i]` may carry `roles: string[]` to scope visibility. The nav renderer filters items based on the current user's role before rendering — entries without `roles` are shown to everyone.

### 2.5 Breadcrumbs

`components/custom-breadcrumbs` renders the active route trail plus an optional action button slot (e.g., "+ New Request"). Convention: set via the page component.

---

## 3. Auth layouts

### 3.1 `auth-centered/`

Single column, centered card. Used by sign-in, password reset, email verification.

```
┌──────────────────────────────┐
│           Logo               │
│                              │
│   ┌────────────────────┐    │
│   │  Title             │    │
│   │  Form fields...    │    │
│   │  CTA               │    │
│   └────────────────────┘    │
│                              │
│   Tiny footer links          │
└──────────────────────────────┘
```

### 3.2 `auth-split/`

Two-column on `md+`, single column on small screens. Left = visual / brand panel; right = form.

```
┌──────────────┬───────────────┐
│              │  Logo         │
│   Visual     │               │
│   panel      │   Form        │
│   (image,    │               │
│    quote,    │   CTA         │
│    benefit)  │               │
│              │   Footer      │
└──────────────┴───────────────┘
```

Used for sign-up to balance marketing copy with the form.

---

## 4. Main (public) layout

`layouts/main/` is for unauthenticated visitor pages. Sticky header, then content, then full footer.

Header includes:

- Logo
- Top-level nav (Shop, Blog, About)
- Language switcher
- "Sign in" / "Sign up" buttons (or "Dashboard" if signed in)

Footer includes:

- Brand block
- Sitemap
- Legal links
- Social media
- Newsletter signup (optional)

---

## 5. Responsive behavior

| Breakpoint | xs (<600) | sm (≥600) | md (≥900) | lg (≥1200) | xl (≥1536) |
|---|---|---|---|---|---|
| Dashboard sidebar | drawer overlay | drawer overlay | mini default | full default | full default |
| Auth-split | single col | single col | two col | two col | two col |
| Main nav | hamburger | hamburger | inline | inline | inline |
| Page padding | 16 px | 16 px | 24 px | 32 px | 32 px |

Implementation note: do NOT add `@media` rules in components. Use the responsive `sx` syntax:

```tsx
<Box sx={{ p: { xs: 2, md: 3, lg: 4 } }} />
```

---

## 6. Sticky elements

- TopBar uses `position: sticky; top: 0; z-index: appBar` so it stays on scroll.
- Action bars on long forms can use the same pattern at bottom (`bottom: 0`).

---

## 7. Skeleton & loading

- Each `dashboard/*/page.tsx` can ship a sibling `loading.tsx` that renders skeleton placeholders matching the final layout.
- For long-loading sections, use `<Suspense fallback={<SkeletonX />}>`.

---

## 8. Error boundaries

- App-level error boundary at root layout catches uncaught render errors.
- Each route segment may ship `error.tsx` for scoped recovery (e.g., `dashboard/shops/error.tsx`).
- Snackbars handle non-fatal API errors.

---

## 9. Adding a new layout

1. Create `layouts/<name>/` with `index.tsx` (default export the layout component).
2. Slot pattern: accept `children`; render header + nav + main + (optional) footer.
3. Reuse `components/scrollbar` for the main scroll area to keep custom scrollbar styling.
4. If it's an auth flow, wire it into `app/auth/<flow>/layout.tsx`.

---

## 10. Related

- [[Design System Overview]] · [[Theme Configuration]] · [[Components]]
- [[Frontend Architecture]] — where layouts sit in the tree
- [[Roles & Personas]] — role-driven nav filtering
- [[Settings & Theming]] — layout variant switcher
