# Legal Pages

> Two policy pages with clearly marked sample text: a long-form document whose sticky contents follow your reading position, and a summary-first page with plain-language cards that jump to and flash the full section.

- Collection: Pages
- Tier: pro
- Docs: https://geturui.com/docs/legal-pages
- Install: `npx shadcn@latest add @geturui-pro/legal-pages`
- Dependencies: motion, lucide-react

## Variants

### Document with contents

Long-form terms with a sticky table of contents and scrollspy (IntersectionObserver), reading progress, copyable section links and a mobile contents menu.

Install: `npx shadcn@latest add @geturui-pro/legal-pages-document`

| Prop | Type | Default | Description |
|---|---|---|---|
| eyebrow / title / effective / version / intro | `string` | — | Header copy and badges. |
| sections | `{ id; title; body: (string | { list: string[] })[] }[]` | — | Paragraphs and bullet lists per section. |
| sampleNotice | `boolean` | true | Shows the sample-text notice. |
| contactEmail | `string` | — | Linked in the contact section. |
| stickyOffset | `number` | 0 | Height of a fixed site header, so sticky contents sit below it. |
| className | `string` | — | Classes for the outer element. |

### Summary first

Plain-language summary cards above the full text; each jumps to and flashes its section. Switch policies with a blurred crossfade and expand what changed.

Install: `npx shadcn@latest add @geturui-pro/legal-pages-summary-first`

```tsx
import { LegalSummaryFirst } from "@/components/pages/legal-pages/summary-first";

export default function PrivacyPage() {
  return <LegalSummaryFirst policies={[privacyPolicy, cookiePolicy]} sampleNotice={false} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| title / description | `string` | — | Header copy. |
| policies | `{ id; label; updated; changes?; summaries: { icon; title; text; section }[]; sections: { id; title; paragraphs }[] }[]` | — | Policies; each summary points at a section id. |
| value / defaultValue | `string` | — | Active policy id (controlled / uncontrolled). |
| onValueChange | `(id: string) => void` | — | Called when a policy is chosen. |
| sampleNotice | `boolean` | true | Shows the sample-text notice. |
| className | `string` | — | Classes for the outer element. |

## Accessibility

- Contents links mark the section in view with aria-current="location"; jumping moves focus to the section heading.
- Policy switcher is a tablist with arrow, Home and End keys; “What changed” is a disclosure with aria-expanded.
- Smooth scrolling, gliding indicators and flashes are instant or faded under reduced motion.

## Source

Pro item — send `Authorization: Bearer <registry token>` to include the source.
