> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Customize UI

> Style the allowance verification modal and the CVC recollection form to match your brand

The cards flow ships two hosted UIs, both styled through an `appearance` prop:

* `OrderIntentVerification` renders the modal where the user completes the card network's verification, such as a Visa passkey (see [Create an Agent Card](/agents/payment-methods/cards/create-agent-card#verify-the-selected-rail)).
* `CrossmintCvcRecollection` renders the field where the user re-enters a saved card's CVC after it expires (see [Recollect the CVC](/agents/payment-methods/cards/recollect-cvc)).

## Customize the Verification Modal

The `OrderIntentVerification` appearance object has two top-level keys: **`variables`** (global design tokens) and **`rules`** (per-element overrides).

<Tabs>
  <Tab title="Variables">
    Global design tokens that apply across the entire modal.

    | Token | What it controls |
    | - | - |
    | `fontFamily` | Font stack for all text |
    | `fontSizeUnit` | Base body font size (for example, `"14px"`). Title, small, error, input, and passkey sizes scale proportionally |
    | `spacingUnit` | Base section spacing (for example, `"16px"`). Modal, input, button-gap, and option-gap scale proportionally |
    | `borderRadius` | Default border radius for modal, input, button, and option elements |
    | `colors.accent` | Primary/brand color — buttons, focus rings, radio selected state, spinner |
    | `colors.textPrimary` | Main text color and button text |
    | `colors.textSecondary` | Secondary and placeholder text |
    | `colors.backgroundPrimary` | Surface/card background |
    | `colors.backgroundSecondary` | Input background, secondary button background |
    | `colors.border` | Default border for modal, inputs, and radio |
    | `colors.danger` | Error text, error border, error icon |
    | `colors.success` | Success icon, success background |

    <Info>
      The SDK auto-infers missing color tokens from the ones you provide. For example, setting only `backgroundPrimary` will derive `textPrimary`, `textSecondary`, `backgroundSecondary`, and `border` automatically.
    </Info>
  </Tab>

  <Tab title="Rules">
    Per-element overrides that take precedence over variables.

    | Rule | Customizable properties |
    | - | - |
    | `Overlay` | `colors.background` (backdrop behind the modal) |
    | `Modal` | `borderRadius`, `colors.border` |
    | `Input` | `borderRadius`, `colors.background`, `colors.border` |
    | `PrimaryButton` | `borderRadius`, `colors.text`, `colors.background`, `hover.colors.background`, `disabled.colors.background` |
    | `SecondaryButton` | `colors.text`, `colors.background`, `hover.colors.background` |
    | `CloseButton` | `colors.background`, `hover.colors.background` |
    | `Radio` | `colors.border`, `selected.colors.border`, `selected.colors.background`, `selected.colors.dot` |
  </Tab>
</Tabs>

### Apply the Appearance

You do not need to specify everything. The SDK infers missing colors:

```tsx theme={null}
import {
    OrderIntentVerification,
    type OrderIntentVerificationProps,
} from "@crossmint/client-sdk-react-ui";

function VerifyOrderIntent({
    orderIntent,
}: {
    orderIntent: OrderIntentVerificationProps["orderIntent"];
}) {
    return (
        <OrderIntentVerification
            orderIntent={orderIntent}
            appearance={{
                variables: {
                    colors: {
                        accent: "#6366f1",
                        backgroundPrimary: "#1e1e2e",
                    },
                },
            }}
            onVerificationComplete={() => {
                console.log("Allowance verified");
            }}
            onVerificationError={(error) => {
                console.error("Allowance verification failed", error);
            }}
        />
    );
}
```

This alone will auto-derive `textPrimary`, `textSecondary`, `backgroundSecondary`, and `border` from the dark background, and use the accent color for buttons, focus rings, and radio selections.

## Customize the CVC Recollection Form

`CrossmintCvcRecollection` accepts the same `appearance` object as [`CrossmintPaymentMethodManagement`](/agents/payment-methods/cards/save-card#steps). Keep `fontSizeUnit` and `spacingUnit` close to their defaults: they multiply the component's internal sizes rather than set a base size.

| Token | What it controls |
| - | - |
| `fontFamily` | Font stack for the label, input, and button |
| `fontSizeUnit` | Font size multiplier (default `"4px"`) |
| `spacingUnit` | Spacing multiplier (default `"3.33px"`) |
| `borderRadius` | Border radius for the input and button |
| `colors.accent` | Button background and focus ring |
| `colors.textPrimary` | Label and input text |
| `colors.backgroundPrimary` | Input background |
| `colors.borderPrimary` | Input border |
| `colors.danger` | Error text and error border |

```tsx theme={null}
import { CrossmintCvcRecollection } from "@crossmint/client-sdk-react-ui";

function RecollectCvc({ jwt, paymentMethodId }: { jwt: string; paymentMethodId: string }) {
    return (
        <CrossmintCvcRecollection
            jwt={jwt}
            paymentMethodId={paymentMethodId}
            appearance={{
                variables: {
                    fontSizeUnit: "4px",
                    spacingUnit: "3.33px",
                    borderRadius: "8px",
                    colors: {
                        accent: "#05B959",
                        textPrimary: "#00150d",
                        borderPrimary: "rgba(0,0,0,0.1)",
                    },
                },
            }}
            onComplete={() => {
                console.log("CVC updated");
            }}
        />
    );
}
```
