A page is a shell and three parts, and every part is usable without the others. `Page` renders
a full-height column that owns the theme background; `PageHeader` keeps the title and the
actions within reach; `PageContent` is the `main` landmark that fills the height between them;
`PageFooter` closes the page. None of them adds navigation, data or a breakpoint rule, so a
page is the shell plus whatever you put inside it.

It is the only layout that is a whole document. `Section` is a band inside one and `Container`
is a width around something, neither claims the viewport height, and neither is a landmark.

```tsx demo="layouts/page-preview"
```

## Usage

```tsx
import {
  Card,
  Grid,
  Page,
  PageContent,
  PageFooter,
  PageHeader,
  Typography,
} from "@asheeui/web";

<Page>
  <PageHeader>
    <Typography role="heading-lg">Invoices</Typography>
  </PageHeader>
  <PageContent spacing="lg">
    <Grid columns={1} columnsMd={3} gap="md">
      <Card title="Sent" description="This month">348</Card>
    </Grid>
  </PageContent>
  <PageFooter>
    <Typography role="caption" tone="muted">Ashee Softworks</Typography>
  </PageFooter>
</Page>;
```

The four parts answer different questions, whether the part holds its content to a width, how wide
that width may grow, what rhythm the content area claims, whether the bar stays put, and whether a
separator is drawn, and each accepts only the answers it acts on. `components.page` states all
five once, and a part reads the ones it owns.

## The options belong to the part

`Page` accepts none of the five. That is the rule rather than an omission: a shell has no bar to
keep at the top, no content rhythm to claim and no footer to separate, so every option belongs to
the part that can act on it, and the types say so, rather than swallowing an option that would do
nothing.

The consequence is that a misdirected option fails to compile instead of passing quietly.
`<PageHeader sticky>` and `<PageContent spacing="lg">` are options of the part that acts on them;
`<Page sticky>`, `<PageHeader spacing>`, `<PageContent sticky>` and `<PageFooter spacing>` are in
nobody's type. A configured `components.page.spacing` still reaches the content area, which is the
part that owns the rhythm.

```tsx demo="layouts/page-sticky"
```

Stickiness belongs to the header, and so does the rule under it. The divider above the footer
is a separate statement, which is why a page can keep a separator under the bar and none over
the footer. Scroll the page with `Sticky` on and the bar holds the top of the window; the bar
renders translucently over whatever passes beneath it, so the content is still legible as it
goes.

## Width and rhythm

`contained` with `containerSize` decides whether a part wraps its content in a `Container`, and
the header, the content area and the footer each decide for themselves. A header that spans the
window above a content area that is capped is a normal arrangement, and so is its opposite.

The content area is also the part that fills. The shell claims the height of the window and the
header and the footer take their natural height, so `PageContent` takes what is left: a short
page still ends with the footer at the bottom of the window instead of just under its last card.

`spacing` is the vertical padding the content area claims above its first block and below its
last. It is padding rather than the gap between the blocks themselves: the area is a column and
`spacing` moves it, while the rhythm between two cards in it is a `Stack`'s. Keeping the two
apart is what lets a page hold a rhythm in configuration while a single screen tightens its own.

```tsx demo="layouts/page-rhythm"
```

Pick a token and the content moves under the bar. Turn `Contained` off and the column grows to
the window width while the header keeps its own answer, the two parts are not coupled.

## Props

```props Page
```

The shell takes none of the five options and applies none of them, as described above: `as` is the
only thing it acts on. The default is a `div`, and a page whose shell *is* the document body can
render `main` here instead, though `main` is usually `PageContent`, which is where the landmark
belongs.

```props PageHeader
```

The header takes, and acts on, `sticky`, `contained`, `containerSize` and `divider`. `spacing` is
not among them: a bar has no vertical rhythm of its own, so the option is not in the type rather
than accepted and ignored, `<PageHeader spacing="xl">` is a compile error, and a configured
`components.page.spacing` still reaches `PageContent`.

```props PageContent
```

The content area takes, and acts on, `spacing`, `contained` and `containerSize`. `sticky` and
`divider` belong to the parts above and below it and are not in its type. `className` styles the
element the part renders, the `main` landmark by default, while `innerClassName` styles the
column inside it, which is where the vertical padding and the flex layout live; that is the one to
reach for when a screen wants its content laid out differently without losing the landmark's own
classes.

```props PageFooter
```

The footer takes, and acts on, `contained`, `containerSize` and `divider`. Neither `sticky` nor
`spacing` is in its type: a bar that followed the reader at the top would not be a footer, and its
rhythm is its own padding rather than the content area's.

Every value here is registered by the component rather than left to the application:
`components.page` states `contained: true`, `containerSize: "lg"`, `spacing: "md"`, `sticky: true`
and `divider: true`, and the four parts read that one entry. So an application that wants a
full-bleed shell, a wider column and a tighter rhythm states it once:

```tsx
<AsheeUIProvider
  config={{
    components: {
      page: { contained: false, containerSize: "xl", spacing: "lg", sticky: false },
    },
  }}>
  <App />
</AsheeUIProvider>
```

There is no `variant`, `radius` or `colour` on the page: a shell is structure, and anything it
paints beyond the theme background is a `Section`'s job.

## Accessibility

- `PageHeader` renders a `<header>`, which is the `banner` landmark while it is not inside an
  `article`, `aside`, `main`, `nav` or `section`, which is the case in the shell, because `Page`
  is a `div`. `as="div"` removes the landmark and keeps the bar.
- `PageContent` renders a `<main>`: the landmark a screen reader jumps to, and the target of a
  skip link. There is one per document, so a nested page uses `as="section"` or `as="div"` for
  the inner one.
- `PageFooter` renders a `<footer>`, which is the `contentinfo` landmark under the same nesting
  rule as the header.
- Stickiness is a positioning declaration, not a second copy of the bar: nothing leaves the
  document, and the tab order is the order you wrote.
- The divider is a border, and no state is carried by it alone, a page whose header and content
  must be told apart for a reader who cannot see the rule relies on the headings, which is why
  each part takes a real element through `as` rather than a styled `div`.

The spacing scale, the width tokens and `as` are shared by every layout; see
[Layout and spacing](/concepts/layout-and-spacing), and for how the shells assemble a page from
these parts, [Page compositions](/guides/page-compositions).

## Related

```related section, container, stack
```
