> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Spacing & UX Standards

> Version: 1.1.0 Last Updated: 2026-04-08 Status: Active

**Version:** 1.1.0\
**Last Updated:** 2026-04-08\
**Status:** Active

> **UI/UX Guide:** For full UI/UX standards including design system, page templates, navigation, and accessibility, see [UI\_UX\_STANDARDS.md](UI_UX_STANDARDS.md).
> **Scope:** This file is spacing/layout specific; keep broad UI policy in `UI_UX_STANDARDS.md` to avoid duplication.

This document consolidates spacing and UX standards from previous review documents to provide a single source of truth for spacing patterns, responsive design, and UX consistency across the Encore Health OS platform.

***

## Quick Reference

### Standard Spacing Scale

```tsx theme={null}
// Mobile → Tablet → Desktop
xs:  8px  (0.5rem)  - Tight spacing (icons, badges)
sm:  12px (0.75rem) - Compact spacing (form fields)
md:  16px (1rem)    - Standard spacing (cards, sections)
lg:  24px (1.5rem)  - Large spacing (sections, groups)
xl:  32px (2rem)    - Extra large (major sections)
2xl: 48px (3rem)    - Page-level spacing
```

### Common Patterns

**Page Container:**

```tsx theme={null}
<PageContainer spacing="md">{children}</PageContainer>
```

**Vertical Spacing:**

```tsx theme={null}
<div className="space-y-4 md:space-y-6">{items}</div>
```

**Grid Spacing:**

```tsx theme={null}
<div className="grid gap-3 md:gap-4 lg:gap-6 md:grid-cols-2">{items}</div>
```

**Form Spacing:**

```tsx theme={null}
<form className="space-y-4 md:space-y-6">{fields}</form>
```

**Card Padding:**

```tsx theme={null}
<Card className="p-4 md:p-6">{content}</Card>
```

### Helper Components

* **PageContainer** - Consistent responsive page-level padding
* **ResponsiveFormLayout** - Responsive column layouts for forms
* **MobileTableWrapper** - Horizontal scroll wrapper for wide tables

### Best Practices

1. ✅ Always use responsive spacing - `space-y-4 md:space-y-6`
2. ✅ Use PageContainer - Don't manually add container padding
3. ✅ Consistent grid gaps - `gap-3 md:gap-4 lg:gap-6`
4. ✅ Mobile-first - Start with mobile spacing, scale up
5. ❌ Avoid fixed padding on all screen sizes
6. ❌ Avoid double padding (container + explicit)
7. ❌ Avoid inconsistent spacing patterns

**For detailed patterns and examples, see sections below.**

***

## Table of Contents

### Core Patterns

