---
url: https://docs.comnto.com/customization/appearance.md
description: >-
  Theme modes (auto/light/dark), brand colour tokens, sanitised custom CSS (16
  KB cap), background detection hints, branding, and responsive sizing.
---

# Appearance

Comnto adapts to the page around it while giving you fine-grained control over colours and theming.

## Theme modes

* **auto** (default) Detects the container’s background and switches between light or dark themes automatically. Ideal for dynamic themes or toggles.
* **light** and **dark** Locks all elements to the selected palette.

When a background sits in the middle—neither bright nor dark enough—the auto detector might classify it as light or dark. Override the decision by setting `data-theme="light"` / `data-theme="dark"` or calling `widget.setTheme(...)`.

To disable automatic background detection, set `data-surface` or `colors.surface` to your desired backdrop. Once set, the loader will stop trying to detect the background and use your palette as is.

## Brand colours

Pass a `colors` object to override individual CSS variables. The widget understands the following keys:

```
primary, primaryHover, onPrimary,
link, linkHover,
success, successHover, onSuccess,
danger, dangerHover, onDanger,
warning, warningHover, onWarning,
surface, surfaceAlt,
text
```

Use the action tokens (`primary`, `link`, `success`, `danger`, `warning`) to tint buttons, links, and status badges. Pair them with the matching foreground tokens (`onPrimary`, `onSuccess`, `onDanger`, `onWarning`) to keep icon and text contrast. `surface` / `surfaceAlt` control the widget background layers, while `text` ensures the default body copy stays readable.

Derived values (border, muted text) are calculated automatically. Provide colours as hex (`#2563eb`), rgb, or any CSS colour string.

```js
const widget = window.comnto({
  el: '#comments',
  site: 'my-blog',
  colors: {
    primary: '#2563eb',
    primaryHover: '#1d4ed8',
    onPrimary: '#ffffff',
    surface: '#ffffff',
    surfaceAlt: '#f7f7f9',
    text: '#111827'
  }
});
```

You can update colours later without rebuilding the iframe:

```js
widget.setColors({
  primary: '#22c55e',
  success: '#16a34a',
  successHover: '#15803d'
});
```

## Custom CSS overrides

For advanced adjustments, Comnto accepts a small custom stylesheet. You can manage it from the dashboard (Appearance → Custom CSS) or set it programmatically by updating the site configuration (`css`) via the API.

The CSS snippet is sanitised before it reaches the iframe: HTML tags, `javascript:` URLs, and legacy `expression()` rules are stripped, and the payload is capped at 16 KB to prevent runaway injections.

```js
window.comnto({
  el: '#comments',
  site: 'my-blog',
  css: `
    .comnto-comment-card {
      border-radius: 1.25rem;
    }

    .comnto-badge--moderator {
      background: linear-gradient(135deg, #2563eb, #22d3ee);
      color: #fff;
    }
  `
});
```

Wrap multiline CSS in a template literal string if you embed it through a framework. Plain HTML attributes accept escaped newlines (`&#10;`) or you can keep the snippet compact on one line.

If you prefer declarative embeds, place the CSS on the container:

```html
<div
  id="comments"
  data-site="my-blog"
  data-css="
    .comnto-editor-toolbar { border: 0; background: transparent; }
    .comnto-button--primary { font-family: 'Inter', sans-serif; }
  "
></div>
```

> Clear the override by sending an empty string (`widget.update({ css: '' })`). When no override is present, only the built-in theme variables are applied.

### Background detection hints

* When you pass `colors.surface`, it takes priority over automatic background detection.
* In auto mode, text colour derives from `surface` unless you supply `colors.text`.
* The widget may not detect backgrounds accurately if you use gradients or semi-transparent colors. In such cases, you can send extra context from the host page by posting `comnto:background` events. The loader already sends background colors it observes, so you rarely need this.

```js
widget.iframe.contentWindow.postMessage({ 
  type: 'comnto:background', 
  payload: { color: '#f6f6f7' } 
}, '*');
```

## Branding controls

The footer shows “Powered by Comnto” unless your plan includes white-label branding and you choose to hide it in the dashboard. The widget automatically applies this setting—no code changes needed.

## Responsive layout

* The iframe always uses 100% width. Wrap your container in a parent element with the desired max-width to constrain it.
* The widget reports its height whenever content changes (`comnto:height`). Use that event if you implement custom iframe resizing logic.

```js
widget.on('comnto:height', ({ height }) => {
  console.log('New widget height:', height);
});
```
