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

# Theme Support

> Configure light, dark, or system-driven themes for the PayNext Checkout.

## Theme Configuration

<Note>
  Provide the `theme` property on the object you pass into `checkout.mount('element-id', { ...config })` after creating the instance with `new PayNextCheckout()`, as shown in [Mount the Checkout](/sdk-reference/introduction/getting-started#mount-the-checkout).
</Note>

<ParamField path="theme" type="'light' | 'dark' | 'system'">
  Theme mode for the checkout UI.

  * `'light'`: Fixed light theme
  * `'dark'`: Fixed dark theme
  * `'system'`: Resolves to browser's `prefers-color-scheme` at mount time, then fixed
  * `undefined`: Defaults to `'light'` and listens for system theme changes

  <Info>
    When `theme` is `undefined`, the SDK automatically updates when the user changes their system theme preference. When explicitly set (including `'system'`), the theme is fixed and does not listen to system changes.
  </Info>
</ParamField>

<CodeGroup>
  ```ts Fixed Theme theme={"system"}
  import { PayNextCheckout, type PayNextConfig } from '@paynext/sdk'

  const checkout = new PayNextCheckout()

  const config: PayNextConfig = {
    clientToken: 'your-client-token',
    environment: 'sandbox',
    apiVersion: '1.0.0',
    theme: 'dark',
  }

  await checkout.mount('checkout-container', config)
  ```

  ```ts System Theme theme={"system"}
  import { PayNextCheckout, type PayNextConfig } from '@paynext/sdk'

  const checkout = new PayNextCheckout()

  const config: PayNextConfig = {
    clientToken: 'your-client-token',
    environment: 'sandbox',
    apiVersion: '1.0.0',
    theme: 'system',
  }

  await checkout.mount('checkout-container', config)
  ```

  ```ts Auto-detect theme={"system"}
  import { PayNextCheckout, type PayNextConfig } from '@paynext/sdk'

  const checkout = new PayNextCheckout()

  const config: PayNextConfig = {
    clientToken: 'your-client-token',
    environment: 'sandbox',
    apiVersion: '1.0.0',
    // theme omitted - defaults to light, listens to system changes
  }

  await checkout.mount('checkout-container', config)
  ```
</CodeGroup>

***

## Payment Button Styling

Payment buttons automatically adapt to the theme:

* **Apple Pay**: `style: 'black'` (light) / `'white'` (dark)
* **Google Pay**: `color: 'black'` (light) / `'white'` (dark)
* **PayPal**: `color: 'gold'` (light) / `'white'` (dark)
* **Pix**: white background with an `#e0e0e0` border (light) / `#1a1a1a` background with a `#333` border (dark)

Custom button styles in `styles.ApplePayButton`, `styles.GooglePayButton`, `styles.PayPalButton`, or `styles.PixButton` override theme defaults.

***

## Pix Form Theming

<Info>
  Available from SDK version **1.1.0**.
</Info>

The Pix form's embedded Stripe Payment Element — the email, CPF/CNPJ, and name fields, plus the QR code step — follows the checkout's light/dark theme automatically. No configuration is required.

* **Light theme**: white field background, dark text
* **Dark theme**: dark field background, light text

Both themes share the same accent color and remove Stripe's default focus shadow, so the Pix form matches the rest of the checkout's flat input style.

<Tip>
  Changing the theme at runtime (`checkout.update({ theme })`) re-themes an already-open Pix form immediately — you don't need to close and reopen it.
</Tip>

### Custom Pix Form Colors

Override individual colors and the border radius with `styles.PixForm` (type `PixFormStyles`). These map to [Stripe's Appearance API](https://stripe.com/docs/elements/appearance-api) variables, not the `--paynext-sdk-*` tokens below, since the Pix form renders inside a Stripe-hosted iframe.

```ts pix-form-theme.ts theme={"system"}
import { PayNextCheckout, type StylesConfig } from '@paynext/sdk'

const styles: StylesConfig = {
  PixForm: {
    colorPrimary: '#ff4785',
    borderRadius: '4px'
    // colorBackground, colorText, colorDanger, colorTextPlaceholder also available
  }
}

const checkout = new PayNextCheckout()
await checkout.mount('checkout-container', {
  clientToken: 'your-client-token',
  environment: 'sandbox',
  apiVersion: '1.0.0',
  styles
})
```

Fields you don't set keep the active theme's default, and overrides apply to both recurring Pix Automático and one-time Pix. See [PixForm](/sdk-reference/web-sdk/customization/appearance#pix-form) for the complete field reference.

***

## CSS Variables

Override theme tokens by passing `styles.cssVariables` (type `CSSVariablesConfig`) when you mount the SDK, or target `.checkout` / `.checkout.dark` classes from your stylesheet. Unset values fall back to the active theme defaults.

<Note>
  Variables marked "inherits" are not redefined in dark mode and use the light theme value. Variables marked "same" are explicitly set to the same value in both themes.
</Note>

### Complete Token Reference

| Variable                             | Light default                                                                                           | Dark default            | Description                   |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------- | ----------------------- | ----------------------------- |
| `--paynext-sdk-bg`                   | `transparent`                                                                                           | `transparent`           | Checkout container background |
| `--paynext-sdk-text`                 | `#1a1a1a`                                                                                               | `#ffffff`               | Primary text color            |
| `--paynext-sdk-border`               | `#e0e0e0`                                                                                               | `#404040`               | Default border color          |
| `--paynext-sdk-border-focus`         | `#6b7280`                                                                                               | `#9ca3af`               | Border color on focus         |
| `--paynext-sdk-border-radius`        | `12px`                                                                                                  | inherits                | Global border radius          |
| `--paynext-sdk-input-bg`             | `transparent`                                                                                           | `transparent`           | Input field background        |
| `--paynext-sdk-input-text`           | `hsla(0, 0%, 10%, 0.9)`                                                                                 | `hsla(0, 0%, 90%, 0.9)` | Input text color              |
| `--paynext-sdk-input-focus-shadow`   | `0 0 0 1px rgba(13, 118, 110, 0.7), 0 1px 1px 0 rgba(0, 0, 0, 0.07), 0 0 0 4px rgba(13, 118, 110, 0.3)` | same                    | Focus ring/shadow             |
| `--paynext-sdk-placeholder`          | `#9ca3af`                                                                                               | `#6b7280`               | Placeholder text color        |
| `--paynext-sdk-error`                | `#ef4444`                                                                                               | `#f87171`               | Error text color              |
| `--paynext-sdk-error-border`         | `#dc2727`                                                                                               | `#f87171`               | Error border color            |
| `--paynext-sdk-disabled-bg`          | `#ebedef`                                                                                               | `#374151`               | Disabled input background     |
| `--paynext-sdk-disabled-text`        | `#9ca3af`                                                                                               | `#6b7280`               | Disabled input text           |
| `--paynext-sdk-button-bg`            | `#0d766e`                                                                                               | `#0d766e`               | Submit button background      |
| `--paynext-sdk-button-hover-bg`      | `#0d766d25`                                                                                             | inherits                | Button hover background       |
| `--paynext-sdk-button-text`          | `#ffffff`                                                                                               | `#ffffff`               | Button text color             |
| `--paynext-sdk-button-hover-opacity` | `0.7`                                                                                                   | `0.8`                   | Button hover opacity          |
| `--paynext-sdk-card-bg`              | `#252525`                                                                                               | `#ffffff`               | Card icon container           |
| `--paynext-sdk-card-icon`            | `#565656`                                                                                               | `#d1d5db`               | Card icon color               |

### Override from Config

Pass `cssVariables` through the `styles` option when mounting:

```ts config-override.ts theme={"system"}
import { PayNextCheckout, type CSSVariablesConfig, type StylesConfig } from '@paynext/sdk'

const cssVariables: CSSVariablesConfig = {
  '--paynext-sdk-bg': '#0b1220',
  '--paynext-sdk-text': '#e2e8f0',
  '--paynext-sdk-button-bg': 'linear-gradient(135deg, #0ea5e9, #6366f1)',
  '--paynext-sdk-border-radius': '14px',
  '--paynext-sdk-input-focus-shadow': 'none' // Remove default focus ring
}

const styles: StylesConfig = { cssVariables }

const checkout = new PayNextCheckout()
await checkout.mount('checkout-container', {
  clientToken: 'your-token',
  environment: 'sandbox',
  apiVersion: '1.0.0',
  styles
})
```

<Tip>
  Set `--paynext-sdk-input-focus-shadow` to `none` to disable the default teal focus ring and apply your own focus styles via component styling or external CSS.
</Tip>

### Override from External CSS

Target the `.checkout` class from your stylesheet:

```css styles.css theme={"system"}
/* Light theme overrides */
.checkout {
  --paynext-sdk-border: #e5e7eb;
  --paynext-sdk-border-focus: #6366f1;
  --paynext-sdk-input-focus-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
}

/* Dark theme overrides */
.checkout.dark {
  --paynext-sdk-border: #374151;
  --paynext-sdk-border-focus: #818cf8;
}
```

### Style Presets

Create reusable style presets for different design systems:

<Tabs>
  <Tab title="Minimal">
    ```ts minimal-preset.ts theme={"system"}
    import type { CSSVariablesConfig, StylesConfig } from '@paynext/sdk'

    const minimalPreset: StylesConfig = {
      cssVariables: {
        '--paynext-sdk-input-focus-shadow': 'none',
        '--paynext-sdk-border': '#000000',
        '--paynext-sdk-border-focus': '#000000',
        '--paynext-sdk-border-radius': '0px'
      },
      SubmitButton: {
        styles: {
          background: '#000000',
          borderRadius: '0px',
          textTransform: 'uppercase',
          letterSpacing: '1px'
        }
      }
    }
    ```
  </Tab>

  <Tab title="Colorful">
    ```ts colorful-preset.ts theme={"system"}
    import type { CSSVariablesConfig, StylesConfig } from '@paynext/sdk'

    const colorfulPreset: StylesConfig = {
      cssVariables: {
        '--paynext-sdk-input-focus-shadow': '0 0 0 3px rgba(139, 92, 246, 0.2)',
        '--paynext-sdk-border': '#e0e7ff',
        '--paynext-sdk-border-focus': '#8b5cf6',
        '--paynext-sdk-button-bg': '#8b5cf6'
      },
      SubmitButton: {
        styles: {
          background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
          borderRadius: '12px',
          boxShadow: '0 8px 32px rgba(102, 126, 234, 0.3)'
        }
      }
    }
    ```
  </Tab>

  <Tab title="Brand Colors">
    ```ts brand-preset.ts theme={"system"}
    import type { CSSVariablesConfig, StylesConfig } from '@paynext/sdk'

    // Define your brand colors
    const brand = {
      primary: '#ff6b6b',
      dark: '#2d3436',
      light: '#dfe6e9'
    }

    const brandPreset: StylesConfig = {
      cssVariables: {
        '--paynext-sdk-border': brand.light,
        '--paynext-sdk-border-focus': brand.primary,
        '--paynext-sdk-input-focus-shadow': `0 0 0 3px ${brand.primary}20`,
        '--paynext-sdk-button-bg': brand.primary,
        '--paynext-sdk-button-text': '#ffffff'
      },
      Input: {
        label: {
          styles: { color: brand.dark, fontWeight: '600' }
        }
      },
      SubmitButton: {
        styles: {
          borderRadius: '10px',
          boxShadow: `0 4px 14px ${brand.primary}40`
        }
      }
    }
    ```
  </Tab>
</Tabs>

***

## TypeScript Reference

The SDK exports full type definitions for theme configuration:

```ts types.ts theme={"system"}
import { PayNextCheckout, type PayNextConfig } from '@paynext/sdk'
import type { CSSVariablesConfig, ThemeMode, StylesConfig } from '@paynext/sdk'

// Theme mode type
const theme: ThemeMode = 'system' // 'light' | 'dark' | 'system'

// Typed CSS variables
const cssVariables: CSSVariablesConfig = {
  '--paynext-sdk-bg': '#0b1220',
  '--paynext-sdk-text': '#e2e8f0',
  '--paynext-sdk-border': '#1e293b',
  '--paynext-sdk-border-focus': '#3b82f6',
  '--paynext-sdk-input-bg': '#1e293b',
  '--paynext-sdk-input-text': '#f1f5f9',
  '--paynext-sdk-input-focus-shadow': '0 0 0 2px rgba(59, 130, 246, 0.3)',
  '--paynext-sdk-placeholder': '#64748b',
  '--paynext-sdk-error': '#f87171',
  '--paynext-sdk-error-border': '#f87171',
  '--paynext-sdk-disabled-bg': '#374151',
  '--paynext-sdk-disabled-text': '#6b7280',
  '--paynext-sdk-button-bg': '#3b82f6',
  '--paynext-sdk-button-text': '#ffffff',
  '--paynext-sdk-button-hover-bg': '#2563eb',
  '--paynext-sdk-button-hover-opacity': '0.9',
  '--paynext-sdk-border-radius': '8px',
  '--paynext-sdk-card-bg': '#334155',
  '--paynext-sdk-card-icon': '#94a3b8'
}

// Combined styles config
const styles: StylesConfig = {
  cssVariables,
  // Component-level overrides still work alongside cssVariables
  SubmitButton: {
    styles: { fontWeight: '600' }
  }
}

const config: PayNextConfig = {
  clientToken: 'your-client-token',
  environment: 'sandbox',
  apiVersion: '1.0.0',
  theme,
  styles,
}

const checkout = new PayNextCheckout()
await checkout.mount('checkout-container', config)
```

<Info>
  All `CSSVariablesConfig` properties are optional. Only override the tokens you need to change.
</Info>

***