* [Page Container Pattern](#page-container-pattern)
* [Sidebar Adaptive Layout](#sidebar-adaptive-layout)
* [Container Padding Standards](#container-padding-standards)

### Dialog & Sheet Sizes

* [Dialog Size Tiers](#dialog-size-tiers)
* [Sheet Size Tiers](#sheet-size-tiers)
* [Dialog/Sheet Decision Guide](#dialogsheet-decision-guide)

### Spacing Guidelines

* [Vertical Spacing](#vertical-spacing)
* [Card Padding](#card-padding)
* [Mobile-First Considerations](#mobile-first-considerations)
* [Grid Layouts](#grid-layouts)
* [Form Spacing](#form-spacing)
* [Table Spacing](#table-spacing)

### Component Patterns

* [Section Headers](#section-headers)
* [Page Header Pattern](#page-header-pattern)
* [Stats Bar Pattern](#stats-bar-pattern)
* [Content Grid Pattern](#content-grid-pattern)

### Dialog & Sheet Sizing

* [Dialog Size Tiers](#dialog-size-tiers)
* [Sheet Size Tiers](#sheet-size-tiers)
* [Dialog Sizing Rules](#dialog-sizing-rules)

### Migration & Reference

* [Migration Checklist](#migration-checklist)
* [Review History](#review-history)
* [Related Documents](#related-documents)

***

## Dialog Size Tiers

> **Full Reference:** See `.cursor/rules/dialog-size-standards.md` for complete standards and decision guide.\
> **Audit:** See `docs/development/UI_CONSISTENCY_REVIEW.md` for the full UI consistency audit.

### Standard Dialog Sizes

| Tier    | Class          | Width | Use Case                                                                |
| ------- | -------------- | ----- | ----------------------------------------------------------------------- |
| Small   | `sm:max-w-md`  | 448px | Confirmations, simple forms (1-3 fields), quick actions, export options |
| Medium  | `sm:max-w-lg`  | 512px | Standard forms (4-8 fields), settings panels, single-section content    |
| Large   | `sm:max-w-2xl` | 672px | Complex forms, multi-section dialogs, forms with tables, email compose  |
| X-Large | `sm:max-w-3xl` | 768px | Large tables, comparison views, wizards, version history                |
| Full    | `sm:max-w-4xl` | 896px | Document previews, code editors, full-width content, bulk operations    |

### Standard Sheet Sizes

| Tier    | Class          | Width          | Use Case                                    |
| ------- | -------------- | -------------- | ------------------------------------------- |
| Default | (no override)  | 75% / sm:384px | Quick panels, navigation, simple content    |
| Medium  | `sm:max-w-md`  | 448px          | Chat panels, variable editors, AI assistant |
| Large   | `sm:max-w-lg`  | 512px          | Form panels, settings, approval workflows   |
| X-Large | `sm:max-w-xl`  | 576px          | Complex editors, test scenario editors      |
| Wide    | `sm:max-w-2xl` | 672px          | Wide previews, wizard previews              |

### Dialog Sizing Rules

1. **ALWAYS** include `sm:` responsive prefix
2. **NEVER** use arbitrary pixel values (`[425px]`, `[500px]`, etc.)
3. **NEVER** add `overflow-y-auto` to `DialogContent` (base handles it)
4. **NEVER** add `max-h-*` to `DialogContent` (base provides `sm:max-h-[85vh]`)

```tsx theme={null}
// ✅ CORRECT
<DialogContent className="sm:max-w-lg">

// ❌ WRONG
<DialogContent className="max-w-lg">                     // missing sm: prefix
<DialogContent className="sm:max-w-[500px]">              // arbitrary pixels
<DialogContent className="sm:max-w-lg max-h-[90vh] overflow-y-auto"> // redundant
```

***

## Page Container Pattern

### Standard Implementation

```tsx theme={null}
import { PageContainer } from '@/shared/components/PageContainer';

// Standard page
<PageContainer spacing="md">
  {/* Content */}
</PageContainer>

// Compact page
<PageContainer spacing="sm">
  {/* Content */}
</PageContainer>

// Spacious page
<PageContainer spacing="lg">
  {/* Content */}
</PageContainer>
```

### Responsive Padding

**Recommended Pattern:**

* Mobile: `16px` (py-4 px-4)
* Tablet: `24px` (md:py-6 md:px-6)
* Desktop: `32px` (lg:py-8 lg:px-8)

**Avoid:**

* ❌ Fixed padding on all screen sizes
* ❌ Double padding (container + explicit padding)
* ❌ Container default padding (32px) on mobile

## Overview Page Wrapper Pattern

### When to Use

Use `OverviewPageWrapper` for:

* Module landing pages (e.g., `/hr`, `/rh`, `/fa`)
* Any page that needs pull-to-refresh with query invalidation
* Pages following the standard overview structure

### Standard Implementation

```tsx theme={null}
import { OverviewPageWrapper } from '@/shared/components';

<OverviewPageWrapper 
  refreshQueryKeys={['hr']} 
  spacing="md"
>
  {/* Page content */}
</OverviewPageWrapper>
```

### Props Reference

| Prop                   | Type                    | Default  | Description                         |
| ---------------------- | ----------------------- | -------- | ----------------------------------- |
| `refreshQueryKeys`     | `string[]`              | Required | Query keys to invalidate on refresh |
| `spacing`              | `'sm' \| 'md' \| 'lg'`  | `'md'`   | Vertical spacing between sections   |
| `maxWidth`             | `'sm' \| ... \| 'full'` | `'7xl'`  | Maximum content width               |
| `onRefresh`            | `() => Promise<void>`   | -        | Additional refresh handler          |
| `disablePullToRefresh` | `boolean`               | `false`  | Disable PTR (rare use)              |

***

## Sidebar Adaptive Layout

### Critical Requirement: Content Expansion

**Problem:** Content must expand when sidebar collapses to utilize available space.

**Sidebar Dimensions:**

* Expanded: `16rem` (256px)
* Collapsed: `3rem` (48px)
* Available space when collapsed: +208px

**Solution Pattern:**

```tsx theme={null}
// ✅ CORRECT: Use flex-1 and responsive container
<div className="flex-1">
  <PageContainer className="w-full max-w-none">
    {/* Content adapts to available space */}
  </PageContainer>
</div>

// ❌ WRONG: Fixed max-width doesn't adapt
<div className="container mx-auto max-w-7xl">
  {/* Content stays same width regardless of sidebar */}
</div>
```

### Implementation Guidelines

1. **Use `flex-1`** on content container to fill available space
2. **Remove fixed max-width** or use responsive max-width
3. **Use `w-full`** to ensure content uses full available width
4. **Test sidebar collapse** to verify content expansion

***

## Container Padding Standards

### Standard Patterns

**Pattern 1: Responsive Padding (Recommended)**

```tsx theme={null}
<div className="p-4 md:p-6 lg:p-8">
  {/* Content */}
</div>
```

**Pattern 2: Horizontal + Vertical Separate**

```tsx theme={null}
<div className="py-6 px-4 md:px-6 lg:px-8">
  {/* Content */}
</div>
```

**Pattern 3: PageContainer Component (Preferred)**

```tsx theme={null}
<PageContainer spacing="md">
  {/* Content */}
</PageContainer>
```

### Anti-Patterns to Avoid

**❌ Double Padding:**

```tsx theme={null}
// WRONG: Container already has 2rem padding
<div className="container mx-auto p-6">
```

**❌ Fixed Padding on Mobile:**

```tsx theme={null}
// WRONG: Too large for mobile
<div className="p-8">
```

**❌ Inconsistent Patterns:**

```tsx theme={null}
// WRONG: Mix of patterns in same codebase
<div className="p-4">  // Some places
<div className="p-6">  // Other places
<div className="container mx-auto">  // Yet others
```

***

## Vertical Spacing

### Standard Patterns

**Between Sections:**

```tsx theme={null}
<div className="space-y-6">
  <Section1 />
  <Section2 />
  <Section3 />
</div>
```

**Between Cards:**

```tsx theme={null}
<div className="grid gap-4 md:gap-6">
  <Card />
  <Card />
</div>
```

**Responsive Spacing:**

```tsx theme={null}
<div className="space-y-4 md:space-y-6 lg:space-y-8">
  {/* Content */}
</div>
```

### Guidelines

* Use `space-y-*` for vertical spacing between children
* Use `gap-*` for grid/flex layouts
* Scale spacing responsively: smaller on mobile, larger on desktop
* Maintain consistent spacing scale (4, 6, 8, not 4, 5, 7)

***

## Card Padding

### Standard Patterns

**Responsive Card Padding:**

```tsx theme={null}
<Card className="p-4 md:p-6">
  {/* Card content */}
</Card>
```

**Guidelines:**

* Mobile: `p-4` (16px) - Prevents cramped cards
* Tablet+: `p-6` (24px) - Comfortable spacing
* Avoid `p-6` on mobile (too large)

***

## Dialog Size Tiers

Use **only** these standard tiers for `DialogContent`. Always include the `sm:` prefix.

| Tier    | Class          | Width | Use case                                                                |
| ------- | -------------- | ----- | ----------------------------------------------------------------------- |
| Small   | `sm:max-w-md`  | 448px | Confirmations, simple forms (1–3 fields), quick actions, export options |
| Medium  | `sm:max-w-lg`  | 512px | Standard forms (4–8 fields), settings panels, single-section content    |
| Large   | `sm:max-w-2xl` | 672px | Complex forms, multi-section dialogs, forms with tables, email compose  |
| X-Large | `sm:max-w-3xl` | 768px | Large tables, comparison views, wizards, version history                |
| Full    | `sm:max-w-4xl` | 896px | Document previews, code editors, full-width content, bulk operations    |

Do **not** use arbitrary pixel values (e.g. `max-w-[425px]`). The base dialog already provides `sm:max-h-[85vh]` and overflow; do not add `max-h-*` or `overflow-y-auto` on `DialogContent`.

***

## Sheet Size Tiers

Use **only** these standard tiers for `SheetContent`. Always include the `sm:` prefix.

| Tier    | Class          | Width          | Use case                                    |
| ------- | -------------- | -------------- | ------------------------------------------- |
| Default | (no override)  | 75% / sm:384px | Quick panels, navigation, simple content    |
| Medium  | `sm:max-w-md`  | 448px          | Chat panels, variable editors, AI assistant |
| Large   | `sm:max-w-lg`  | 512px          | Form panels, settings, approval workflows   |
| X-Large | `sm:max-w-xl`  | 576px          | Complex editors, test scenario editors      |
| Wide    | `sm:max-w-2xl` | 672px          | Wide previews, wizard previews              |

***

## Dialog/Sheet Decision Guide

* **Confirmation or 1–5 fields?** → Dialog Small (`sm:max-w-md`) or Sheet Default/Medium
* **Standard form (4–8 fields)?** → Dialog Medium (`sm:max-w-lg`) or Sheet Large
* **Multiple sections or tabs?** → Dialog Large (`sm:max-w-2xl`)
* **Table or comparison view?** → Dialog X-Large (`sm:max-w-3xl`)
* **Document preview or full editor?** → Dialog Full (`sm:max-w-4xl`) or Sheet Wide

**See also:** [.cursor/rules/dialog-size-standards.md](../../.cursor/rules/dialog-size-standards.md) for full rules and examples; `docs/development/index.md` for current migration and review status references.

***

## Mobile-First Considerations

### Touch Targets

* **Minimum:** 44x44px (per `constitution.md §6.7`)
* **Recommended:** 48x48px for primary actions
* **Spacing between targets:** 8px minimum

### Safe Area Insets

```tsx theme={null}
// Fixed navigation with safe area
<div className="fixed bottom-0 pb-safe">
  {/* Navigation */}
</div>
```

### Responsive Breakpoints

```tsx theme={null}
// Standard breakpoints
sm:  640px  // Mobile landscape
md:  768px  // Tablet
lg:  1024px // Desktop
xl:  1280px // Large desktop
2xl: 1536px // Extra large
```

***

## Grid Layouts

### Responsive Grid Patterns

**Standard Grid:**

```tsx theme={null}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6">
  <Card />
  <Card />
  <Card />
</div>
```

**Guidelines:**

* Start with single column on mobile
* Add columns at tablet breakpoint (md:)
* Use consistent gap spacing (4, 6, 8)

***

## Form Spacing

### Standard Patterns

**Form Field Spacing:**

```tsx theme={null}
<div className="space-y-4">
  <FormField />
  <FormField />
  <FormField />
</div>
```

**Form Section Spacing:**

```tsx theme={null}
<div className="space-y-6">
  <FormSection />
  <FormSection />
</div>
```

***

## Table Spacing

### Standard Patterns

**Table Padding:**

```tsx theme={null}
<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Column</TableHead>  {/* h-10 md:h-12, px-3 md:px-4 */}
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>Data</TableCell>  {/* p-3 md:p-4 */}
    </TableRow>
  </TableBody>
</Table>
```

**For Wide Tables on Mobile:**

```tsx theme={null}
import { MobileTableWrapper } from '@/shared/components';

<MobileTableWrapper>
  <Table>
    {/* Wide table content */}
  </Table>
</MobileTableWrapper>
```

**Table Spacing Guidelines:**

* Mobile: `12px` (p-3)
* Desktop: `16px` (md:p-4)
* Header Height: Mobile `40px` (h-10), Desktop `48px` (md:h-12)

## Section Headers

### Standard Patterns

**Standard Section Header:**

```tsx theme={null}
<h2 className="text-xl font-semibold mt-6 mb-3 md:mt-8 md:mb-4">
  Section Title
</h2>
```

**With Description:**

```tsx theme={null}
<div className="mb-4 md:mb-6">
  <h2 className="text-xl font-semibold">Section Title</h2>
  <p className="text-muted-foreground">Section description</p>
</div>
```

## Page Header Pattern

### Standard Implementation

```tsx theme={null}
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 md:gap-4">
  <div>
    <h1 className="text-2xl md:text-3xl font-bold">Page Title</h1>
    <p className="text-muted-foreground">Page description</p>
  </div>
  <Button>Action</Button>
</div>
```

## Stats Bar Pattern

### Standard Implementation

```tsx theme={null}
<div className="grid gap-3 md:gap-4 lg:gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-4">
  {stats.map((stat) => (
    <Card key={stat.id}>
      {/* Stat content */}
    </Card>
  ))}
</div>
```

## Content Grid Pattern

### Standard Implementation

```tsx theme={null}
<div className="grid gap-3 md:gap-4 md:grid-cols-2 lg:grid-cols-3">
  {items.map((item) => (
    <Card key={item.id}>
      {/* Item content */}
    </Card>
  ))}
</div>
```

## Migration Checklist

When updating a page to follow spacing standards:

* [ ] Replace `container mx-auto p-6` with `PageContainer`
* [ ] Replace `space-y-6` with `space-y-4 md:space-y-6`
* [ ] Replace `gap-4`/`gap-6` with `gap-3 md:gap-4 lg:gap-6`
* [ ] Update manual margins to use spacing system
* [ ] Test on mobile (320px), tablet (768px), desktop (1024px+)
* [ ] Verify no horizontal scrolling
* [ ] Verify content doesn't touch edges

## Troubleshooting Common Issues

### Content Touching Screen Edges on Mobile

**Problem:** Content appears to touch the left/right edges on mobile devices.

**Solution:**

```tsx theme={null}
// ❌ WRONG: Missing container padding
<div className="space-y-4">{content}</div>

// ✅ CORRECT: Use PageContainer
<PageContainer spacing="md">{content}</PageContainer>
```

### Inconsistent Spacing Between Breakpoints

**Problem:** Spacing jumps dramatically between mobile and desktop.

**Solution:**

```tsx theme={null}
// ❌ WRONG: Fixed spacing
<div className="space-y-6">{items}</div>

// ✅ CORRECT: Responsive spacing
<div className="space-y-4 md:space-y-6">{items}</div>
```

### Horizontal Scrolling on Mobile

**Problem:** Page scrolls horizontally on mobile devices.

**Solution:**

1. Check for fixed-width elements: Remove `w-{fixed}` classes
2. Use responsive grid: `grid-cols-1 md:grid-cols-2`
3. Check container: Ensure `PageContainer` is used, not manual padding
4. Verify safe areas: Check for elements extending beyond viewport

### Content Overlapping with Sidebar

**Problem:** Content overlaps when sidebar is visible.

**Solution:**

```tsx theme={null}
// ✅ CORRECT: Use sidebar-adaptive layout
<div className="ml-0 md:ml-64">
  <PageContainer spacing="md">{content}</PageContainer>
</div>
```

### Grid Items Too Close Together

**Problem:** Grid items have insufficient spacing.

**Solution:**

```tsx theme={null}
// ❌ WRONG: No gap
<div className="grid grid-cols-2">{items}</div>

// ✅ CORRECT: Responsive gap
<div className="grid gap-3 md:gap-4 lg:gap-6 grid-cols-1 md:grid-cols-2">{items}</div>
```

### Form Fields Too Tight

**Problem:** Form fields appear cramped.

**Solution:**

```tsx theme={null}
// ❌ WRONG: Tight spacing
<form className="space-y-2">{fields}</form>

// ✅ CORRECT: Standard form spacing
<form className="space-y-4 md:space-y-6">{fields}</form>
```

### Cards Have Inconsistent Padding

**Problem:** Some cards have different padding than others.

**Solution:**

```tsx theme={null}
// ❌ WRONG: Inconsistent padding
<Card className="p-4">Content</Card>
<Card className="p-6">Content</Card>

// ✅ CORRECT: Standard card padding
<Card className="p-4 md:p-6">Content</Card>
```

***

## Review History

This document consolidates content from:

* This document consolidates content from `SPACING_AND_SIDEBAR_ADAPTIVE_REVIEW.md` (archived 2025-12-08)
* This document consolidates content from `SPACING_AND_UX_REVIEW.md` (archived 2025-01-27)
* `SPACING_QUICK_REFERENCE.md` (2025-01-27) - Quick reference guide (consolidated)

**Key Issues Addressed:**

1. Content expansion when sidebar collapses
2. Container padding consistency
3. Responsive spacing patterns
4. Mobile-first design
5. Dead space elimination

***

## Related Documents

* **Constitution:** `constitution.md §6.7` - UI/UX guardrails
* **Navigation Standards:** `docs/architecture/NAVIGATION_STANDARD.md` - Navigation patterns
* **UI/UX Standards:** `docs/development/UI_UX_STANDARDS.md` - Full UI/UX guide
* **Dialog/Sheet size rules:** `.cursor/rules/dialog-size-standards.md` - Required size tiers and anti-patterns
* **UI consistency review:** `docs/development/UI_CONSISTENCY_REVIEW.md` - Migration status and remaining work

***
