An authentication route is one form and very little else, so the page around it is mostly a
decision about where the form sits. AuthLayout supplies that: the column is centred in the height
it is given, it keeps a readable measure, it can be drawn on a panel, and it has somewhere to put
the brand, the heading, the supporting sentence and the link to the other route.

It carries no authentication of its own. There is no field registry, no validation and no request:
the form is `children`, and everything the reader submits is the page's.

Reach for it when the whole screen is a way in, sign in, sign up, reset, verify. For a screen
behind that door, the shell is `SidebarLayout` or `Page`.

```tsx demo="layouts/auth-layout-preview"
```

## Usage

```tsx
import {
  AuthLayout,
  Form,
  Input,
  Link,
  PasswordInput,
  VStack,
} from "@asheeui/web";

<AuthLayout
  brand="Ashee SMS"
  title="Sign in"
  description="Use the email address your workspace knows."
  footer={<Link href="/sign-up">Create an account</Link>}
>
  <Form aria-label="Sign in" submitLabel="Sign in" onSubmit={signIn}>
    <VStack gap="md">
      <Input label="Email" type="email" name="email" autoComplete="email" />
      <PasswordInput label="Password" name="password" />
    </VStack>
  </Form>
</AuthLayout>;
```

That is the whole contract. `brand`, `title` and `description` fill the block above the form,
`children` is the form, and `footer` is the row under it. The shell decides where those sit; the
page decides what they say, every field, the submit control and the form's own name included.

## The media column

`media` is a slot rather than a picture prop: pass a screenshot, a card of numbers, a quotation,
whatever the page wants beside the form. With content in it the shell becomes two columns from the
`lg` breakpoint (1024 pixels), the media taking half of the width, and `mediaPosition` states which
half.

```tsx demo="layouts/auth-layout-media"
```

Below `lg` there is only one column, so the media stacks **in the order the side puts it in the
flow**: above the form for `start`, below it for the registered `end`. That is deliberate, a
product shot under a short form still reads as part of the page, while a figure above a long form
would push the first field past the fold.

## The panel and the measure

Three options decide what the form is drawn on and how wide it is. `panel` (registered `true`)
wraps the form in a bordered surface with its own padding; without it the form sits directly on the
page background. `align` (registered `center`) centres the column vertically, or holds it at the
top for a route with a long form or a message above it. `contentSize` (registered `sm`) is the
maximum width of that column, taken from the [width tokens](/concepts/layout-and-spacing).

```tsx demo="layouts/auth-layout-panel"
```

The three are independent on purpose: a sign-up route usually wants `panel={false}`, `align="start"`
and a wider measure, and stating one of them should not quietly change the others.

## Props

```props AuthLayout
```

All four layout options are registered by the component, so each resolves from the instance, then
from `components.authlayout`, then from the registration: `panel` `true`, `align` `center`,
`mediaPosition` `end`, `contentSize` `sm`. `brand`, `title`, `description`, `children`, `footer`
and `media` are instance-only, because they are the page's own words, and `as` is instance-only
too. There is no colour or variant option: the panel is the framework's own bordered surface, so
it follows the theme's border and background rather than asking the page. Its corners are not a
layout option either, the radius resolves from the application's `defaultRadius`, with `md` as
the hard fallback when no configuration supplies one, so a product that rounds every surface
rounds the sign-in panel with them.

## Accessibility

- The shell renders no landmark. It is a `div` unless `as` says otherwise, so place it inside the
  document's `main`, or pass `as="main"` when the shell is the route's whole page.
- `title` renders an `<h2>`, not the page's `<h1>`. It goes through the shared section heading at
  the `lg` step, and that heading renders an `<h2>` at every size by default; this layout has no
  `titleAs` to raise it, because a layout that decided the page's top-level heading for it would be
  deciding the route's outline. So a route that states its own `<h1>`, a line of the `brand`, or a
  heading at the top of `children`, keeps `title` as the section heading beneath it, and a route
  whose title *is* the page's only heading states that `<h1>` itself rather than expecting the
  shell to render one.
- The form is yours, including its name. The shell renders no `form` element and adds no
  `aria-label`, so the name and the submit control come from the `Form` you pass (its `legend`, or
  its `aria-label`).
- `panel` and the media column are visual boundaries only: neither is a landmark, a region or a
  name, and alternative text belongs to the media you pass into the slot.

The tokens behind `contentSize` and the gaps inside the form are the ones
[Layout and spacing](/concepts/layout-and-spacing) describes; which shell a product should start
from is the argument in [Page compositions](/guides/page-compositions).

## Native

`@asheeui/native` ships `AuthLayout` with the same props and the same cascade. The platform's
differences are the platform's: the shell fills the screen the platform gives it rather than
claiming a viewport height, nothing scrolls, and the media column is placed from the same `lg`
width by the platform's own measurement instead of by a media query. See
[React Native](/platforms/native).

## Related

```related form, input, link
```
