> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-feat-update-styling-docs-for-universal-components.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Customize Style and Themes with Auth0 Universal Components

> Customize Auth0 Universal Components using CSS variables, Tailwind v4, and built-in theme presets.

export const ReleaseStageNotice = ({feature, stage, plans, contact, terms}) => {
  const stageTextMap = {
    "beta": "Beta",
    "ea": "Early Access"
  };
  const stageText = stageTextMap[stage] || "a product release stage";
  const prsLink = "/docs/troubleshoot/product-lifecycle/product-release-stages";
  const linkify = (text, url) => {
    return <a href={url} target="_blank" rel="noreferrer" class="link">{text}</a>;
  };
  const includeDetails = (plans, contact, terms) => {
    const hasDetails = terms || plans || contact;
    if (!hasDetails) return null;
    return <span data-as="p">
            {plans && <>This feature is available for {linkify(`${plans} plans`, "https://auth0.com/pricing")}. </>}
            {contact && "To participate, contact " + contact + ". "}
            {terms && <>By using this feature, you agree to the applicable Free Trial terms in Okta's {linkify("Master Subscription Agreement", "https://www.okta.com/legal")}.</>}
        </span>;
  };
  return <Warning>
            <span data-as="p">
                <strong>The {feature} feature is in {linkify(stageText, prsLink)}.</strong>
            </span>

            {includeDetails(plans, contact, terms)}
        </Warning>;
};

<ReleaseStageNotice feature="Auth0 Universal Components" stage="ea" terms="true" contact="Auth0 Support" />

Auth0 Universal Components are built on a design system backed by Tailwind CSS and Radix UI primitives. You apply brand customization by setting CSS custom properties that the components read directly.

Choose your CSS setup below.

<Tabs>
  <Tab title="Plain CSS">
    ## Setup

    Import the pre-compiled stylesheet in your app entry point:

    ```tsx theme={null}
    import "@auth0/universal-components-react/styles";
    ```

    Then override tokens in your CSS:

    ```css theme={null}
    :root {
      --auth0-primary: #4f46e5;            /* your brand color */
      --auth0-primary-foreground: #ffffff; /* text on primary surfaces */
    }
    ```

    All component colors cascade from these two tokens. Add more from the [CSS variables reference](#css-variables) as needed.

    <Callout icon="triangle-exclamation" color="#F59E0B" iconType="regular">
      In plain CSS mode, setting `--primary` or `--color-primary` has no effect. The compiled stylesheet reads `--auth0-*` variables directly.
    </Callout>

    ***

    ## Theme presets

    Pass `themeSettings` to `Auth0ComponentProvider` to switch between built-in visual variants.

    ```tsx theme={null}
    <Auth0ComponentProvider
      themeSettings={{
        mode: "light", // 'light' | 'dark'
        theme: "default", // 'default' | 'minimal' | 'rounded'
      }}
    >
      <App />
    </Auth0ComponentProvider>
    ```

    <table class="table">
      <thead>
        <tr>
          <th>Preset</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td><code>default</code></td>
          <td>Standard Auth0 look with balanced shadows and borders</td>
        </tr>

        <tr>
          <td><code>minimal</code></td>
          <td>Reduced visual weight — fewer shadows, lighter borders</td>
        </tr>

        <tr>
          <td><code>rounded</code></td>
          <td>Increased border radii for a softer appearance</td>
        </tr>
      </tbody>
    </table>

    <Callout icon="circle-info" color="#6366F1" iconType="regular">
      Shadow variables only take effect with the `default` preset. The `minimal` and `rounded` presets disable shadows internally.
    </Callout>

    ***

    <h2 id="css-variables">
      CSS variables reference
    </h2>

    All visual properties are driven by CSS custom properties. Override them in your stylesheet (as shown in Setup above) or via the [`themeSettings.variables` prop](#js-api).

    Set these in `:root` for light mode defaults. Use `.dark` or `themeSettings.mode` for dark mode values.

    <Tabs>
      <Tab title="Colors">
        ```css theme={null}
        :root {
          /* Brand */
          --auth0-primary: oklch(37% 0 0);              /* buttons, links, active states */
          --auth0-primary-foreground: oklch(100% 0 0);  /* text on primary surfaces */

          /* Surfaces */
          --auth0-background: oklch(100% 0 0);          /* page background */
          --auth0-foreground: oklch(9% 0 0);            /* default text */
          --auth0-card: oklch(100% 0 0);                /* card background */
          --auth0-card-foreground: oklch(0% 0 0);       /* text inside cards */
          --auth0-popover: oklch(100% 0 0);             /* dropdown/dialog background */
          --auth0-popover-foreground: oklch(9% 0 0);    /* text inside popovers */
          --auth0-input: oklch(100% 0 0);               /* input field background */

          /* Secondary & muted */
          --auth0-secondary: oklch(96% 0 0);
          --auth0-secondary-foreground: oklch(100% 0 0);
          --auth0-muted: oklch(96% 0 0);                /* disabled/subtle backgrounds */
          --auth0-muted-foreground: oklch(45% 0 0);     /* placeholder text */

          /* Accent & destructive */
          --auth0-accent: oklch(97% 0 0);               /* hover highlights */
          --auth0-accent-foreground: oklch(9% 0 0);
          --auth0-destructive: oklch(93% 0.03 17);      /* error states */
          --auth0-destructive-foreground: oklch(36% 0.14 17);

          /* Borders */
          --auth0-border: oklch(89% 0 0);
          --auth0-ring: oklch(89% 0 0);                 /* focus ring */
        }
        ```
      </Tab>

      <Tab title="Status Colors">
        Status color tokens use no prefix and are set independently from the `--auth0-*` color set.

        | Token                        | Controls                                    |
        | ---------------------------- | ------------------------------------------- |
        | `--color-page`               | Page-level background (outermost container) |
        | `--color-info`               | Info alert background                       |
        | `--color-info-foreground`    | Info alert text and icon                    |
        | `--color-success`            | Success alert background                    |
        | `--color-success-foreground` | Success alert text and icon                 |
        | `--color-warning`            | Warning alert background                    |
        | `--color-warning-foreground` | Warning alert text and icon                 |
        | `--color-destructive-border` | Destructive input/button border             |
        | `--color-popover-border`     | Popover/dropdown border                     |
        | `--color-input-foreground`   | Input text color                            |
        | `--color-input-muted`        | Muted input variant background              |

        Override them in `:root` or via `themeSettings.variables.light` / `.dark`:

        ```css theme={null}
        :root {
          --color-success: oklch(94% 0.05 145);
          --color-success-foreground: oklch(30% 0.1 145);
        }
        ```
      </Tab>

      <Tab title="Border Radius">
        ```css theme={null}
        :root {
          /* Most commonly adjusted */
          --radius-sm:  4px;   /* tags, chips */
          --radius-md:  6px;   /* small elements */
          --radius-lg:  10px;  /* buttons, inputs */
          --radius-xl:  12px;  /* cards */
          --radius-2xl: 16px;  /* modals, large panels */

          /* Fine-grained */
          --radius-xs:  2px;
          --radius-3xl: 20px;
          --radius-4xl: 24px;
          --radius-5xl: 32px;
          --radius-6xl: 40px;
          --radius-7xl: 48px;
          --radius-8xl: 56px;
          --radius-9xl: 64px;
        }
        ```
      </Tab>

      <Tab title="Typography">
        ```css theme={null}
        :root {
          --font-size-page-header:      2.25rem;   /* 36px — main page title */
          --font-size-heading:          1.5rem;    /* 24px — section headings */
          --font-size-title:            1.25rem;   /* 20px — card titles */
          --font-size-subtitle:         1.125rem;  /* 18px — secondary headings */
          --font-size-body:             1rem;      /* 16px — body text */
          --font-size-paragraph:        0.875rem;  /* 14px — descriptions */
          --font-size-label:            0.875rem;  /* 14px — form labels */
          --font-size-page-description: 0.875rem;  /* 14px — page subtitles */
        }
        ```
      </Tab>
    </Tabs>

    ***

    <h2 id="js-api">
      Override via JS API
    </h2>

    Pass `themeSettings.variables` to `Auth0ComponentProvider` for programmatic overrides. These take the highest specificity and override both `:root` CSS and any stylesheet values.

    Variables are organized into three buckets:

    * `common` — applied regardless of mode (radius, typography)
    * `light` — applied when `mode: "light"`
    * `dark` — applied when `mode: "dark"`

    ```tsx theme={null}
    <Auth0ComponentProvider
      themeSettings={{
        mode: "light",
        variables: {
          common: {
            "--radius-lg": "12px",
            "--font-size-body": "0.875rem",
          },
          light: {
            "--auth0-primary": "#4f46e5",
            "--auth0-primary-foreground": "#ffffff",
            "--auth0-background": "#fafafa",
          },
          dark: {
            "--auth0-primary": "#818cf8",
            "--auth0-background": "#121212",
          },
        },
      }}
    >
      <App />
    </Auth0ComponentProvider>
    ```

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      `themeSettings.variables` always uses `--auth0-*` names for color tokens, regardless of your CSS setup. Border radius and typography tokens use their own names (`--radius-*`, `--font-size-*`).
    </Callout>

    ***

    ## Override per component

    Every component accepts a `styling` prop to scope overrides without affecting global styles.

    ```tsx theme={null}
    <SsoProviderTable
      styling={{
        variables: {
          common: {
            "--radius-lg": "16px",
          },
          light: {
            "--auth0-primary": "#059669",
            "--auth0-card": "#f8fafc",
          },
          dark: {
            "--auth0-primary": "#34d399",
            "--auth0-card": "#1e293b",
          },
        },
        classes: {
          "SsoProviderTable-header": "shadow-lg",
          "SsoProviderTable-table": "rounded-xl",
        },
      }}
    />
    ```

    Use `variables` for CSS token overrides scoped to this component, and `classes` for Tailwind or custom classes applied to specific component parts.

    <Accordion title="Available class targets by component">
      **SsoProviderCreate**

      * `SsoProviderCreate-header`, `SsoProviderCreate-wizard`
      * `ProviderSelect-root`, `ProviderDetails-root`, `ProviderConfigure-root`

      **SsoProviderTable**

      * `SsoProviderTable-header`, `SsoProviderTable-table`, `SsoProviderTable-row`

      **SsoProviderEdit**

      * `SsoProviderEdit-header`, `SsoProviderEdit-tabs`
      * `SsoProviderEdit-ssoTab`, `SsoProviderEdit-provisioningTab`, `SsoProviderEdit-domainsTab`

      **DomainTable**

      * `DomainTable-header`, `DomainTable-table`
      * `DomainTable-createModal`, `DomainTable-configureModal`, `DomainTable-deleteModal`

      **OrganizationDetailsEdit**

      * `OrganizationDetailsEdit-header`, `OrganizationDetailsEdit-form`, `OrganizationDetailsEdit-actions`
    </Accordion>

    ***

    ## Common customizations

    ### Brand color

    ```css theme={null}
    :root {
      --auth0-primary: #4f46e5;
      --auth0-primary-foreground: #ffffff;
    }
    ```

    ### Soft corners

    ```css theme={null}
    :root {
      --radius-lg: 16px;  /* buttons, inputs */
      --radius-xl: 20px;  /* cards */
      --radius-2xl: 24px; /* modals */
    }
    ```

    ### Compact typography

    ```css theme={null}
    :root {
      --font-size-page-header: 1.75rem;
      --font-size-heading: 1.25rem;
      --font-size-title: 1rem;
      --font-size-body: 0.875rem;
    }
    ```

    ***

    ## Dark mode

    Components respond to `themeSettings.mode`. Wire it to your app's theme state:

    ```tsx theme={null}
    function App() {
      const [isDark, setIsDark] = useState(false);

      return (
        <Auth0ComponentProvider
          themeSettings={{ mode: isDark ? "dark" : "light" }}
        >
          <YourApp />
        </Auth0ComponentProvider>
      );
    }
    ```

    Or sync with system preference:

    ```tsx theme={null}
    const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;

    <Auth0ComponentProvider
      themeSettings={{ mode: prefersDark ? "dark" : "light" }}
    >
    ```

    For **Next.js** with server-side rendering, read the preferred mode from a cookie to avoid a flash on load:

    ```tsx layout.tsx theme={null}
    export default async function RootLayout({ children }) {
      const cookieStore = await cookies();
      const mode = cookieStore.get("theme-mode")?.value === "dark" ? "dark" : "light";

      return (
        <html lang="en">
          <body>
            <Auth0ComponentProvider
              mode="proxy"
              domain={process.env.NEXT_PUBLIC_AUTH0_DOMAIN}
              proxyConfig={{ baseUrl: "/api/auth" }}
              themeSettings={{ mode }}
            >
              {children}
            </Auth0ComponentProvider>
          </body>
        </html>
      );
    }
    ```
  </Tab>

  <Tab title="Tailwind v4">
    <h2 id="setup-tailwind">
      Setup
    </h2>

    Import both Tailwind and the component stylesheet:

    ```css theme={null}
    @import 'tailwindcss';
    @import '@auth0/universal-components-react/tailwind';
    ```

    Define your design tokens and expose them to Tailwind utilities with `@theme inline`:

    ```css theme={null}
    @theme inline {
      --color-primary: var(--color-primary);
      --color-primary-foreground: var(--color-primary-foreground);
      /* add other tokens you use in Tailwind utilities */
    }

    :root {
      --color-primary: #4f46e5;
      --color-primary-foreground: #ffffff;
    }
    ```

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      **Next.js:** Same pattern — put your `@import` lines and `@theme` block in `globals.css`, then split color overrides into separate `light.css` and `dark.css` files imported from `globals.css`. Import `globals.css` in your root `layout.tsx`.
    </Callout>

    ***

    <h2 id="theme-presets-tailwind">
      Theme presets
    </h2>

    Pass `themeSettings` to `Auth0ComponentProvider` to switch between built-in visual variants.

    ```tsx theme={null}
    <Auth0ComponentProvider
      themeSettings={{
        mode: "light", // 'light' | 'dark'
        theme: "default", // 'default' | 'minimal' | 'rounded'
      }}
    >
      <App />
    </Auth0ComponentProvider>
    ```

    <table class="table">
      <thead>
        <tr>
          <th>Preset</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td><code>default</code></td>
          <td>Standard Auth0 look with balanced shadows and borders</td>
        </tr>

        <tr>
          <td><code>minimal</code></td>
          <td>Reduced visual weight — fewer shadows, lighter borders</td>
        </tr>

        <tr>
          <td><code>rounded</code></td>
          <td>Increased border radii for a softer appearance</td>
        </tr>
      </tbody>
    </table>

    <Callout icon="circle-info" color="#6366F1" iconType="regular">
      Shadow variables only take effect with the `default` preset. The `minimal` and `rounded` presets disable shadows internally.
    </Callout>

    ***

    ## CSS variables reference

    All visual properties are driven by CSS custom properties. Override them in your stylesheet (as shown in Setup above) or via the [`themeSettings.variables` prop](#js-api-tailwind).

    Set these in `:root` for light mode defaults. Use `.dark` or `themeSettings.mode` for dark mode values.

    <Tabs>
      <Tab title="Colors">
        ```css theme={null}
        :root {
          /* Brand */
          --color-primary: oklch(37% 0 0);              /* buttons, links, active states */
          --color-primary-foreground: oklch(100% 0 0);  /* text on primary surfaces */

          /* Surfaces */
          --color-background: oklch(100% 0 0);          /* page background */
          --color-foreground: oklch(9% 0 0);            /* default text */
          --color-card: oklch(100% 0 0);                /* card background */
          --color-card-foreground: oklch(0% 0 0);       /* text inside cards */
          --color-popover: oklch(100% 0 0);             /* dropdown/dialog background */
          --color-popover-foreground: oklch(9% 0 0);    /* text inside popovers */
          --color-input: oklch(100% 0 0);               /* input field background */

          /* Secondary & muted */
          --color-secondary: oklch(96% 0 0);
          --color-secondary-foreground: oklch(100% 0 0);
          --color-muted: oklch(96% 0 0);                /* disabled/subtle backgrounds */
          --color-muted-foreground: oklch(45% 0 0);     /* placeholder text */

          /* Accent & destructive */
          --color-accent: oklch(97% 0 0);               /* hover highlights */
          --color-accent-foreground: oklch(9% 0 0);
          --color-destructive: oklch(93% 0.03 17);      /* error states */
          --color-destructive-foreground: oklch(36% 0.14 17);

          /* Borders */
          --color-border: oklch(89% 0 0);
          --color-ring: oklch(89% 0 0);                 /* focus ring */
        }
        ```
      </Tab>

      <Tab title="Status Colors">
        Status color tokens share the same `--color-*` naming as the brand tokens above.

        | Token                        | Controls                                    |
        | ---------------------------- | ------------------------------------------- |
        | `--color-page`               | Page-level background (outermost container) |
        | `--color-info`               | Info alert background                       |
        | `--color-info-foreground`    | Info alert text and icon                    |
        | `--color-success`            | Success alert background                    |
        | `--color-success-foreground` | Success alert text and icon                 |
        | `--color-warning`            | Warning alert background                    |
        | `--color-warning-foreground` | Warning alert text and icon                 |
        | `--color-destructive-border` | Destructive input/button border             |
        | `--color-popover-border`     | Popover/dropdown border                     |
        | `--color-input-foreground`   | Input text color                            |
        | `--color-input-muted`        | Muted input variant background              |

        Override them in `:root` or via `themeSettings.variables.light` / `.dark`:

        ```css theme={null}
        :root {
          --color-success: oklch(94% 0.05 145);
          --color-success-foreground: oklch(30% 0.1 145);
        }
        ```
      </Tab>

      <Tab title="Border Radius">
        ```css theme={null}
        :root {
          /* Most commonly adjusted */
          --radius-sm:  4px;   /* tags, chips */
          --radius-md:  6px;   /* small elements */
          --radius-lg:  10px;  /* buttons, inputs */
          --radius-xl:  12px;  /* cards */
          --radius-2xl: 16px;  /* modals, large panels */

          /* Fine-grained */
          --radius-xs:  2px;
          --radius-3xl: 20px;
          --radius-4xl: 24px;
          --radius-5xl: 32px;
          --radius-6xl: 40px;
          --radius-7xl: 48px;
          --radius-8xl: 56px;
          --radius-9xl: 64px;
        }
        ```
      </Tab>

      <Tab title="Typography">
        ```css theme={null}
        :root {
          --font-size-page-header:      2.25rem;   /* 36px — main page title */
          --font-size-heading:          1.5rem;    /* 24px — section headings */
          --font-size-title:            1.25rem;   /* 20px — card titles */
          --font-size-subtitle:         1.125rem;  /* 18px — secondary headings */
          --font-size-body:             1rem;      /* 16px — body text */
          --font-size-paragraph:        0.875rem;  /* 14px — descriptions */
          --font-size-label:            0.875rem;  /* 14px — form labels */
          --font-size-page-description: 0.875rem;  /* 14px — page subtitles */
        }
        ```
      </Tab>
    </Tabs>

    ***

    <h2 id="js-api-tailwind">
      Override via JS API
    </h2>

    Pass `themeSettings.variables` to `Auth0ComponentProvider` for programmatic overrides. These take the highest specificity and override both `:root` CSS and any stylesheet values.

    Variables are organized into three buckets:

    * `common` — applied regardless of mode (radius, typography)
    * `light` — applied when `mode: "light"`
    * `dark` — applied when `mode: "dark"`

    ```tsx theme={null}
    <Auth0ComponentProvider
      themeSettings={{
        mode: "light",
        variables: {
          common: {
            "--radius-lg": "12px",
            "--font-size-body": "0.875rem",
          },
          light: {
            "--auth0-primary": "#4f46e5",
            "--auth0-primary-foreground": "#ffffff",
            "--auth0-background": "#fafafa",
          },
          dark: {
            "--auth0-primary": "#818cf8",
            "--auth0-background": "#121212",
          },
        },
      }}
    >
      <App />
    </Auth0ComponentProvider>
    ```

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      `themeSettings.variables` always uses `--auth0-*` names for color tokens, regardless of your CSS setup. Border radius and typography tokens use their own names (`--radius-*`, `--font-size-*`).
    </Callout>

    ***

    <h2 id="override-per-component-tailwind">
      Override per component
    </h2>

    Every component accepts a `styling` prop to scope overrides without affecting global styles.

    ```tsx theme={null}
    <SsoProviderTable
      styling={{
        variables: {
          common: {
            "--radius-lg": "16px",
          },
          light: {
            "--auth0-primary": "#059669",
            "--auth0-card": "#f8fafc",
          },
          dark: {
            "--auth0-primary": "#34d399",
            "--auth0-card": "#1e293b",
          },
        },
        classes: {
          "SsoProviderTable-header": "shadow-lg",
          "SsoProviderTable-table": "rounded-xl",
        },
      }}
    />
    ```

    Use `variables` for CSS token overrides scoped to this component, and `classes` for Tailwind or custom classes applied to specific component parts.

    <Accordion title="Available class targets by component">
      **SsoProviderCreate**

      * `SsoProviderCreate-header`, `SsoProviderCreate-wizard`
      * `ProviderSelect-root`, `ProviderDetails-root`, `ProviderConfigure-root`

      **SsoProviderTable**

      * `SsoProviderTable-header`, `SsoProviderTable-table`, `SsoProviderTable-row`

      **SsoProviderEdit**

      * `SsoProviderEdit-header`, `SsoProviderEdit-tabs`
      * `SsoProviderEdit-ssoTab`, `SsoProviderEdit-provisioningTab`, `SsoProviderEdit-domainsTab`

      **DomainTable**

      * `DomainTable-header`, `DomainTable-table`
      * `DomainTable-createModal`, `DomainTable-configureModal`, `DomainTable-deleteModal`

      **OrganizationDetailsEdit**

      * `OrganizationDetailsEdit-header`, `OrganizationDetailsEdit-form`, `OrganizationDetailsEdit-actions`
    </Accordion>

    ***

    <h2 id="common-customizations-tailwind">
      Common customizations
    </h2>

    <h3 id="brand-color-tailwind">
      Brand color
    </h3>

    ```css theme={null}
    :root {
      --color-primary: #4f46e5;
      --color-primary-foreground: #ffffff;
    }
    ```

    <h3 id="soft-corners-tailwind">
      Soft corners
    </h3>

    ```css theme={null}
    :root {
      --radius-lg: 16px;  /* buttons, inputs */
      --radius-xl: 20px;  /* cards */
      --radius-2xl: 24px; /* modals */
    }
    ```

    <h3 id="compact-typography-tailwind">
      Compact typography
    </h3>

    ```css theme={null}
    :root {
      --font-size-page-header: 1.75rem;
      --font-size-heading: 1.25rem;
      --font-size-title: 1rem;
      --font-size-body: 0.875rem;
    }
    ```

    ***

    <h2 id="dark-mode-tailwind">
      Dark mode
    </h2>

    Components respond to `themeSettings.mode`. Wire it to your app's theme state:

    ```tsx theme={null}
    function App() {
      const [isDark, setIsDark] = useState(false);

      return (
        <Auth0ComponentProvider
          themeSettings={{ mode: isDark ? "dark" : "light" }}
        >
          <YourApp />
        </Auth0ComponentProvider>
      );
    }
    ```

    Or sync with system preference:

    ```tsx theme={null}
    const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;

    <Auth0ComponentProvider
      themeSettings={{ mode: prefersDark ? "dark" : "light" }}
    >
    ```

    For **Next.js** with server-side rendering, read the preferred mode from a cookie to avoid a flash on load:

    ```tsx layout.tsx theme={null}
    export default async function RootLayout({ children }) {
      const cookieStore = await cookies();
      const mode = cookieStore.get("theme-mode")?.value === "dark" ? "dark" : "light";

      return (
        <html lang="en">
          <body>
            <Auth0ComponentProvider
              mode="proxy"
              domain={process.env.NEXT_PUBLIC_AUTH0_DOMAIN}
              proxyConfig={{ baseUrl: "/api/auth" }}
              themeSettings={{ mode }}
            >
              {children}
            </Auth0ComponentProvider>
          </body>
        </html>
      );
    }
    ```
  </Tab>
</Tabs>
