Theming — make it blend in

Every Olotalk surface renders in a shadow root, so your page’s stylesheet can’t reach inside it. That’s deliberate — it’s what keeps citations, the grounding badge, and the “answer / no answer” states intact no matter how the surface is styled. You can restyle what it looks like; you can’t remove what it says.

To skin it, you set a small set of CSS custom properties. Those do cross the shadow boundary. Put them anywhere the surface inherits from — :root is simplest — and the assistant picks them up.

:root {
  --olotalk-font-family: 'Inter', system-ui, sans-serif;
  --olotalk-accent: #4f46e5;
  --olotalk-surface: #ffffff;
  --olotalk-text: #111827;
  --olotalk-radius: 10px;
}

That’s the whole integration. No JavaScript, no config object, no rebuild. This works for every placement — the corner bubble and the inline assistant both read the same tokens.

Set nothing and the surface looks exactly as it ships. Every token falls back to its built-in value, so adding this is never a restyle you didn’t ask for — it only changes what you explicitly set.


  1. 1
    --olotalk-font-familyAll text
  2. 2
    --olotalk-accentLinks, send, focus
  3. 3
    --olotalk-surfacePanel background
  4. 4
    --olotalk-textMessage text
  5. 5
    --olotalk-radiusButton & input corners
  6. 6
    --olotalk-borderDividers & edges

Tokens

TokenControls
--olotalk-font-familyTypeface for all text. The highest-leverage token — matching your site’s font is what makes the surface read as yours.
--olotalk-font-sizeBase text size.
--olotalk-line-heightBase line height.
--olotalk-accentAccent / primary colour — links, the send action, focus.
--olotalk-textPrimary text colour.
--olotalk-mutedSecondary text — timestamps, captions, placeholders.
--olotalk-surfaceMain panel background.
--olotalk-surface-altSecondary background — header, hovered rows, chips.
--olotalk-borderDivider and border colour.
--olotalk-radiusCorner radius for buttons, inputs, chips.
--olotalk-radius-panelCorner radius for the outer panel.
--olotalk-shadowPanel drop shadow.

Set only the ones you care about. A common minimal set is --olotalk-font-family, --olotalk-accent, and --olotalk-surface — enough to make the surface feel native on most sites.

Coverage

The chat assistant only reads the tokens it actually paints. Nothing breaks if you set one it ignores — it’s simply inert:

  • Chat assistant (floating and embedded) reads every token except --olotalk-font-size — it derives text sizes from its own type scale, driven by --olotalk-font-family and --olotalk-line-height.

What you can’t theme (on purpose)

Spacing and layout. There are no tokens for padding, gaps, or element sizes. Inheriting a host page’s full styling is what makes an embedded component look broken on pages with unusual CSS — so the surface keeps its own internal rhythm and only exposes appearance. This is a deliberate boundary, not a missing feature.

The trust layer. Citations, the source list, the grounding badge, and the honest “I don’t have that” refusal are structural. Tokens change their colour, type, and radius; they can’t hide or remove them. A skin can’t turn a grounded assistant into one that looks like it’s answering when it isn’t.


Precedence

When a value is set in more than one place, the most specific wins:

--olotalk-* token
in your stylesheet
overrides
dashboard appearance
configured per assistant
overrides
built-in default
what ships

A --olotalk-* token you set in your stylesheet overrides the same value configured in the Olotalk dashboard, which overrides the built-in default. The token wins because it’s the most local expression of intent — you, editing the page you’re embedding into.


Dark mode

Tokens are for blending in, not for switching light/dark. To render the chat assistant in dark mode, use its theme option (theme: 'dark') — a separate axis from tokens. You can then still layer tokens on top to tune the dark palette to your brand.


Example — an in-page chat that matches your site

Embedding the chat inline (see Embed reference → Embedded mode) and want it to look like part of the page rather than a bolted-on assistant? Pair the embed with a few tokens:

<div id="chat" style="height: 560px;"></div>

<style>
  :root {
    --olotalk-font-family: var(--site-font, 'Inter', sans-serif);
    --olotalk-accent: #0d9488;
    --olotalk-surface: #fbfbf9;
    --olotalk-surface-alt: #f0efe9;
    --olotalk-border: #e4e2da;
    --olotalk-text: #1c1b19;
    --olotalk-radius: 8px;
    --olotalk-radius-panel: 12px;
  }
</style>

<script>
  window.OlotalkConfig = {
    assistantId: 'ast_oltk_7Kd2mQxRv9TbNhLpW3Zsy',
    mode: 'inline',
    mount: '#chat',
  };
</script>
<script src="https://cdn.jsdelivr.net/npm/@olotalk/assistant-loader@0/dist/loader.iife.js" async></script>

Reuse a variable your site already defines (--site-font above) and the assistant inherits your typography automatically.