# Configuration : en-têtes et pieds de page

> Ce qui s’imprime en haut et en bas de chaque page : texte avec variables, filets, boîtes et images, selon la parité de la page, et la place de chaque élément

- Version HTML: https://postext.dev/fr/docs/configuration-headers-footers
- Dernière mise à jour: 2026-10-16
- Temps de lecture: 34 min
- Autres langues: [en](https://postext.dev/en/docs/configuration-headers-footers.md), [es](https://postext.dev/es/docs/configuration-headers-footers.md), [ca](https://postext.dev/ca/docs/configuration-headers-footers.md), [de](https://postext.dev/de/docs/configuration-headers-footers.md), [it](https://postext.dev/it/docs/configuration-headers-footers.md), [pt](https://postext.dev/pt/docs/configuration-headers-footers.md), [zh](https://postext.dev/zh/docs/configuration-headers-footers.md), [ja](https://postext.dev/ja/docs/configuration-headers-footers.md), [ar](https://postext.dev/ar/docs/configuration-headers-footers.md)

## En bref

Cette page traite de ce qui s’imprime en haut et en bas de chaque page. Un en-tête ou un pied de page peut contenir le numéro de page, le titre du livre ou du chapitre, un trait, une boîte ou une petite image. Les pages de gauche et de droite peuvent afficher des choses différentes. Chaque élément se place à gauche, au centre ou à droite, ou dans la marge à côté du texte. L’en-tête et le pied de page se logent dans les marges : ils ne réduisent jamais la zone de texte.

## En-têtes et pieds de page

Les propriétés `header` et `footer` règlent les emplacements d’en-tête et de pied de page de chaque page. En-têtes et pieds de page sont rendus **à l’intérieur des marges existantes** : ils ne réservent aucun espace supplémentaire et ne réduisent pas la zone de contenu.

**Cadre du conteneur.** Un élément ancré à `'container'` est placé dans la bande de marge comprise entre le corps du texte et le bord de coupe, sur toute la largeur de la zone de contenu. Le conteneur de l’en-tête va du **haut de la coupe** jusqu’au haut du corps ; celui du pied de page, du bas du corps jusqu’au **bas de la coupe**. Les ancres `top-*` d’un en-tête et `bottom-*` d’un pied de page se mesurent donc depuis le bord de coupe, tandis que les ancres `bottom-*` d’un en-tête et `top-*` d’un pied de page se mesurent depuis le bord du corps. Le conteneur n’inclut jamais le fond perdu ni la bande des traits de coupe, si bien qu’un en-tête ou un pied de page tombe au même endroit sur la page rognée, que `page.cutLines` soit activé ou non. Ancrez l’élément à `'page'` (la zone de coupe) ou à `'bleed'` pour dépasser la largeur de la zone de contenu ou atteindre le fond perdu.

Les emplacements suivent le modèle unifié des **emplacements de design** : chaque élément a un `placement` doté d’une `anchor` (au conteneur, ou à un autre élément par `#id`), d’un `offset` facultatif et d’une `size` facultative. Les anciens champs à plat `align`, `marginFromBody`, `marginFromEdge` et `width: 'full'` sont toujours acceptés en entrée et migrés automatiquement vers la nouvelle forme ; la description équivalente dans la nouvelle forme est documentée plus bas.

Chaque emplacement contient une liste d’éléments **texte**, **filet** et **boîte**. L’ordre du tableau est l’ordre de peinture (le premier élément est peint en premier, le dernier par-dessus tous les autres). Cela vaut quelles que soient les ancres : un élément peut s’ancrer à un élément listé après lui (`anchor.to: '#ttl'`), de sorte qu’une boîte de fond peut venir en premier et être tout de même positionnée par rapport au texte derrière lequel elle se trouve.

**Valeurs par défaut intégrées.** Lorsque `header` ou `footer` vaut `undefined`, postext applique une valeur par défaut intégrée raisonnable plutôt qu’un emplacement vide :

- **En-tête par défaut :** `{title}` aligné à droite sur les pages impaires, `{chapterTitle}` aligné à gauche sur les pages paires, et un filet sur toute la largeur, le tout dans la couleur principale de la palette, en Open Sans 8 pt/600, `marginFromBody` `16pt` (texte) / `13pt` (filet).
- **Pied de page par défaut :** `{pageNumber}` centré sur chaque page, dans la couleur principale de la palette, en Open Sans 8 pt/600, `marginFromBody` `16pt`.

Pour renoncer aux valeurs par défaut intégrées, définissez `header: { elements: [] }` (ou `footer: { elements: [] }`). Un tableau `elements` vide explicite est conservé comme « aucun élément » : seul `undefined` déclenche les valeurs par défaut.

| Propriété | Type | Défaut | Description |
| --- | --- | --- | --- |
| `elements` | `HeaderFooterElement[]` | valeurs par défaut intégrées si `undefined` ; `[]` les désactive | Liste ordonnée d’éléments texte et filet. |

### Éléments de texte

Les éléments de texte affichent une chaîne modèle dont les variables sont remplacées. Les variables s’écrivent `{name}` ; `{{` et `}}` produisent des accolades littérales.

Les valeurs par défaut du tableau ci-dessous sont celles d’un élément de texte que vous ajoutez vous-même. L’en-tête et le pied de page intégrés décrits plus haut sous **Valeurs par défaut intégrées** sont des éléments tout faits avec leurs propres valeurs (Open Sans 8 pt/600 dans la couleur principale de la palette), et non les valeurs par défaut de l’élément.

| Propriété | Type | Défaut | Description |
| --- | --- | --- | --- |
| `kind` | `'text'` | — | Discriminant. |
| `id` | `string` | — | Identifiant stable, unique dans l’emplacement. Les autres éléments s’y ancrent avec `anchor.to: '#id'`. Le Sandbox en attribue un à la création. |
| `content` | `string` | `''` | Chaîne modèle. Accepte les variables listées ci-dessous, plus `{attr.<key>}` : un attribut écrit sur la ligne du H1 du chapitre courant (`# Title {author="I. Zango"}`). Un attribut absent donne une chaîne vide, sans avertissement. Un saut de ligne, ou les deux caractères `\n` écrits dans le modèle ou dans la valeur d’un attribut, commence toujours une nouvelle ligne, quel que soit `overflow`. Le texte qu’une variable copie du document (un titre, un champ du frontmatter) s’imprime tel qu’il est écrit : là, seul un vrai saut de ligne, comme une coupure de titre, commence une nouvelle ligne. |
| `align` | `'left' \| 'center' \| 'right' \| 'justify' \| 'start' \| 'end'` | `'center'` | Alignement horizontal des lignes dans la boîte de l’élément. `'justify'` étire les espaces entre mots de chaque ligne coupée, sauf la dernière de chaque paragraphe, pour que la ligne remplisse la boîte ; les lignes voisines d’une lettrine remplissent la place à côté d’elle. Avec `hyphenate`, un mot qui ne tient pas dans le reste d’une ligne justifiée est aussi coupé à une syllabe pour la remplir. La dernière ligne d’un paragraphe, une ligne sans espace à étirer et un texte qui ne passe pas à la ligne sont composés au fer à gauche. Le texte justifié est mis en page paragraphe par paragraphe, si bien que plusieurs lignes vides entre deux paragraphes comptent pour une seule. Le canvas et le PDF placent chaque mot là où la mise en page l’a mis ; le HTML élargit les espaces avec `word-spacing`. `'start'` et `'end'` suivent la `direction` du texte : la droite et la gauche d’un texte écrit de droite à gauche. `'left'` et `'right'` sont les côtés propres de la boîte ; dans un design composé dans le flux d’une page de droite à gauche (une bande d’ouverture, un design de titre), le flux est inversé en miroir : ce sont donc son début et sa fin, comme dans le texte courant. |
| `direction` | `'ltr' \| 'rtl' \| 'auto'` | celle du document | Direction de base du texte : la place de ses caractères neutres, l’ordre de ses segments sur une ligne et le sens des côtés `'start'` et `'end'`. `'auto'` lit la première lettre forte du texte résolu et se rabat sur la [`direction`](https://postext.dev/fr/docs/configuration-language.md#sens-du-texte) du document. Les segments arabes et hébreux se lisent de droite à gauche quelle que soit la base. Un texte qui contient une lettre arabe n’est jamais interlettré (`letterSpacing` est ignoré pour tout le texte) et ses mots ne sont jamais coupés lors du passage à la ligne ou de la troncature ; un mot plus large que la boîte déborde et est signalé comme `unbreakableWordOverflow`. |
| `parity` | `'all' \| 'odd' \| 'even'` | `'all'` | Pages sur lesquelles l’élément apparaît (parité du numéro de page : la page 1 est impaire). |
| `pages` | `'all' \| 'body' \| 'opener' \| 'part' \| 'blank'` | `'all'` | Les *rôles* de page sur lesquels l’élément apparaît, combinés avec `parity`. Après le placement, chaque page est classée comme `'blank'` (remplissage de parité ou séparateur, ou page sans contenu), `'part'` (une page de partie), `'opener'` (son premier bloc est un titre dont le niveau s’étend sur toute la page ou force un saut de page avant lui : la première page d’un chapitre) ou `'body'` (tout le reste). `pages: 'body'` masque un titre courant sur les ouvertures de chapitre ; `pages: 'opener'` n’affiche un folio que là. |
| `fontFamily` | `string` | `'EB Garamond'` | Famille de caractères. |
| `fontSize` | `Dimension` | `8 pt` | Corps du caractère. |
| `fontWeight` | `number` | `400` | Graisse (100–900). |
| `italic` | `boolean` | `false` | Composer ou non en italique. |
| `color` | `ColorValue` | `#000000` | Couleur du texte. |
| `overflow` | `'wrap' \| 'ellipsis-start' \| 'ellipsis-middle' \| 'ellipsis-end' \| 'clip'` | `'wrap'` dans les designs de titre et de partie, sinon `'ellipsis-end'` | Ce que fait le moteur d’un texte qui dépasse la largeur disponible de l’élément. `'wrap'` répartit la ligne sur plusieurs lignes ; les variantes à points de suspension gardent chaque ligne sur une seule ligne et la tronquent avec `…` au début, au milieu ou à la fin ; `'clip'` rogne net au cadre de l’élément sans insérer de caractère. Les sauts de ligne du contenu s’appliquent dans tous les modes : les modes à points de suspension et de rognage tronquent ou rognent chaque ligne séparément. Un élément qui omet `overflow` prend la valeur par défaut de son emplacement : dans un design de titre (`advancedDesign.slot`) ou sur une page de partie (`parts.design`, `parts.versoDesign`), il passe à la ligne ; dans un titre courant, un folio ou une ligne de partie de la table des matières (`toc.parts.design`, une ligne de hauteur fixe), il se termine par `…`. Définissez `'wrap'` sur un titre courant qui peut occuper plusieurs lignes (une adresse), ou des points de suspension sur un surtitre qui doit tenir sur une ligne dans une ouverture. Une ligne coupée par des points de suspension, ou rognée avec de l’encre au-delà de la boîte, est signalée par un avertissement de contenu `designTextTruncated`, une fois par élément et par page (une fois par élément et par chapitre pour un titre courant ou un folio). Une configuration enregistrée avant postext 1.24 (`configVersion` 9 ou antérieure) est lue avec `'ellipsis-end'` sur chaque texte de titre et de partie qui n’en définit pas, afin que ses pages ne bougent pas. Un texte doté d’une `dropCap` passe à la ligne quoi que dise cette propriété ; avec `'clip'`, ses lignes sont tout de même coupées au bord d’une boîte de hauteur fixe. `'ellipsis-end'` et `'ellipsis-start'` coupent à une limite de mot (*The history of…*, et non *The history of th…*) et aucune espace ni ponctuation de liaison (virgule, deux-points, tiret, barre oblique, parenthèse ouvrante) ne touche les points de suspension. Un mot n’est coupé là où il le faut que lorsque la limite de mot, une fois cette ponctuation retirée, garderait moins de la moitié de ce qui tient : un seul mot long, ou une URL (*http://exampl…*, et non *http…*). Une espace insécable ou un trait d’union insécable (U+2011, comme dans *MS‑DOS*) n’est pas une limite de mot ; `'ellipsis-middle'` coupe n’importe où mais supprime les espaces qui l’entourent. Jusqu’à postext 1.4, tous les modes coupaient au dernier caractère qui tenait, espaces compris. |
| `verticalAlign` | `'top' \| 'middle' \| 'bottom'` | `'middle'` | Position du texte dans une boîte plus haute que ses lignes : une `placement.size.height` fixe, ou une boîte étirée par un voisin ancré. Quand les lignes sont plus hautes que la boîte (un grand chiffre dans une boîte de hauteur fixe, une `lineHeight` serrée), elles débordent du côté que l’alignement laisse libre, comme l’alignement flex de CSS : `'bottom'` garde le pied de la boîte de la dernière ligne sur le pied de la boîte et déborde en haut, `'middle'` déborde également aux deux extrémités, `'top'` au pied. Jusqu’à postext 1.4, ces lignes pendaient toujours depuis le haut, quel que soit l’alignement. Une `dropCap` se déplace avec ses lignes (jusqu’à postext 1.4, elle restait en haut d’une boîte dans laquelle `'middle'` ou `'bottom'` les faisait descendre). |
| `lineHeight` | `number \| Dimension` | `1.2` | Interlignage des lignes de l’élément. Un nombre est un multiple de `fontSize`. Une `Dimension` est aussi acceptée, comme s’écrit tout autre interlignage de la configuration : `em` / `rem` donne le même multiple, et une longueur absolue (`pt`, `mm`, `px`…) est la distance entre lignes de base : `{ value: 15.5, unit: 'pt' }` fixe un interlignage de 15,5 pt quel que soit le corps. Toute autre valeur (zéro, un nombre négatif, une dimension mal formée) prend la valeur par défaut. Jusqu’à postext 1.4, une `Dimension` à cet endroit rendait la hauteur du design impossible à mesurer : une ouverture ne réservait alors aucune place, pas même sa `minHeight`, et le corps du texte passait sous le titre. |
| `letterSpacing` | `Dimension` | `0` | Approche : espace supplémentaire ajoutée après chaque caractère, espaces compris, exactement comme le `letter-spacing` de CSS. Les largeurs mesurées augmentent d’autant, si bien qu’une boîte à largeur automatique reste ajustée. Elle ne change jamais les glyphes : les ligatures de la police restent actives dans le canvas, en HTML, en EPUB et dans le PDF (jusqu’à postext 1.27, le canvas et le HTML les supprimaient du texte de design interlettré, qui sortait plus large que mesuré). Un segment hébreu est interlettré comme du texte latin ; seul un texte comportant des lettres arabes ne l’est pas. L’approche qui suit le dernier caractère d’une ligne est exclue de son alignement et d’une boîte à largeur automatique, si bien qu’un titre interlettré centré est centré sur ses lettres, qu’un titre aligné à droite finit sur le bord et que la dernière lettre d’une ligne justifiée atteint le bord (jusqu’à postext 1.4, ils se trouvaient une demi-unité d’approche, ou une unité entière, trop à gauche, et un élément ancré à droite d’un élément interlettré s’en trouvait éloigné d’une unité d’approche de plus). Une valeur négative resserre les lettres (un grand titre à 36 pt prend souvent `{ value: -0.3, unit: 'pt' }`) et les largeurs diminuent de la même façon ; canvas, HTML et PDF la peignent à l’identique (jusqu’à postext 1.4, une valeur négative était ramenée à `0`, sans avertissement). |
| `textTransform` | `'none' \| 'uppercase'` | `'none'` | Transformation de casse appliquée au texte résolu, variables comprises : un titre de partie composé en capitales dans la table des matières. |
| `box` | `ElementBoxStyle` | — | Fond et bordure facultatifs dessinés derrière le texte : `backgroundColor`, `borderColor`, `borderWidth`, `borderRadius` et un `padding` par côté qui agrandit la boîte au-delà du texte (voir [Éléments boîte](https://postext.dev/fr/docs/configuration-headers-footers.md#éléments-boîte) pour les champs). |
| `dropCap` | `{ lines, fontFamily, fontWeight, fontSize, color, gap }` | — | Lettrine : la première lettre composée en grand à côté des `lines` premières lignes (2 par défaut), dans sa propre police, sa propre graisse et sa propre couleur, à `gap` du texte. La lettre repose sur la ligne de base de la dernière ligne qu’elle couvre, et `fontSize` vaut par défaut le corps qui aligne son sommet sur les capitales de la première ligne : le corps du texte plus `lines` − 1 interlignes, les capitales étant comptées pour 0,72 du corps d’une lettre (une police dont les capitales sont nettement plus hautes ou plus basses demande une `fontSize` à elle). Un texte avec lettrine passe à la ligne quel que soit son `overflow` ; avec `'clip'`, ses lignes sont tout de même coupées au bord d’une boîte de hauteur fixe. Une `color` liée à la palette suit les palettes de partie et de section comme le reste du design. Dans un design de titre, la lettre ne réserve aucune place sous le texte : la partie de sa boîte de ligne située sous sa ligne de base ne repousse pas le corps du texte. Une lettre qui descend sous sa ligne de base (un Q ou un J dans beaucoup de polices) peut alors empiéter sur l’espace situé sous le design : donnez au titre une `marginBottom` pour cela. Jusqu’à postext 1.4, le corps par défaut rendait la lettre aussi haute que toutes les boîtes de ligne qu’elle couvre, si bien que son sommet dépassait la première ligne ; un `overflow` autre que `'wrap'` supprimait la lettre sans avertissement ; une palette de section ou de partie laissait sa couleur inchangée ; et une lettre aussi profonde que le texte voisin pouvait repousser le corps du texte d’une ligne de grille. Les configurations enregistrées auparavant gardent le corps de 1.4, écrit sous forme de `fontSize` (voir [Paquets écrits par postext 1.4 ou antérieur](https://postext.dev/fr/docs/configuration-bundles.md#paquets-écrits-par-postext-14-ou-antérieur)). Une lettrine dans le texte courant se règle plutôt depuis les styles de paragraphe et de titre (voir [Lettrines](https://postext.dev/fr/docs/configuration-text.md#lettrines)), ses hauteurs de capitales étant mesurées sur les polices. |
| `paragraphIndent` | `Dimension` | `0` | Retrait de première ligne de chaque paragraphe après le premier. Un saut de ligne dans le contenu, ou les deux caractères `\n` pour un texte issu d’une valeur d’attribut, sépare les paragraphes ; plusieurs sauts de ligne consécutifs comptent pour un seul. |
| `hyphenate` | `boolean` | `false` | Si `true` et que le texte passe à la ligne (`overflow: 'wrap'`, ou une `dropCap`, qui passe toujours à la ligne), les mots longs qui déborderaient encore après un saut de ligne normal sont coupés aux limites de syllabe (selon la langue de césure active du document), avec un trait d’union conditionnel à la coupure. Dans un texte justifié (`align: 'justify'`), un mot qui ne tient pas dans le reste d’une ligne est aussi coupé à sa dernière coupure syllabique qui tient, pour remplir la ligne. |
| `inlineMarks` | `boolean` | `false` | Lit le texte résolu, valeurs des variables comprises, comme du Markdown en ligne : `**bold**`, `*italic*`, `^superscript^`, `~subscript~`. Désactivé, les marqueurs s’impriment tels quels. Dans un design de titre, `{titleText}` garde alors les segments en gras, en italique, en exposant et en indice du titre lui-même (`*Pneumocystis*`, `CO~2~`), ses autres caractères étant échappés pour s’imprimer tels quels (depuis postext 1.19). Voir [Marques en ligne et contours](https://postext.dev/fr/docs/configuration-headers-footers.md#marques-en-ligne-et-contours). |
| `stroke` | `{ width, color?, hollow? }` | — | Contour tracé autour des lettres : `width` (une `Dimension`, centrée sur les bords des glyphes), `color` (par défaut, la couleur du texte ; une lettrine prend sa propre couleur) et `hollow` (`true` ne peint que le contour). Voir [Marques en ligne et contours](https://postext.dev/fr/docs/configuration-headers-footers.md#marques-en-ligne-et-contours). |
| `writingMode` | `'horizontal-tb' \| 'vertical-rl'` | `'horizontal-tb'` | `'vertical-rl'` compose le texte de haut en bas, les lignes de droite à gauche, les caractères debout : un titre courant le long de la marge extérieure, un titre vertical à côté d’un chapitre horizontal. Voir [Éléments de texte vertical](https://postext.dev/fr/docs/configuration-headers-footers.md#éléments-de-texte-vertical). |
| `reserve` | `boolean` | `true` | Designs de titre uniquement : indique si l’élément compte dans la hauteur que le titre réserve dans le flux du texte. `false` pour une décoration qui peut passer sous le texte (un sceau en pied de page, un cadre, une bande latérale). Voir [Hauteur réservée](https://postext.dev/fr/docs/configuration-headings.md#hauteur-réservée). Les designs d’en-tête, de pied de page et de partie l’ignorent. |
| `marginFromBody` | `Dimension` | `6 pt` | Distance absolue entre le bord de l’élément tourné vers le corps et le bord du corps. Indépendante des autres éléments. Migrée vers `placement.offset.y`. |
| `marginFromEdge` | `Dimension` | `0 pt` | Retrait horizontal depuis le bord de contenu aligné. Ne s’applique que si `align` vaut `'left'` ou `'right'`. Migré vers `placement.offset.x`. |
| `placement` | `ElementPlacement` | dérivé de `align` + `marginFromBody` + `marginFromEdge` | Placement avancé (voir plus bas). S’il est défini, il prime sur les anciens champs à plat. |

Variables disponibles :

- `{pageNumber}` : numéro de la page courante, à partir de 1.
- `{totalPages}` : nombre total de pages du document. Dans un livre mis en page chapitre par chapitre (le Sandbox, `buildBundle`), chaque chapitre est un document : c’est donc le nombre de pages du chapitre lui-même.
- `{bookTotalPages}` : nombre total de pages du livre entier, tous les chapitres et toutes les pages blanches compris. Pour un document mis en page seul, il est égal à `{totalPages}`. Voir [Nombre de pages du livre](https://postext.dev/fr/docs/configuration-headers-footers.md#nombre-de-pages-du-livre) plus bas.
- `{title}`, `{subtitle}`, `{author}`, `{publishDate}` : valeurs lues dans `content.metadata`. Une métadonnée inconnue ou vide donne une chaîne vide (et lève un avertissement dans le Sandbox).
- `{chapterTitle}` : texte du dernier H1 situé sur la page courante ou avant elle. Un H1 dont le [style de titre](https://postext.dev/fr/docs/configuration-styles.md#styles-de-titre) définit `runningChapter: false` (une planche, une carte) est ignoré.
- `{chapterTitleAtTop}`, `{chapterNumberAtTop}` : titre et numéro du chapitre en cours en haut de la page, qui diffèrent de `{chapterTitle}` et de `{chapterNumber}` sur une page où un nouveau chapitre commence sous d’autre texte. Voir [Chapitre en haut de la page](https://postext.dev/fr/docs/configuration-headers-footers.md#chapitre-en-haut-de-la-page) plus bas.
- `{partTitle}`, `{partNumber}` : titre et numéro de la partie courante (la dernière page `:::part` située sur la page courante ou avant elle ; les pages blanches de parité placées juste avant une page de partie lui appartiennent déjà). Vides avant la première partie.
- `{firstMark.<key>}`, `{lastMark.<key>}` : premier et dernier mot-repère de la page, soit un titre d’un niveau donné (`h1`–`h6`), soit une entrée d’un style de paragraphe. Voir [Mots-repères](https://postext.dev/fr/docs/configuration-headers-footers.md#mots-repères-première-et-dernière-marque) plus bas.

#### Nombre de pages du livre

`{bookTotalPages}` imprime le nombre de pages du livre entier, celui qu’un lecteur voit dans « page 12 sur 348 ». Il compte les pages physiques, pages blanches comprises, comme `{totalPages}`, mais sur l’ensemble des chapitres :

- **Un document mis en page seul** (`buildDocument` sans `continuation`) constitue le livre entier : `{bookTotalPages}` est égal à `{totalPages}`.
- **`buildBundle`** met le livre en page, additionne les pages de chaque chapitre et le remet en page une fois avec ce total, si bien que tous les chapitres impriment le même nombre. Ce nombre ne déplace jamais un saut de page : un tour de plus suffit donc ; une configuration qui n’imprime pas `{bookTotalPages}` ne coûte rien.
- **Le Sandbox** transmet le total à chaque chapitre dès que les pages de tous les chapitres sont connues. D’ici là, un chapitre imprime le nombre de pages jusqu’à sa propre fin. L’export du livre entier de l’onglet PDF compte les pages qu’il met en page : lorsqu’un chapitre a imprimé un autre nombre, parce que ses pages n’étaient pas encore connues, il remet le livre en page une fois de plus avec le nombre auquel les chapitres sont arrivés.
- **Un hôte qui met lui-même les chapitres en page** passe le total dans `continuation.bookPageCount` (pour le premier chapitre aussi). Sans cela, `{bookTotalPages}` compte les pages jusqu’à la fin du document (`continuation.pageIndexOffset` plus ses propres pages), ce qui n’est juste que pour le dernier chapitre.

```ts
footer: {
  elements: [{
    kind: 'text', id: 'folio', content: '{pageNumber} / {bookTotalPages}',
    fontSize: { value: 8, unit: 'pt' },
    placement: { anchor: { to: 'container', edge: 'top' }, size: { width: 'auto', height: 'auto' } },
  }],
}
```

`configUsesPlaceholder(config, 'bookTotalPages')` indique à un hôte si le calcul de ce nombre en vaut la peine.

#### Mots-repères : première et dernière marque

Un dictionnaire imprime dans son titre courant le premier et le dernier mot-vedette de chaque page (« Aback – Anchor ») ; un ouvrage de référence, la première et la dernière section. `{firstMark.<key>}` et `{lastMark.<key>}` les impriment. La clé désigne ce qui marque une page :

- **`h1` à `h6`** : un titre de ce niveau. La marque est son texte, sans le numéro.
- **Un identifiant de style de paragraphe** (`entry`) : un paragraphe d’un conteneur `:::paragraphs{style="entry"}`. La marque est le segment en gras qui ouvre le paragraphe, le mot-vedette, sans sa ponctuation finale : `**Aback.** Said of…` marque `Aback`. Un paragraphe qui ne commence pas par du gras ne pose aucune marque.

`{firstMark.<key>}` est la première marque qui commence sur la page et `{lastMark.<key>}` la dernière. Une page sur laquelle aucune marque ne commence (une longue entrée qui se poursuit) imprime pour les deux la marque en vigueur, la dernière avant elle. Les pages qui précèdent la première marque n’impriment rien ; dans un livre mis en page chapitre par chapitre, il s’agit de la première marque du chapitre, car les marques ne passent pas d’un chapitre au suivant. Un titre ou un paragraphe coupé entre deux pages ne marque que la page où il commence. La clé s’écrit après le point en lettres, chiffres, `_` et `-`, et commence par une lettre ou par `_` ; une clé inconnue n’imprime rien.

```md
:::paragraphs{style="entry"}
**Aback.** Said of the sails when pressed back against the mast.

**Abaft.** Towards the stern, or behind a given point.
:::
```

```ts
header: {
  elements: [{
    kind: 'text', id: 'guide', content: '{firstMark.entry} – {lastMark.entry}',
    fontSize: { value: 8, unit: 'pt' },
    placement: { anchor: { to: 'container', edge: 'bottom' }, size: { width: 'auto', height: 'auto' } },
  }],
}
```

Les mots-repères sont des titres courants : ils se résolvent dans les emplacements d’en-tête et de pied de page (y compris le `header` et le `footer` d’un style de titre) et n’impriment rien dans les designs de titre, de partie et de table des matières ; dans les designs de titre et de partie, le panneau Vérifications les signale comme variables inconnues. Pour afficher le premier mot-vedette sur les versos et le dernier sur les rectos, donnez à deux éléments `parity: 'even'` et `parity: 'odd'`. Un H1 dont le style de titre définit `runningChapter: false` ne pose aucune marque `h1`.

#### Chapitre en haut de la page

`{chapterTitle}` et `{chapterNumber}` nomment le dernier chapitre commencé sur la page ou avant elle. Dans un livre dont les chapitres s’enchaînent sans saut de page, une page qui termine un chapitre et commence le suivant près de son pied porte alors le titre du nouveau chapitre au-dessus d’un texte qui appartient encore à l’ancien. `{chapterTitleAtTop}` et `{chapterNumberAtTop}` nomment plutôt le chapitre en cours en haut de la page, comme le font les romans aux chapitres enchaînés et de nombreux ouvrages de référence :

- une page dont le premier bloc est le H1 d’un chapitre nomme ce chapitre ;
- toute autre page nomme le chapitre qui s’y poursuit, même lorsqu’un nouveau chapitre commence plus bas ;
- une page blanche ajoutée pour la parité va avec la page qui la suit, et le séparateur des modes `always-*` avec la page qui le précède (voir [Appartenance des pages blanches](https://postext.dev/fr/docs/configuration-headings.md#à-qui-appartiennent-les-pages-blanches)) ; lorsque la page qui suit une page blanche de parité s’ouvre sur la fin d’un chapitre, et non sur son H1, la page blanche garde elle aussi ce chapitre ;
- un H1 avec `runningChapter: false` est ignoré.

```ts
header: {
  elements: [{
    kind: 'text', id: 'chapter', content: '{chapterTitleAtTop}', parity: 'odd', pages: 'body',
    fontSize: { value: 8, unit: 'pt' },
    placement: { anchor: { to: 'container', edge: 'bottom-right' }, size: { width: 'auto', height: 'auto' } },
  }],
}
```

Comme les mots-repères, ces deux variables sont des titres courants : elles se résolvent dans les emplacements d’en-tête et de pied de page et n’impriment rien dans les designs de titre, de partie et de table des matières. `{attr.<key>}` lit toujours le dernier chapitre commencé.

#### Alignement induit par le bord d’ancrage

Lorsque le `placement.anchor.to` d’un élément de texte désigne un autre élément par `#id`, le bord d’ancrage induit un alignement de texte par défaut pour les lignes coupées :

- `right-of` et `align-left` induisent `align: 'left'` : les lignes coupées partent de l’ancre vers la droite.
- `left-of` et `align-right` induisent `align: 'right'` : les lignes coupées se serrent contre le côté le plus proche de la cible d’ancrage.

L’éditeur de titres du Sandbox applique automatiquement ces alignements induits lorsque vous changez le bord ou la cible d’ancrage. Ils gardent un texte coupé sur plusieurs lignes visuellement ancré à l’élément auquel il se rapporte (de sorte que, par exemple, le « P » d’un « Postext » coupé s’aligne verticalement sous le « I » d’« Introduction »).

#### Marques en ligne et contours

Par défaut, un élément de texte compose son texte dans une seule police : `**`, `^` et les autres marqueurs Markdown s’impriment tels quels. Avec `inlineMarks: true`, le texte résolu est lu comme du Markdown en ligne, avec les mêmes marques que le texte courant (voir **Format du document → Mise en forme en ligne**) :

- `**bold**` applique la graisse 700 (ou la `fontWeight` propre de l’élément si elle est plus forte) ; `*italic*` inverse l’inclinaison de l’élément, si bien que l’emphase à l’intérieur d’un élément en italique ressort en romain ; `***both***` fait les deux. Les formes avec tiret bas (`__bold__`, `_italic_`) fonctionnent aussi.
- `^superscript^` et `~subscript~` sont composés à 58 % du corps, l’exposant surélevé d’un tiers de celui-ci et l’indice abaissé de 0,15 ; un indice et un exposant qui se touchent (`T~0~^2^`) sont superposés, comme dans le corps du texte.
- Une barre oblique inverse compose le caractère marqueur lui-même (`\*`, `\_`, `\^`, `\~`). Un lien garde son texte ; les accents graves du code sont supprimés.

Les marques sont lues une fois les variables remplies, si bien qu’une valeur peut en contenir : une ligne d’auteurs dans un attribut de titre reçoit ses numéros d’affiliation en exposant. Le passage à la ligne, la justification, les modes à points de suspension, `dropCap` et `paragraphIndent` fonctionnent tous sur le texte marqué ; chaque segment garde la couleur de l’élément.

```json
{ "kind": "text", "id": "authors", "content": "{attr.authors}", "inlineMarks": true, "overflow": "wrap",
  "fontSize": { "value": 11, "unit": "pt" },
  "placement": { "anchor": { "to": "#title", "edge": "below" }, "offset": { "y": { "value": 6, "unit": "pt" } } } }
```

```md
# Snow cover and river flow {authors="Ana Ruiz^1^, Luis Gil^2^ and Marta Sanz^1,3^"}
```

`stroke` trace un contour autour des lettres : `width` est l’épaisseur du trait, centrée sur les bords des glyphes (une moitié tombe à l’intérieur des lettres, l’autre à l’extérieur ; la largeur mesurée du texte ne change pas), `color` vaut par défaut la couleur du texte, et `hollow: true` laisse les lettres sans remplissage pour ne montrer que le contour : un grand chiffre détouré, un titre qui se détache sur une photographie. Le contour est peint par-dessus le remplissage, de la même façon dans le canvas, en HTML (`-webkit-text-stroke`) et dans le PDF (mode de rendu du texte 2, ou 1 s’il est évidé).

```json
{ "kind": "text", "id": "year", "content": "1863", "fontFamily": "Bitter", "fontSize": { "value": 120, "unit": "pt" }, "fontWeight": 700,
  "color": { "hex": "#1d3557", "model": "hex" },
  "stroke": { "width": { "value": 1.5, "unit": "pt" }, "hollow": true },
  "placement": { "anchor": { "to": "page", "edge": "bottom-right" }, "offset": { "x": { "value": -15, "unit": "mm" }, "y": { "value": -20, "unit": "mm" } } } }
```

Dans le PDF, les segments en gras et en italique incorporent les polices correspondantes de la famille de l’élément : le fournisseur de polices doit donc les fournir.

#### Valeurs par défaut du texte et pièges de l’ancrage

Un élément de texte que vous écrivez vous-même part de ces valeurs, dont certaines surprennent :

- **`overflow` suit l’emplacement.** Dans un design de titre ou sur une page de partie, un long titre passe sur plusieurs lignes ; dans un titre courant, un folio ou une ligne de partie de la table des matières, un texte trop large pour sa place est ramené à une ligne terminée par `…`. Définissez `overflow: 'wrap'` sur un titre courant qui peut s’allonger (une adresse, une signature), et consultez les avertissements `designTextTruncated` pour repérer les textes coupés. Un saut de ligne dans le contenu (un retour à la ligne, ou `\n` dans le modèle ou dans une valeur d’attribut) commence une nouvelle ligne dans tous les modes ; les modes à points de suspension coupent chaque ligne séparément.
- **`align` vaut `'center'` et `verticalAlign` vaut `'middle'`.** Un élément à largeur automatique s’ajuste à sa ligne la plus longue, si bien que ses lignes sont centrées les unes par rapport aux autres ; définissez `align: 'left'` pour un bloc au fer à gauche (un élément à largeur automatique ancré à un autre élément aligne de lui-même ses lignes du côté de son ancre, voir plus haut).
- **La police est EB Garamond 8 pt, en noir, `lineHeight` 1,2**, quelle que soit celle du texte courant. Contrairement aux autres interlignages de la configuration, la `lineHeight` d’un texte de design est en général un simple multiple (`1.2`) ; une `Dimension` fonctionne aussi (voir plus haut).

Un élément sans `placement.size.width` (ou avec `'auto'`) prend la taille de son texte, mais seulement dans la place comprise entre son point d’ancrage et le bord du conteneur vers lequel il s’étend : pour une ancre `top` ou `bottom`, deux fois la distance au bord le plus proche. Son `offset` compte. Un décalage qui l’éloigne de ce bord ne coûte rien : un titre courant ancré `top-left` avec un `x` négatif (qui déborde dans la marge de gauche) ne perd aucune place, car il s’étend vers la droite. Un décalage vers ce bord réduit la place d’autant (du double pour une ancre `top` ou `bottom`), et un décalage qui pousse l’ancre au-delà du bord n’en laisse aucune : une ancre `top-right` dont le `x` est inférieur à moins la largeur du conteneur, ou une ancre `top` déplacée latéralement de plus de la moitié de cette largeur. Sans place, un mode à points de suspension n’imprime rien et `'wrap'` empile un caractère par ligne. Trois façons d’en sortir :

- donnez à l’élément une `size.width` fixe : les largeurs fixes ne sont jamais bridées ;
- ancrez-le à `'page'` ou à `'bleed'`, ce qui fait de la page (ou du fond perdu) le cadre de sa place ;
- ancrez-le au bord opposé du conteneur.

Le conteneur d’un en-tête va du haut de la coupe jusqu’au corps, et celui d’un pied de page du corps jusqu’au bas de la coupe : dans un en-tête, les ancres `top-*` se mesurent depuis le bord de coupe et les ancres `bottom-*` depuis le corps, et l’inverse dans un pied de page (voir **Cadre du conteneur** plus haut). Un en-tête ou un pied de page ne déplace jamais le texte courant et se peint par-dessus : un élément poussé dans la zone du corps recouvre donc le texte. Une bande d’ouverture, à l’inverse, se peint sous le texte courant ; la place qu’elle prend dans le flux est décrite sous [Hauteur réservée](https://postext.dev/fr/docs/configuration-headings.md#hauteur-réservée).

### Éléments de texte vertical

Un élément de texte avec `writingMode: 'vertical-rl'` est composé verticalement dans un emplacement dont le texte est horizontal : les titres courants et les folios de n’importe quel livre, qui restent sur la feuille, et tous les designs d’une page horizontale. Il est mis en page comme un texte horizontal dans son propre cadre tourné d’un quart de tour dans le sens horaire, puis ramené sur la page :

- Sa boîte reste là où le placement la met. Sa hauteur est la longueur d’une ligne : `size.height` la fixe (ou `'auto'`, la longueur du texte ; `'fill'`, jusqu’au bord du conteneur), `size.width` fixe le nombre de lignes qui tiennent en travers, et `size.maxWidth` plafonne la longueur d’une ligne.
- `align` place les lignes le long de la boîte (`'left'` en haut), `verticalAlign` en travers (`'top'` à droite, là où se trouve la première ligne), et le padding d’une boîte reste du côté pour lequel il est écrit.
- Les caractères sont mesurés et peints comme dans une page verticale : les caractères han debout, un cadratin chacun, la ponctuation sous sa forme verticale, les mots latins couchés, les nombres courts dans une seule case (`cjk.uprightDigits`). Le canvas, le PDF et le HTML le placent dans le même rectangle.
- Avec `inlineMarks: true`, les marques d’orientation isolent un segment comme dans le corps du texte : `第:tcy[3.0]回` compose 3.0 dans une seule case, `:upright[GDP]` met les lettres debout l’une sous l’autre, `:sideways[…]` couche un segment ; une ligne ne se coupe jamais à l’intérieur de l’une d’elles. Un élément horizontal les ignore.
- Aucune lettrine n’est composée sur un élément vertical.
- Dans le flux d’une page verticale (une ouverture, une page de partie, un titre d’encadré), le texte descend déjà, et `writingMode` n’y change rien.

Les livres chinois verticaux placent leurs titres courants et leurs folios à l’un de trois endroits ([clreq §7.2](https://www.w3.org/TR/clreq/#x7-2-page-headers-footers-etc) ; [JLREQ §2.6](https://www.w3.org/TR/jlreq/#running_heads_and_page_numbers) pour le japonais) :

| Convention | Emplacement | Comment le régler |
| --- | --- | --- |
| Tête et pied horizontaux | Au-dessus et au-dessous du bloc de texte, comme dans les livres horizontaux ; c’est le plus courant. | L’en-tête et le pied de page tels quels. |
| Marge extérieure (style 中缝, 邊峰 à Taïwan) | Le long de la marge extérieure : le titre du chapitre ou du livre à partir d’environ quatre caractères sous la tête du bloc de texte, le folio se terminant environ cinq caractères au-dessus de son pied, en chiffres chinois, à environ 80 % du corps du texte. | Deux éléments verticaux ancrés à `'outer'`, ci-dessous. |
| Coin extérieur du pied | Le folio en pied de page, dans le coin extérieur (règles de Taïwan pour les livres 中式). | Un élément horizontal dans le pied de page à `'bottom-left'` avec `parity: 'odd'` et un autre à `'bottom-right'` avec `parity: 'even'` dans un livre relié à droite (l’inverse dans un livre relié à gauche). |

Voici les titres en marge extérieure tels que le Sandbox les ajoute (**En-tête › Titres en marge extérieure (vertical)**), ici pour un texte courant de 10 pt (le Sandbox les compose à 80 % du corps du texte) :

```json
{
  "page": { "pageNumbering": { "format": "trad-chinese-informal" } },
  "header": { "elements": [
    { "kind": "text", "id": "head", "content": "{chapterTitle}", "writingMode": "vertical-rl",
      "fontSize": { "value": 8, "unit": "pt" }, "overflow": "clip", "align": "left",
      "placement": { "anchor": { "to": "outer", "edge": "top" }, "offset": { "y": { "value": 4, "unit": "em" } } } },
    { "kind": "text", "id": "folio", "content": "{pageNumber}", "writingMode": "vertical-rl",
      "fontSize": { "value": 8, "unit": "pt" }, "overflow": "clip", "align": "left",
      "placement": { "anchor": { "to": "outer", "edge": "bottom" }, "offset": { "y": { "value": -5, "unit": "em" } } } }
  ] }
}
```

`anchor.to: 'outer'` (voir [Placement des éléments](https://postext.dev/fr/docs/configuration-headers-footers.md#placement-des-éléments)) désigne la marge extérieure de chaque page : les deux éléments descendent donc le long du bord gauche d’un recto et du bord droit d’un verso dans un livre relié à droite (`page.binding`). `{pageNumber}` s’imprime dans le format de numérotation des pages : `trad-chinese-informal` donne 一百零三 en page 103, `cjk-decimal` 一〇三. Les règles propres à chaque emplacement s’appliquent toujours : `pages: 'body'` tient un titre courant à l’écart des ouvertures de chapitre. Un court ornement entre le titre courant et le folio (une queue de poisson ︻, un filet) est un élément ordinaire ancré au même cadre.

Dans le VDT, un bloc vertical porte `vertical` (`VDTDesignTextBlock.vertical` : la région, les chiffres debout et l’axe central de chaque famille) ; ses lignes sont exprimées dans le cadre tourné propre au bloc, `xOffset` vers le bas depuis le haut de la boîte, `baselineY` vers la gauche depuis son bord droit. Un segment d’une ligne marquée porte `tcy` ou `orientation`, comme un segment du corps du texte.

### Éléments filet

Les éléments filet tracent une ligne : horizontale en travers de l’emplacement, ou verticale de haut en bas.

| Propriété | Type | Défaut | Description |
| --- | --- | --- | --- |
| `kind` | `'rule'` | — | Discriminant. |
| `id` | `string` | — | Identifiant stable, unique dans l’emplacement, pour les références `anchor.to: '#id'`. |
| `direction` | `'horizontal' \| 'vertical'` | `'horizontal'` | Un filet horizontal s’étend sur `placement.size.width` (`'fill'` = jusqu’au bord du conteneur) et a une hauteur de `thickness`. Un filet vertical descend sur `placement.size.height` (`'fill'` ou non défini = jusqu’au bord du conteneur) et a une largeur de `thickness` : un séparateur entre un titre courant et un folio. |
| `color` | `ColorValue` | `#000000` | Couleur du trait. |
| `thickness` | `Dimension` | `0.5 pt` | Épaisseur du trait. Un filet qui l’omet est tracé à la valeur par défaut (jusqu’à postext 1.4, il ne peignait rien). |
| `width` | `Dimension \| 'full'` | `'full'` | `'full'` couvre la zone de contenu ; une Dimension limite la ligne à une longueur fixe positionnée par `align`. |
| `align` | `'left' \| 'center' \| 'right'` | `'center'` | Alignement lorsque `width` ne vaut pas `'full'`. |
| `marginFromBody` | `Dimension` | `6 pt` | Distance absolue entre le bord du filet tourné vers le corps et le bord du corps. Indépendante des autres éléments. |
| `marginFromEdge` | `Dimension` | `0 pt` | Retrait horizontal depuis le bord de contenu aligné. Ne s’applique que si `width` est une `Dimension` fixe et si `align` vaut `'left'` ou `'right'`. |
| `parity` | `'all' \| 'odd' \| 'even'` | `'all'` | Pages sur lesquelles le filet apparaît. |
| `pages` | `'all' \| 'body' \| 'opener' \| 'part' \| 'blank'` | `'all'` | Rôles de page sur lesquels le filet apparaît (voir le champ `pages` des éléments de texte). |
| `reserve` | `boolean` | `true` | Designs de titre uniquement : indique si le filet compte dans la hauteur que le titre réserve dans le flux du texte (voir [Hauteur réservée](https://postext.dev/fr/docs/configuration-headings.md#hauteur-réservée)). |
| `placement` | `ElementPlacement` | dérivé de `align` + `marginFromBody` + `marginFromEdge` | Placement avancé (voir [Placement des éléments](https://postext.dev/fr/docs/configuration-headers-footers.md#placement-des-éléments)). `size.width` / `size.height` fixent la longueur du filet ; `width: 'fill'` correspond à l’ancien `'full'`. |

### Éléments boîte

Les éléments boîte peignent un rectangle aux coins arrondis dans l’emplacement : un fond derrière le texte d’une ouverture de chapitre, d’un encart latéral ou d’un pied de page, par exemple. Les éléments boîte se positionnent exclusivement par le champ `placement` ; ils n’ont pas d’ancienne forme abrégée à plat. Le remplissage, le trait et le rayon des coins se trouvent dans l’objet imbriqué `style` (`ElementBoxStyle`), comme dans l’exemple JSON de « Placement des éléments ».

| Propriété | Type | Défaut | Description |
| --- | --- | --- | --- |
| `kind` | `'box'` | — | Discriminant. |
| `id` | `string` | — | Identifiant stable, unique dans l’emplacement. Les éléments voisins s’y ancrent avec `anchor.to: '#id'`. Le Sandbox en attribue un à la création. |
| `style.backgroundColor` | `ColorValue` | `transparent` | Couleur de remplissage. Réglez-la sur `transparent` pour une boîte réduite à son contour. |
| `style.borderColor` | `ColorValue` | `transparent` | Couleur du trait. |
| `style.borderWidth` | `Dimension` | `0 pt` | Épaisseur du trait. Les traits sont peints à l’intérieur du rectangle englobant de la boîte afin que ses dimensions extérieures restent constantes : le bord extérieur du trait suit le bord de la boîte, et une boîte arrondie garde son rayon extérieur. Un trait aussi large que la boîte la remplit. Canvas, HTML et PDF le dessinent à l’identique (jusqu’à postext 1.4, le canvas et le PDF centraient le trait sur le bord, une moitié hors de la boîte). |
| `style.borderRadius` | `Dimension` | `0 pt` | Rayon des coins. Limité à la moitié du plus petit côté au moment du rendu. |
| `placement` | `ElementPlacement` | — | Obligatoire. Voir « Placement des éléments » ci-dessous. |
| `parity` | `'all' \| 'odd' \| 'even'` | `'all'` | Pages sur lesquelles la boîte apparaît. |
| `pages` | `'all' \| 'body' \| 'opener' \| 'part' \| 'blank'` | `'all'` | Rôles de page sur lesquels la boîte apparaît (voir le champ `pages` des éléments de texte). |
| `reserve` | `boolean` | `true` | Designs de titre uniquement : indique si la boîte compte dans la hauteur que le titre réserve dans le flux du texte (voir [Hauteur réservée](https://postext.dev/fr/docs/configuration-headings.md#hauteur-réservée)). |

### Éléments image

Un élément `image` dessine une ressource bitmap ou SVG du document : le logo d’un éditeur sur une page de titre, une marque dans un titre courant. Sa taille vient de son `placement.size` : si l’un des côtés `width` / `height` est laissé à `'auto'` (la valeur par défaut), l’autre suit les proportions de l’image ; si les deux sont définis, l’image est ajustée dans la boîte et centrée. Une ressource absente ou qui n’est pas une image ne dessine rien.

```ts
{
  kind: 'image', id: 'logo', resourceId: 'logo-publisher',
  placement: { anchor: { to: 'page', edge: 'top-left' }, offset: { x: { value: 64, unit: 'mm' }, y: { value: 233, unit: 'mm' } }, size: { width: { value: 83, unit: 'mm' }, height: 'auto' } },
}
```

`resourceId` accepte les variables que prend le `content` d’un élément de texte, si bien qu’un même design peut dessiner une image différente pour chaque titre. Avec `resourceId: '{attr.vignette}'` dans un style de titre, `# Chapter I {style="opener" vignette="log"}` dessine la ressource `log` et `# Chapter II {style="opener" vignette="wig"}` dessine `wig` : les chapitres partagent le style au lieu d’en avoir un clone par image. Un en-tête ou un pied de page lit les attributs du chapitre de la page, comme le fait `{attr.<key>}` dans un titre courant, et les autres variables fonctionnent aussi (`'map-{chapterNumber}'`). Un identifiant qui ressort vide, par exemple pour un titre sans l’attribut, ne dessine rien. Depuis postext 1.8.

| Propriété | Type | Défaut | Description |
| --- | --- | --- | --- |
| `id` | `string` | — | Identifiant stable ; d’autres éléments peuvent s’y ancrer sous la forme `#id`. |
| `resourceId` | `string` | — | Identifiant d’une `Resource` bitmap ou SVG du document. Il peut contenir des variables, dont `{attr.<key>}`, remplies par titre, par partie ou par page. |
| `decorative` | `boolean` | `false` | L’image n’est qu’une décoration (un ornement, une bande) : elle ne fournit aucun texte alternatif à la sortie, même si sa ressource en a un (voir plus bas). |
| `placement` | `ElementPlacement` | — | Ancre, décalage et taille (voir [Placement des éléments](https://postext.dev/fr/docs/configuration-headers-footers.md#placement-des-éléments)). Un côté `'fill'` s’étend jusqu’au bord du conteneur. |
| `parity`, `pages` | comme ci-dessus | `'all'` | Pages sur lesquelles l’image apparaît. |
| `reserve` | `boolean` | `true` | Designs de titre uniquement : indique si l’image compte dans la hauteur que le titre réserve dans le flux du texte (voir [Hauteur réservée](https://postext.dev/fr/docs/configuration-headings.md#hauteur-réservée)). |

Le moteur de rendu PDF incorpore la ressource comme une figure (un SVG doté d’un original d’impression utilise celui-ci) ; la visionneuse HTML la résout par `resourceImageUrl`.

Une image dessinée par un design est du contenu lorsque sa ressource la décrit : l’`altText` de la ressource, ou à défaut sa légende en texte brut (une pastille lue par son libellé, un `:ref` par son `text` s’il en a un), entre dans le VDT (`VDTDesignImageBlock.altText`), devient l’`alt` de son `<img>` en HTML et une `Figure` avec `/Alt` dans un PDF balisé, lue juste après le texte de son design (la planche d’un chapitre après le titre du chapitre). Une image dont la ressource n’a ni l’un ni l’autre, ou qui est marquée `decorative`, est une décoration : `alt=""` avec `role="presentation"`, et un artefact dans le PDF. L’image d’un titre courant ou d’un pied de page se répète sur chaque page : elle relève donc de l’habillage de la page, quoi que dise sa ressource : pas d’`altText` dans le VDT, `alt=""` avec `role="presentation"` en HTML, un artefact de la page dans le PDF.

### Placement des éléments

`ElementPlacement` est le modèle de positionnement unifié qu’utilisent tous les types d’éléments (texte, filet, boîte) dans n’importe quel emplacement de design : en-tête de page, pied de page ou emplacement de design avancé d’un niveau de titre. Trois données décrivent un placement :

```ts
interface ElementPlacement {
  /** What this element anchors to and which edge of that target. */
  anchor: {
    to: 'container' | 'page' | 'bleed' | 'outer' | `#${string}`; // container = the slot; page = trim box; bleed = trim box + bleed; outer = the outer margin (header, footer); #id = another element
    edge: AnchorEdge;
  };
  /** Distance from the anchor point. */
  offset?: { x?: Dimension; y?: Dimension };
  /** Optional fixed width / height. Width also accepts 'fill' (span the slot).
   *  `maxWidth` caps an 'auto' width (text): the element still shrink-wraps its
   *  content, so elements anchored to it stay attached, but a long text wraps or
   *  ellipsizes there — a running head can reserve room for the label hanging
   *  off it instead of squeezing that label out. */
  size?: { width?: Dimension | 'fill' | 'auto'; height?: Dimension | 'fill' | 'auto'; maxWidth?: Dimension };
}
```

`AnchorEdge` accepte :

- **Bords du conteneur** (lorsque `anchor.to` vaut `'container'`, `'page'` ou `'bleed'`) : `top`, `top-left`, `top-right`, `bottom`, `bottom-left`, `bottom-right`, `left`, `right`.
- **Bords relatifs à un élément** (lorsque `anchor.to === '#someId'`) : `right-of`, `left-of`, `below`, `above`, `align-top`, `align-bottom`, `align-left`, `align-right`.

Chaque bord relatif à un élément place un coin de l’élément sur un coin de l’élément auquel il s’ancre, et `offset` le déplace à partir de là :

- `right-of` : son coin supérieur gauche sur le coin supérieur droit de la cible (à côté d’elle, sommets alignés) ; `left-of` : son coin supérieur droit sur le coin supérieur gauche de la cible ;
- `below` : son coin supérieur gauche sur le coin inférieur gauche de la cible (en dessous, bords gauches alignés) ; `above` : son coin inférieur gauche sur le coin supérieur gauche de la cible ;
- `align-top` et `align-left` : son coin supérieur gauche sur le coin supérieur gauche de la cible. Les deux noms donnent le même placement : les bords supérieurs comme les bords gauches s’alignent ;
- `align-bottom` : son coin inférieur gauche sur le coin inférieur gauche de la cible ;
- `align-right` : son coin supérieur droit sur le coin supérieur droit de la cible.

Un bord relatif à un élément utilisé avec `'container'`, `'page'` ou `'bleed'`, et un bord de conteneur utilisé avec `'#id'`, sont lus comme le coin supérieur gauche.

`anchor.to: 'page'` ancre l’élément à la **zone de coupe** (la page physique après rognage) et `'bleed'` à la zone de coupe agrandie de `cutLines.bleed` de chaque côté (identique à la zone de coupe tant que les traits de coupe sont désactivés). Ces deux cadres servent aussi de référence pour `size: 'fill'` et pour la limitation automatique de la largeur, si bien qu’une bande de couleur peut aller d’un bord à l’autre quelles que soient les marges de la page :

```json
{ "kind": "box", "id": "band", "placement": { "anchor": { "to": "bleed", "edge": "top-left" }, "size": { "width": "fill", "height": { "value": 6, "unit": "cm" } } }, "style": { "backgroundColor": { "hex": "#1d3557", "model": "hex" } } }
```

Avec les traits de coupe activés, tout ce qu’un élément peint au-delà de la zone de fond perdu est rogné (voir [Traits de coupe](https://postext.dev/fr/docs/configuration-page-layout.md#traits-de-coupe)).

`anchor.to: 'outer'` (emplacements d’en-tête et de pied de page) ancre l’élément à la **marge extérieure** de la page : du bord du bloc de texte au bord de coupe, du côté opposé au dos, et de la tête du bloc de texte à son pied. Elle se trouve à droite d’un recto et à gauche d’un verso dans un livre relié à gauche, et inversement dans un livre relié à droite (`page.binding`), si bien qu’un seul élément sert aux deux pages d’une double page : un titre courant le long de la marge extérieure, par exemple (voir [Éléments de texte vertical](https://postext.dev/fr/docs/configuration-headers-footers.md#éléments-de-texte-vertical)). Dans tout autre emplacement, elle se lit comme `'container'`. L’`offset` d’un élément de texte peut s’écrire en `em`, c’est-à-dire en cadratins de sa propre `fontSize` : quatre caractères sous la tête du bloc de texte s’écrivent `{ "y": { "value": 4, "unit": "em" } }`.

Dans l’emplacement de design avancé d’un titre, les éléments ancrés à la page ou au fond perdu n’augmentent pas la hauteur réservée au titre, sauf s’ils descendent sous le bord supérieur du titre (une bande en haut de la page se place derrière l’ouverture ; une bande qui descend sous le titre repousse le texte courant). Utilisez `advancedDesign.minHeight` pour réserver malgré tout une hauteur d’ouverture fixe, et `reserve: false` sur un élément qui ne doit pas du tout repousser le texte. Les règles complètes se trouvent sous [Hauteur réservée](https://postext.dev/fr/docs/configuration-headings.md#hauteur-réservée).

Chaque élément a un `id` stable (attribué automatiquement par le Sandbox ; vous pouvez aussi le définir à la main). Les éléments ancrés à d’autres éléments forment un petit graphe de dépendances que le moteur résout avant la mesure, si bien qu’un élément peut s’enchaîner à un autre sans coordonnées manuelles.

L’ancienne forme `align` + `marginFromBody` + `marginFromEdge` est analysée en entrée et réécrite en placement au moment de la résolution de la configuration : les configurations existantes continuent donc de fonctionner sans changement.
