<!-- source-hash: 3706922a9df0493d5342fee857818e2a -->
Unified page component for rendering markdown-backed legal documents (privacy policy, terms of service, etc.), replacing duplicate per-document hub components with a single configurable abstraction.

## Key Components

### `LegalDocumentPage`
Main exported component that handles the full page lifecycle — loading skeleton, error state, empty state, and rendered markdown content — driven entirely by props.

### `LegalDocumentPageProps`
Configuration interface covering:
- **`docType`** — drives the default `/api/legal/<docType>` endpoint and error-log prefix
- **`title` / `fallbackDescription`** — heading and subtitle text
- **`contactEmail` / `errorContactPrompt` / `errorTitle` / `emptyStateMessage`** — per-document copy strings
- **`initialData` / `initialLastUpdatedLabel`** — SSR hydration-safe pre-fetched data
- **`apiEndpoint`** — optional override for reverse-proxy or alternate API paths
- **`MarkdownRenderer`** — injectable renderer (defaults to `SimpleMarkdownRenderer`); pass a richer renderer for embeds/video/OG previews
- **`backButton`** — configurable back-nav; pass `false` to hide in embed mode

### `LegalDocumentMarkdownRendererProps`
Renderer contract interface with `content`, `sectionIds`, and `demoteMarkdownH1ToH2`.

## Usage Example

```typescript
// Privacy Policy page
<LegalDocumentPage
  docType="privacy"
  title="Privacy Policy"
  fallbackDescription="Our privacy policy and data protection practices."
  contactEmail="privacy@openframe.io"
  errorContactPrompt="For privacy-related questions, please contact:"
  errorTitle="Unable to load privacy policy"
  emptyStateMessage="Privacy policy content is not available at this time."
  initialData={ssrDocument}
  initialLastUpdatedLabel="January 15, 2025"
/>

// Embed mode with custom renderer and no back button
<LegalDocumentPage
  docType="terms"
  title="Terms of Service"
  fallbackDescription="Terms governing use of our platform."
  contactEmail="legal@openframe.io"
  errorContactPrompt="For legal questions, please contact:"
  errorTitle="Unable to load terms of service"
  emptyStateMessage="Terms of service content is not available at this time."
  MarkdownRenderer={RichMarkdownRenderer}
  backButton={false}
/>
```