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.