---
type: reference
title: Style the widget with CSS
summary: Style the widget shell from your own stylesheet, with ::part() selectors and the --cpt-skin custom properties, plus a reference of every part and variable.
---

The widget renders in an open shadow root and gives you two ways to style it from your own page: **shadow parts** (target an element with `::part()`) and **CSS custom properties** (override a color with `--cpt-skin-*`). For colors and wording, prefer [white-labeling](/docs/widget-customization/white-label) (it is built for that and travels with every embed); reach for the CSS surface here when you want a page-local tweak or something white-labeling does not cover.

This is the widget shell only. The game runs in a separate sandboxed frame you cannot style from the page.

## Targeting a part

Select a part on the element with `::part(name)`:

```css
caputchin-widget::part(simple-checkbox) {
  border-radius: 1rem;
}

caputchin-game::part(game-frame) {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}
```

A few practical notes:

- The shadow root is open, so `::part()` from your page works in every modern browser.
- Some structural parts (the checkbox container, the game frame) carry base layout styles applied inline on the element. To override one of those properties you may need `!important`, since an inline style outranks a normal `::part()` rule. Text and brand parts style cleanly without it.
- Parts are the styling surface; the widget does not expose its internal class names, and they may change. Style by part, not by digging into the shadow tree.

## Parts on the checkbox widget

These appear on `<caputchin-widget>` (and on the pre-game overlay of `<caputchin-game>`, which reuses the same brand block).

| Part | What it is |
|---|---|
| `simple-checkbox` | The outer checkbox container (border, background, padding). |
| `simple-shield-box` | The shield indicator that shows the verification state. |
| `simple-shield-spinner` | The spinner arc inside the shield while verifying. |
| `simple-checkbox-label` | The state text (Verify, Verifying, Verified, Failed). |
| `simple-brand` | The brand block (logo, name, and tag together). |
| `simple-brand-home` | The link wrapping the logo and name, pointing at the home link. |
| `simple-brand-logo` | The brand logo image. |
| `simple-brand-name` | The brand wordmark text. |
| `simple-brand-tag` | The brand tag line, a link pointing at the legal link. |

## Parts on the game widget

These appear on `<caputchin-game>`, around the sandboxed game frame.

| Part | What it is |
|---|---|
| `game-frame` | The chrome frame around the game. |
| `game-iframe-slot` | The slot that holds the game's sandboxed iframe. |
| `game-slot` | The projection container the game renders into. |
| `game-badge-slot` | The brand badge shown below the game. |
| `game-overlay-host` | The host of the pre-game overlay (shown before the game starts). |
| `game-overlay-checkbox` | The checkbox in that overlay. |
| `game-overlay-dialog` | The overlay dialog, in modal and fullscreen layouts. |
| `game-overlay-close` | The overlay close button, in modal and fullscreen layouts only. |

## Color variables

The widget writes its resolved shell colors onto the host element as CSS custom properties named `--cpt-skin-<token>`, and its own styles read them. You can override a single color from your stylesheet by setting the property on the element:

```css
caputchin-widget {
  --cpt-skin-primary: #7c3aed !important;
  --cpt-skin-surface_bg: #faf5ff !important;
}
```

The `!important` matters: the widget sets these properties inline on the host as it resolves the skin, and an inline value outranks a normal stylesheet rule, so a plain override is ignored. These are the shell's colors only; they do not reach the game inside the frame.

This is the page-local escape hatch. To change colors across every embed, set a [skin in white-labeling](/docs/widget-customization/white-label) instead; it uses the same token names.

| Variable | What it colors |
|---|---|
| `--cpt-skin-primary` | The primary action color: the active shield, focus ring, and verified state. |
| `--cpt-skin-primary_hover` | The hover variant of the primary color. |
| `--cpt-skin-surface_bg` | The widget's background. |
| `--cpt-skin-text_primary` | The main text. |
| `--cpt-skin-text_label` | The state label text (Verify, Verifying, and so on). |
| `--cpt-skin-text_muted` | Secondary text, including the brand tag. |
| `--cpt-skin-text_passive` | The shield outline while the widget waits. |
| `--cpt-skin-separator` | The separator between brand pieces in the compact layout. |
| `--cpt-skin-border` | The widget's border. |
| `--cpt-skin-glyph` | The check or alert glyph drawn inside the shield. |
| `--cpt-skin-error` | The error state color. |
| `--cpt-skin-shadow` | The widget's drop shadow. |
| `--cpt-skin-modal_backdrop` | The backdrop behind the modal-layout game overlay. |
| `--cpt-skin-fullscreen_backdrop` | The backdrop behind the fullscreen-layout game overlay. |
| `--cpt-skin-close_btn_bg` | The background of the fullscreen overlay's close button. |
| `--cpt-skin-brand_text` | The brand link text color. |
| `--cpt-skin-brand_text_hover` | The brand link color on hover. |

The brand logo is a separate skin token (an image, not a color), so it is swapped through [white-labeling](/docs/widget-customization/white-label), not CSS. The same token names and their light and dark defaults are in the [schema reference](/docs/references/customization-schema).

These `--cpt-skin-*` variables carry the **widget shell's** skin only. A **game** receives its own skin as values handed to its code (not as CSS variables, and you cannot style a game from your page); see [Customize a game's skin](/docs/game-customization/skin#how-a-skin-value-reaches-the-game).

## See also

- [White-label the widget](/docs/widget-customization/white-label): change wording, colors, and links the supported way.
- [How the widget resolves its language and skin](/docs/widget-customization/resolution): what the shell renders before you style it.
- [Our philosophy](/docs/understanding-caputchin/philosophy): why this styling surface is open and free on every plan.
