# Frontend Layout Tree {#frontend-layout-tree}



## Overview {#overview}


The MQUAD frontend uses a **single vertical scroll ownership** architecture. Each page type has exactly one scroll container to prevent nested scrolling conflicts and ensure predictable behavior across zoom levels and display scaling.


## Root Entry Point {#root-entry-point}


```
src/main.tsx
  └── src/App.tsx
        └── Routes (react-router)
              ├── Public Routes
              │     └── DefaultLayout
              │           └── <Outlet />
              └── Protected Routes
                    └── DashboardLayout  ← PRIMARY SCROLL OWNER
                          └── <Outlet /> (all dashboard pages)
```


## Layout Structure {#layout-structure}



### Default Layout (Public Pages) {#default-layout-public-pages}


```tsx
// File: src/components/layouts/default-layout.tsx
<div className="flex flex-col min-h-screen bg-primary-foreground">
  <header className="p-4 bg-secondary border-b">
  <main id="main-content" className="flex-1">  ← No scroll owner
  <Footer />
</div>
```

- Used for: Login, Landing pages, Public content
- Scroll behavior: Inherits from viewport (no internal scrolling)
- Key pattern: `min-h-screen` (not `h-screen`) for safe scaling


### Dashboard Layout (Protected Pages) {#dashboard-layout-protected-pages}


```tsx
// File: src/components/layouts/dashboard-layout.tsx
<SidebarProvider>  ← Uses min-h-svh internally
  <DashboardSidebar />
  <main className="sm:w-full flex flex-col">  ← Row container only
    <div className="flex flex-col w-full z-50">  ← Header bar (sticky)
      <SidebarTrigger />
      <DarkMode />
    </div>
    <section className="w-full flex-1 flex flex-col min-h-0 overflow-auto">  ← PRIMARY SCROLL OWNER
      <Banner />
      <div className="flex-1 flex-col min-h-0">  ← Inner flex container
        <header className="flex items-center p-2 mx-5">
        <section className="pt-10 flex-1">
          <div className="p-2">
            <Outlet />  ← All dashboard pages render here
          </div>
        </section>
      </div>
      <SimpleFooter />
    </section>
  </main>
</SidebarProvider>
```

| Element | Classes | Role | Scroll Ownership |
|---------|---------|------|------------------|
| SidebarProvider | - | Sidebar context | None (w/ `min-h-svh`) |
| `main` | `sm:w-full flex flex-col` | Row container | **None** |
| `div.z-50` | `flex flex-col w-full` | Sticky header | **None** |
| `section` (line 154) | `w-full flex-1 flex flex-col min-h-0 overflow-auto` | Content area | **OWNER** |
| `div` (line 156) | `flex-1 flex-col min-h-0` | Inner wrapper | **None** (supports parent) |


## Scroll Ownership Rules {#scroll-ownership-rules}


1. **One scroll owner per page type** — Only `section` at line 154 has `overflow-auto`
2. **Inner containers need `min-h-0`** — Allows flex scrolling to propagate
3. **Loading states use `min-h-screen`** — Safer than `h-screen` at Windows scaling >100%
4. **Dialog/Sheet content are independent** — They have their own scroll containers (do not modify)


## Contained Scroll Areas {#contained-scroll-areas}


These components use `overflow-auto` with explicit height constraints — **NOT** page-level scroll owners:

| Component | File | Pattern |
|-----------|------|---------|
| ScrollArea | `src/components/ui/scroll-area.tsx` | Radix UI scroll area |
| DialogContent | Various dialog files | `max-h-[80vh] overflow-y-auto` |
| SheetContent | Various sheet files | `overflow-y-auto` |
| Response tables | `src/components/shared/advance-table.tsx` | Virtualized scrolling |


## Key Files {#key-files}


| File | Purpose |
|------|---------|
| `src/components/layouts/dashboard-layout.tsx` | Primary scroll owner for dashboard |
| `src/components/layouts/default-layout.tsx` | Public pages layout |
| `src/components/layouts/dashboard-sidebar-layout.tsx` | Sidebar navigation |
| `src/components/ui/sidebar.tsx` | Sidebar component (uses `min-h-svh`) |


## Testing Scroll Behavior {#testing-scroll-behavior}


Test at these settings to verify proper scroll behavior:

| Platform Setting | Expected Behavior |
|------------------|-------------------|
| Windows scaling: 100% | Scroll works normally |
| Windows scaling: 125% | Scroll area calculates correctly |
| Windows scaling: 150% | Content not clipped |
| Windows scaling: 175% | Full content accessible |
| Browser zoom: 80% | Scroll boundary correct |
| Browser zoom: 200% | Scroll wheel works smoothly |


## Common Issues & Fixes {#common-issues--fixes}


| Issue | Cause | Fix |
|-------|-------|-----|
| Content clipped at 125% scaling | `h-screen` is smaller than scaled viewport | Use `min-h-screen` |
| Nested scrollbars | Multiple elements with `overflow-auto` | Remove duplicate scroll owners |
| Scroll not working | Missing `min-h-0` on flex children | Add `min-h-0` to support flex scrolling |
