---
title: Styling
description: Use Smoothstream's default prose theme, override CSS tokens, or supply your own styles with unstyled.
---

Adapters load two layers of CSS automatically:

1. **Functional reveal styles** — animation, layout hold, table scrolling, code toolbar mechanics. These stay on even when you opt out of the theme.
2. **Default prose theme** — headings, lists, links, quotes, code, tables, and images. It does not require Tailwind CSS and does not constrain the response width.

The theme is scoped to `[data-smoothstream-theme="default"]`, uses zero-specificity `:where()` selectors, and is unlayered so a normal application stylesheet can override it without `!important`.

## Tint the default theme

The palette is derived from one foreground token. Change that token to recolor body text, headings, markers, quotes, and code surfaces together.

<Tabs>
  <Tab label="React">
    ```tsx
    <Smoothstream className="assistant-markdown" receiving={receiving}>
      {text}
    </Smoothstream>
    ```
  </Tab>
  <Tab label="Vue">
    ```vue
    <Smoothstream class="assistant-markdown" :markdown="text" :receiving="receiving" />
    ```
  </Tab>
  <Tab label="Vanilla">
    ```ts
    createSmoothstream(container, {
      className: "assistant-markdown",
      receiving: true,
    });
    ```
  </Tab>
</Tabs>

```css title="assistant-message.css"
.assistant-markdown {
  --smoothstream-foreground: #3b2a20;
}
```

Override a derived token when you need a sharper exception:

```css
.assistant-markdown {
  --smoothstream-heading-color: #7c2d12;
}
```

## Tokens you are likely to set

| Token | Typical use |
| --- | --- |
| `--smoothstream-foreground` | Recolor the whole theme from one value. |
| `--smoothstream-heading-color` | Headings only. |
| `--smoothstream-link-color` | Links. |
| `--smoothstream-font-mono` | Inline and fenced code face. |
| `--smoothstream-inline-code-font-size` | Inline `code` size. |
| `--smoothstream-code-font-size` | Fenced code size. Follows inline size unless you set it. |
| `--smoothstream-code-background` | Fenced block surface. Application tokens win over a Shiki theme. |
| `--smoothstream-code-border-color` | Fenced block frame. |
| `--smoothstream-table-border-color` | Outer table frame. |
| `--smoothstream-table-border-radius` | Outer table corners. |

Task-list checkboxes remain native disabled inputs. The default theme paints a consistent box; forced-colors mode restores the platform checkbox. Size, offset, border, radius, checked fill, and check image each have tokens (`--smoothstream-task-*`).

Wide tables sit in a stationary frame (`[data-smoothstream-table-shell]`) around a nested scroll viewport. Style the frame through the table border tokens, or, with `unstyled`, target that hook. Style `table` / `th` / `td` for typography and cells. The semantic table is not a direct child of the Markdown root.

## Use your own prose styles

Set `unstyled` to drop the default theme. Functional reveal CSS remains.

```tsx
<Smoothstream className="prose max-w-none" unstyled receiving={receiving}>
  {text}
</Smoothstream>
```

```css
.assistant-markdown [data-smoothstream-table-shell] {
  border: 1px solid #d6d3d1;
  border-radius: 0.75rem;
}
```

Body copy inherits the surrounding font and size. The default theme does not pin a root `rem`; heading and spacing tokens that use `em` scale from the host.

<Callout type="info" title="Code surfaces with Shiki">
  An attached highlighter supplies fenced-code foreground and background from the Shiki theme. Language labels, the copy control, the frame, and the scrollbar still follow your content color unless you override the code tokens above. See [Syntax highlighting](/customize/syntax-highlighting).
</Callout>
