# Paywall Appearance and Styling

Source: https://docs.ezoic.com/docs/subscriptions/paywall-appearance/


The paywall and checkout are pre-built, so they work with no styling on your part. When you want more control, there are three ways to get it, from least to most effort:

1. **Appearance settings** — pick a template, color mode, and accent per product in the dashboard. No code.
2. **CSS variables** — override the widget's design tokens from your own stylesheet for exact brand matching.
3. **Build your own pricing UI** — skip Ezoic's paywall screen and render your own plan cards, handing off to `openCheckout({ price })` for payment only. See [Build Your Own Pricing UI](/docs/subscriptions/site-integration/#build-your-own-pricing-ui).

Most sites only need Appearance settings. Add CSS variables when the built-in template and accent aren't close enough. Reach for your own pricing UI when you want full control of how plans are presented — see the caveat at the end of this page if you combine it with Appearance settings.

## Appearance Settings

Each product has Appearance settings you choose in the Ezoic dashboard, on that product's page. They apply everywhere that product's paywall and checkout appear:

- **Template** — `Classic` (compact, neutral) or `Modern` (rounder corners, a colored top bar, and carded price rows).
- **Color mode** — `Light`, `Dark`, or `Auto`. `Auto` follows the visitor's system preference.
- **Accent color** — an optional brand color used for the primary button and focus ring. Ezoic derives the matching hover and text-on-accent colors for you.

For most sites, picking a template, mode, and accent is all you need.

## Custom Styling With CSS Variables

The widget renders inside a [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM), which isolates it from your page's stylesheet. That means you can't target its internal elements with your own CSS selectors — but it exposes a curated set of **CSS custom properties** (variables) on its host element, `#ezoic-sm`, and those are the supported way to restyle it.

Set the variable you want on `#ezoic-sm` from your site's CSS:

```css
#ezoic-sm {
  --sm-accent: #5fa624;
  --sm-accent-hover: #4e8a1e;
  --sm-radius: 12px;
  --sm-font-family: "Source Sans 3", system-ui, sans-serif;
}
```


A value you set on `#ezoic-sm` wins over the product's template, color mode, and accent. It applies in every mode, so if you only want to change dark mode, scope the rule: `#ezoic-sm[data-sm-mode="dark"] { --sm-surface: #101828; }`.


### A Fuller Example

```css
#ezoic-sm {
  /* Brand accent — primary button and focus ring */
  --sm-accent: #5fa624;
  --sm-accent-hover: #4e8a1e;
  --sm-on-accent: #ffffff;
  --sm-focus: rgba(95, 166, 36, 0.14);

  /* Type and surfaces */
  --sm-font-family: "Source Sans 3", system-ui, sans-serif;
  --sm-text: #0f172a;
  --sm-surface: #ffffff;
  --sm-bg: #f8fafc;
  --sm-border: #e2e8f0;

  /* Shape and elevation */
  --sm-radius: 12px;
  --sm-radius-lg: 16px;
  --sm-shadow: 0 24px 64px rgba(15, 23, 42, 0.28);
}
```

### Supported Variables

| Variable | Controls |
|---|---|
| `--sm-font-family` | UI typeface |
| `--sm-text` | Primary text |
| `--sm-text-secondary` | Secondary text |
| `--sm-text-muted` | Muted / hint text |
| `--sm-surface` | Card and panel fill |
| `--sm-surface-hover` | Hover fill for quiet controls |
| `--sm-bg` | Behind-panel background |
| `--sm-border` | Dividers and control borders |
| `--sm-border-strong` | Stronger borders |
| `--sm-accent` | Primary button / accent |
| `--sm-accent-hover` | Accent hover state |
| `--sm-on-accent` | Text/icon on the accent |
| `--sm-focus` | Focus ring |
| `--sm-danger` | Error text |
| `--sm-danger-bg` | Error background |
| `--sm-success-fg` | Success text |
| `--sm-success-bg` | Success background |
| `--sm-radius-sm` | Small corner radius |
| `--sm-radius` | Base corner radius |
| `--sm-radius-lg` | Large corner radius |
| `--sm-overlay-bg` | Paywall backdrop scrim |
| `--sm-shadow` | Panel elevation (Classic) |
| `--sm-shadow-lg` | Panel elevation (Modern) |

The card entry fields (powered by Stripe) pick up these same variables automatically, so your checkout form stays consistent with the rest of the paywall.

## Build Your Own Pricing UI

For full control of how plans are presented, skip `showPaywall()` and render your own plan cards, then call `openCheckout({ price })` to hand off payment. See [Build Your Own Pricing UI](/docs/subscriptions/site-integration/#build-your-own-pricing-ui) for the full pattern.


`openCheckout({ price })` opens payment only — it does not carry a product's Appearance settings (template, color mode, accent), since it starts from a price, not a themed product. It always renders in the Classic/Light default. CSS variables still apply, so if you want it to match your brand, set them on `#ezoic-sm` as shown above.


## What You Can't Customize

The [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM) boundary means the CSS variables above are the full supported surface. You can't:

- Style the widget's internal elements with your own CSS selectors.
- Inject arbitrary CSS or scripts into the widget.
- Change its layout, or hide, add, or reorder elements.

If your brand needs something the variables don't cover, [let us know](/docs/subscriptions/troubleshooting/) — the supported set grows based on real publisher needs.

