# Configuration: comics

> The comics settings: the frame and gutters of comic pages, panel styles, lettering, balloon styles and the cast

- HTML version: https://postext.dev/en/docs/configuration-comics
- Last updated: 2026-10-10
- Reading time: 3 min
- Other languages: [es](https://postext.dev/es/docs/configuration-comics.md), [ca](https://postext.dev/ca/docs/configuration-comics.md), [pt](https://postext.dev/pt/docs/configuration-comics.md), [zh](https://postext.dev/zh/docs/configuration-comics.md), [ja](https://postext.dev/ja/docs/configuration-comics.md), [ar](https://postext.dev/ar/docs/configuration-comics.md)

## In short

This page covers the settings for comic pages. You set the frame of the page and the space between panels. You choose the font and the size of the lettering. You define how speech balloons, captions and sound effects are drawn. You can also list the characters, so each one speaks in its own style. The Comics guide explains how to write the pages themselves.

## Comics

The `comics` property configures comic pages (`:::page`), strips (`:::strip`) and spreads: the frame and the gutters the panels are cut from, the panel styles, the lettering, the balloon styles and the cast. Only documents with comics read it; a document without them lays out exactly as before, and a document with comics and no `comics` section takes the defaults of its language. The markup and the way pages are lettered are explained in [Comics](https://postext.dev/en/docs/comics.md).

```ts
const config: PostextConfig = {
  comics: {
    readingDirection: 'auto',
    gutter: { horizontal: { value: 5, unit: 'mm' }, vertical: { value: 2.5, unit: 'mm' } },
    panel: { borderWidth: { value: 0.8, unit: 'pt' }, borderStyle: 'rough' },
    panelStyles: [{ id: 'night', background: { hex: '#14142b', model: 'hex' }, borderColor: { hex: '#ffffff', model: 'hex' } }],
    lettering: { fontSize: { value: 8.5, unit: 'pt' }, textTransform: 'uppercase' },
    balloonStyles: [{ id: 'eerie', shape: 'wavy', italic: true }],
    cast: [{ id: 'maya', name: 'Maya' }, { id: 'tomas', name: 'Grandpa Tomás' }],
  },
};
```

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `readingDirection` | `'auto' \| 'ltr' \| 'rtl'` | `'auto'` | The order of the panels in a tier. `'auto'` reads right to left in a right-to-left document, in a vertical one and in Japanese and Traditional Chinese, and in the direction of `artDirection` otherwise (Simplified Chinese and Korean included). A page's `direction` attribute overrides it. With `page.binding: 'auto'`, a book whose comics read right to left is bound on the right. |
| `artDirection` | `'ltr' \| 'rtl'` | `'ltr'` | The reading direction the art was drawn for: `'rtl'` for manga. |
| `mirrorArt` | `boolean` | `false` | Flip the pictures of a page read in the other direction than `artDirection`. A panel keeps its picture as drawn with `mirror=false`. |
| `frame.margins` | `PageMargins` | the page margins | Margins of their own for comic pages (`top`, `bottom`, `left`, `right`, `mirror`). The panels are cut from the box they leave; unset, from the page's text area. |
| `gutter.horizontal` | `Dimension` | `4mm` | The room between tiers. A page's `gutter` attribute overrides it. |
| `gutter.vertical` | `Dimension` | `2mm` | The room between panels side by side in a tier. |
| `panel` | `PanelStyleConfig` | see below | The default panel style. |
| `panelStyles` | `NamedPanelStyleConfig[]` | `[]` | Named panel styles, picked with `:::page{style=…}` or `::panel{style=…}`. Each has an `id`, an optional `name` (editor UIs only) and the fields of a panel style; unset fields follow `panel`. |
| `lettering` | `LetteringConfig` | see below | The face, size and house rules of every balloon of the book. |
| `balloonStyles` | `BalloonStyleConfig[]` | the nine built-in styles | Balloon styles by kind. The built-in ones are always there; an entry with one of their ids changes it, an entry with a new id adds a style laid over `speech`. |
| `cast` | `ComicCastMember[]` | `[]` | The characters (see [Cast](https://postext.dev/en/docs/configuration-comics.md#cast)). |
| `runningHeads` | `boolean` | `false` | Print the running heads and folios on comic pages. Off, a comic page is all panels and its number still counts. |
| `viewerLeaf` | `ComicViewerLeafConfig` | unset | For hosts whose pages are not leaves: lays comic pages out on a print leaf (`width`, `height`, `margins`) scaled to `fitWidth` px (and at most `fitHeight` px tall) at the top of the page. The Sandbox's HTML viewer sets it; it is never saved with a document. |

### Panel styles

`comics.panel` and each entry of `comics.panelStyles`:

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `borderWidth` | `Dimension` | `1pt` | Border width; `0` draws none. The border is stroked on the panel's outline. |
| `borderColor` | `ColorValue` | black | Border colour (palette-linkable). |
| `borderRadius` | `Dimension` | `0` | Corner radius of a rectangular panel, clamped to half its shorter side. A panel cut by a slanted line keeps sharp corners. |
| `borderStyle` | `'solid' \| 'rough' \| 'none'` | `'solid'` | A clean line, a hand-drawn line that wobbles a little (seeded from the panel, so the same on every build), or none. |
| `background` | `ColorValue` | white | The fill under the picture: the colour of an empty panel and of the bands around a picture shown whole. |
| `fit` | `'cover' \| 'contain'` | `'cover'` | `cover` crops the picture to fill the panel, never into its safe area; `contain` shows it whole. |
| `bleed` | `boolean` | `false` | Panels in this style run past the frame to the trim and the bleed on every side that touches the frame. |

### Lettering

`comics.lettering` sets every balloon of the book. There is one size: a balloon style can scale it (`fontScale`), and text is never shrunk to fit a balloon.

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `fontFamily` | `string` | by language | The lettering face. Unset: `Comic Neue`; `Zen Antique` in Japanese, `Noto Sans SC` in Simplified Chinese, `LXGW WenKai TC` in Traditional Chinese, `Playpen Sans Arabic` in Arabic, Persian and Urdu (`defaultComicFont(locale)`). |
| `fontSize` | `Dimension` | `7.5pt` | The size of balloon text. Comics are usually lettered at 7 to 9 pt on the printed page. |
| `lineHeight` | `number` | `1.15` | Distance between lines, a multiple of the size. Left at the default, vertical, Chinese and Japanese balloons take 1.5 and Arabic ones 1.45. |
| `color` | `ColorValue` | black | Text colour. |
| `bold`, `italic` | `boolean` | `false` | Set all the lettering bold or italic. Chinese, Japanese and Arabic lettering is never slanted. |
| `letterSpacing` | `Dimension` | `0` | Extra room between letters; `em` is relative to the text size. Never applied to Arabic. |
| `writingMode` | `'auto' \| 'horizontal' \| 'vertical'` | `'auto'` | `'auto'` letters Japanese and Traditional Chinese, and any document set in vertical writing, in vertical columns, and everything else horizontally. A script line's `vertical` or `horizontal` flag sets that line otherwise (see [Comics › Lettering](https://postext.dev/en/docs/comics.md#lettering)). |
| `textTransform` | `'none' \| 'uppercase'` | `'none'` | All capitals, the classic look of American and European lettering. Scripts without case are left as they are. |
| `dropFinalStop` | `'auto' \| boolean` | `'auto'` | Leave out the full stop that ends a balloon (`。` in manga). `'auto'`: in Japanese and Chinese only. |
| `doubleDash` | `boolean` | `false` | Letter an em dash as `--`, a habit of American lettering. |
| `inset` | `Dimension` | `1.5mm` | Room kept between a balloon and its panel's border. A caption butted to the border ignores it. |
| `joinSameSpeaker` | `'butt' \| 'connector' \| 'none'` | `'butt'` | Two balloons in a row from the same speaker: bodies merged into one outline, linked by a narrow neck, or kept apart. A script line asks for its own with `join` or `join=false`. |
| `maxColumnChars` | `number` | `8` | Vertical lettering: the most characters in one column of a balloon. Sound effects break after five. |

### Balloon styles

Each entry of `comics.balloonStyles` is laid over the built-in style of the same id (`speech`, `thought`, `whisper`, `shout`, `radio`, `caption`, `inner`, `note`, `sfx`), or over `speech` for a new id. The defaults below are those of `speech`; the [Comics page](https://postext.dev/en/docs/comics.md#balloon-styles) lists what each built-in style changes. Lengths in `em` are relative to the balloon's text size.

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `id` | `string` | required | The word a script line names the style with: `ben{whisper}: …` or `style=whisper`. |
| `name` | `string` | `id` | Human-readable name, for editor UIs only. |
| `shape` | `'oval' \| 'rounded' \| 'rectangle' \| 'cloud' \| 'burst' \| 'wavy' \| 'electric' \| 'none'` | `'oval'` | The outline around the text. `'none'` sets the text straight on the picture. |
| `fill` | `ColorValue` | white | Balloon fill. |
| `stroke` | `ColorValue` | black | Outline colour. |
| `strokeWidth` | `Dimension` | `0.6pt` | Outline width. |
| `dash` | `boolean` | `false` | A dashed outline (a whisper). |
| `double` | `boolean` | `false` | A double outline. |
| `wobble` | `number` | `0` | Hand-drawn wobble of the outline, 0 to 1, seeded from the balloon so it never changes between builds. |
| `roundness` | `number` | `2.2` | The superellipse exponent of an oval: 2 is an ellipse, higher values are squarer. |
| `burstPoints` | `number` | `14` | The spikes of a burst; `0` counts them from the perimeter. |
| `burstDepth` | `number` | `0.22` | The depth of a burst's spikes, a fraction of the body's radius. |
| `padding` | `Dimension` | `0.55em` | The air between the text and the outline. |
| `aspect` | `number` | `1.6` | The width over height the line breaking aims the text block at (horizontal lettering). |
| `tail` | `'curved' \| 'wedge' \| 'bubbles' \| 'zigzag' \| 'none'` | `'curved'` | The tail. |
| `tailWidth` | `Dimension` | `0.9em` | The width of the tail where it leaves the outline. |
| `tailReach` | `number` | `0.55` | How far the tail reaches toward its speaker, a fraction of the gap from the outline to the mouth. |
| `target` | `'mouth' \| 'head'` | `'mouth'` | What the tail points at: the anchor's mouth, or its head (thought balloons). |
| `position` | `'auto' \| 'top-start' \| 'top-end' \| 'bottom-start' \| 'bottom-end' \| 'top' \| 'bottom'` | `'auto'` | Where the balloon goes when the line pins none: placed by the lettering, or at a corner or edge of the panel. |
| `butt` | `boolean` | `false` | Set a corner or edge balloon flush against the panel border (captions). |
| `fontFamily` | `string` | the lettering face | The face of this style. `sfx` defaults to the sound-effect face of the language: `Bangers`, `Dela Gothic One` in Japanese, `ZCOOL KuaiLe` in Simplified Chinese, `LXGW WenKai TC` in Traditional Chinese, `Lalezar` in Arabic (`defaultComicSfxFont(locale)`). |
| `fontScale` | `number` | `1` | The text size, a multiple of the lettering size. |
| `bold`, `italic` | `boolean` | the lettering's | Bold or italic text. |
| `color` | `ColorValue` | the lettering's | Text colour. |
| `textTransform` | `'none' \| 'uppercase'` | the lettering's | All capitals for this style. |
| `letterSpacing` | `Dimension` | the lettering's | Extra room between letters. |
| `align` | `'center' \| 'start'` | `'center'` | Line alignment inside the balloon. |
| `halo` | `Dimension` | none | An outline drawn around the letters, its width, so text reads over the picture (sound effects). |
| `haloColor` | `ColorValue` | white | The colour of the halo. |
| `rotate` | `number` | `0` | Rotation in degrees, clockwise. A line's `rotate` attribute wins. |

### Cast

Each entry of `comics.cast` describes a character:

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `id` | `string` | required | The speaker key of the script and of the pictures' anchors. |
| `name` | `string` | `id` | The name the HTML output and the reflowable EPUB print before the character's lines, and editors show. |
| `balloonStyle` | `string` | `speech` | The style of the character's lines that name none. |
| `color` | `ColorValue` | the style's | Text colour of the character's balloons. |
| `fill` | `ColorValue` | the style's | Fill of the character's balloons. |
| `fontFamily` | `string` | the style's | The face of the character's balloons. |

A line's own `color` and `font` win over the cast, and the cast over the balloon style. Every comic colour may be a palette entry, which follows the palette like any linked colour.

```ts
const resolved = resolveComicsConfig(config.comics, 'ja');
// => every field filled; Zen Antique and Dela Gothic One as the faces

const minimal = stripComicsDefaults(config.comics, 'ja');
// => undefined when everything is a default

const shout = pickBalloonStyle(resolved, 'shout'); // the built-in shout with the book's changes
const night = pickPanelStyle(resolved, 'night');   // a named panel style, else the default panel
```
