# Auth Card

> Centered card for sign-in, sign-up, password reset, two-step codes and invites.

Pattern · Pro kit · [Live page](https://ui.twentyfirst.media/pro/patterns/AuthCard/)

Centered card for sign-in, sign-up, password reset, two-step codes and invites.

Props: `title`, `text`, `icon` + `tint` (for non-sign-in steps), `brand`, `foot` (the one secondary link), children (fields and one primary Button).

- One task per card, one primary button. Secondary paths go in the footer.
- After "Send reset link", swap to a confirmation card that doesn't reveal whether the account exists.
- Put it on the `canvas` color with a small "Back" link at top-left.

## Code

```tsx
import * as React from "react";
import { AuthCard, Button, OtpInput, TextField } from "@twentyfirstmedia/pro";

export default function Preview() {
  return (
    <div
      className="tf-grid"
      style={
        {
          "--cols": "repeat(3, minmax(0, 1fr))",
          gap: 16,
          alignItems: "start",
        } as React.CSSProperties
      }
    >
      <AuthCard
        brand="Halo"
        title="Welcome back"
        text="Sign in to the Halo workspace."
        foot="New here? Create a workspace"
      >
        <TextField label="Email" icon="mail" defaultValue="mara@halo.app" />
        <TextField label="Password" type="password" icon="lock" defaultValue="secret-pass" />
        <Button>Sign in</Button>
      </AuthCard>
      <AuthCard
        brand="Halo"
        icon="key"
        tint="butter"
        title="Reset your password"
        text="We’ll email you a link to choose a new one."
        foot="Back to sign in"
      >
        <TextField label="Email" icon="mail" defaultValue="mara@halo.app" />
        <Button icon="send">Send reset link</Button>
      </AuthCard>
      <AuthCard
        brand="Halo"
        icon="shield"
        tint="sky"
        title="Enter your code"
        text="Type the 6-digit code from your authenticator app."
        foot="Use a recovery code instead"
      >
        <OtpInput />
      </AuthCard>
    </div>
  );
}
```

## Props

### AuthCard

| Prop | Type | Notes |
| --- | --- | --- |
| `title` | `string` | Required |
| `text?` | `string` |  |
| `icon?` | `IconName` |  |
| `tint?` | `Tint` |  |
| `brand?` | `string` |  |
| `foot?` | `ReactNode` |  |
| `children?` | `ReactNode` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### Button

| Prop | Type | Notes |
| --- | --- | --- |
| `variant?` | `"primary" \| "secondary" \| "soft" \| "ghost" \| "danger" \| "danger-solid"` |  |
| `size?` | `"md" \| "sm"` |  |
| `icon?` | `IconName` |  |
| `iconRight?` | `IconName` |  |
| `disabled?` | `boolean` |  |
| `type?` | `"button" \| "submit" \| "reset"` |  |
| `onClick?` | `(e: MouseEvent<HTMLButtonElement>) => void` |  |
| `children?` | `ReactNode` |  |
| `asChild?` | `boolean` | Render the single child element (a link, a router Link) with the button's look instead of a <button>. |
| `id?` | `string` |  |
| `name?` | `string` | Form field name and value, sent with the form when this button submits it. |
| `value?` | `string` |  |
| `form?` | `string` | The id of the form this button belongs to, when it sits outside it. |
| `title?` | `string` |  |
| `tabIndex?` | `number` |  |
| `autoFocus?` | `boolean` |  |
| `aria-label?` | `string` |  |
| `aria-labelledby?` | `string` |  |
| `aria-describedby?` | `string` |  |
| `aria-expanded?` | `boolean \| "true" \| "false"` | For disclosure and menu triggers: whether what the button controls is open. |
| `aria-controls?` | `string` |  |
| `aria-haspopup?` | `boolean \| "true" \| "false" \| "menu" \| "listbox" \| "tree" \| "grid" \| "dialog"` |  |
| `aria-pressed?` | `boolean \| "true" \| "false" \| "mixed"` | For toggle buttons. |
| `aria-current?` | `boolean \| "true" \| "false" \| "page" \| "step" \| "location" \| "date" \| "time"` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### OtpInput

| Prop | Type | Notes |
| --- | --- | --- |
| `length?` | `number` |  |
| `onComplete?` | `(code: string) => void` |  |
| `error?` | `boolean` |  |
| `clearOnError?` | `boolean` | Empties the cells when `error` turns on, ready for the next try (default true). |
| `ref?` | `Ref<OtpInputHandle>` | `ref.current.reset()` empties the cells on demand. |
| `label?` | `string` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### TextField

| Prop | Type | Notes |
| --- | --- | --- |
| `type?` | `string` | Input type (`"text"` by default): `"email"`, `"number"`, `"tel"`, `"url"`, `"password"` … |
| `icon?` | `IconName` |  |
| `suffix?` | `ReactNode` |  |
| `value?` | `string` |  |
| `defaultValue?` | `string` |  |
| `placeholder?` | `string` |  |
| `disabled?` | `boolean` |  |
| `readOnly?` | `boolean` |  |
| `autoComplete?` | `string` |  |
| `autoFocus?` | `boolean` |  |
| `min?` | `number \| string` | Smallest value for `type="number"`, `"date"` and the like (native `min`). |
| `max?` | `number \| string` | Largest value (native `max`). |
| `step?` | `number \| string` | Step between valid values (native `step`), e.g. `1` for whole numbers or `"any"`. |
| `minLength?` | `number` | Fewest characters (native `minlength`). |
| `maxLength?` | `number` | Most characters (native `maxlength`). |
| `pattern?` | `string` | Pattern the value must match (native `pattern`). |
| `inputMode?` | `"none" \| "text" \| "tel" \| "url" \| "email" \| "numeric" \| "decimal" \| "search"` | Virtual keyboard on touch devices (native `inputmode`), e.g. `"numeric"` or `"decimal"`. |
| `onChange?` | `(e: ChangeEvent<HTMLInputElement>) => void` |  |
| `onBlur?` | `(e: ChangeEvent<HTMLInputElement>) => void` |  |
| `onKeyDown?` | `(e: KeyboardEvent<HTMLInputElement>) => void` |  |
| `action?` | `ReactNode` | An interactive control at the end of the field (an `IconButton`: clear, copy, locate …). Unlike `suffix` it can be clicked, and it stays when the field shows an error or success mark. |
| `reveal?` | `boolean` | For `type="password"`: a button that shows and hides the password (default true). |
| `label?` | `string` |  |
| `hint?` | `string` |  |
| `error?` | `string` |  |
