# Pyramid Plume: technical reference for AI assistants

> Power BI custom visual by Plume Studio (Plume Visuals). Visual version **1.1.0.0**. This page is generated from the visual's source code at each site build: field names, option names and defaults are exact for this version.

Use it to help someone build a report with Pyramid Plume: which fields to drag, how to shape the data, which Format pane option to change, or how to write the visual's settings in a PBIP `visual.json` file.

- Product page: https://plumevisuals.com/en/visuals/population-pyramid (French: https://plumevisuals.com/fr/visuels/population-pyramid)
- Summary: The age pyramid that comes alive: drop the age, the sex and the population, press ▶ and watch generations climb year after year.
- Power BI visual GUID (`visualType`): `plumePopulationPyramid247171417FEF4CFEA0FEE64FE39F53DF`
- Power BI visuals API: 5.11.1
- Support: https://plumevisuals.com/support · contact@plumevisuals.com
- Index of everything on the site for AI assistants: https://plumevisuals.com/llms.txt

## What the visual does

Pyramid Plume (identifier `population-pyramid`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission being prepared) that draws **population pyramids** (age pyramids) and, more generally, **butterfly / tornado charts**: two sides face to face, one row per category. Power BI Desktop has no native population pyramid (the usual workaround is a stacked bar chart with one side made negative).

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (`ageAxis` → `catAxis`, gridlines in **Gridlines**); hatched surplus with an "Excess" key, neutral vocabulary option (non-age data), shared Gridlines card.

- **Three fields**: `age` (an age or age band, or any category), `side` (the sex or any two-value field), `value` (a measure). Without `side`, two measures in `value` face each other (butterfly chart).
- **Ages in natural numeric order with no sort column**: the visual reads the number in each label ("0-4", "5 à 9 ans", "100 ans et +", "85+", "under 5", Eurostat codes `Y_LT5`, `Y5-9`, `Y_GE85`) and sorts by itself; young at the bottom. Labels without numbers keep the model order (or are sorted by total for a tornado).
- **Positive values on both sides**: both sides start from the center with positive ticks; negative values (the usual workaround) are read as absolute values.
- **Age bands computed in the visual** ★: 2, 5, 10 or 20-year bands from single ages and an open last band ("90+"), with no calculated column.
- Counts, % of the total population or % of each side; side headers with name, total and share; ★ surplus of one side (darker shade); ★ median and mean age lines (Analytics pane); ★ birth years next to the ages.
- **Play axis ★** (`play` role, a year or date column; premium since the free / premium rebalancing of 2026-10-22): the shared Plume player (play / pause, slider, speed ×0.5 to ×4, loop, keyboard) animates bars, totals and labels year after year, with a fixed scale by default. Playback is per session, never saved in the report.
- Men stay on the left even when the data starts with women; `pyramid.swap` swaps the sides.

## Free vs premium (★)

- Every feature works without a key and nothing is ever blocked. Free features never show a watermark.
- Shared Style card (the same in every Plume visual): the styles `none`, `minimal` and `blackWhite`, the two Plume gradient palettes (`crest`, `crestDiverging`), "Follow report theme" and all custom colors are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Pyramid Plume: the age / side / value fields, butterfly mode, numeric ordering, bands already in the data, counts and shares, side headers, data labels, axes, scale maximum, own scale per side, colors, cross-filtering, highlighting, tooltips.
- Premium features of Pyramid Plume:
  - the `play` role ("Play axis ★": watermark as soon as the field holds data, even one year; the Playback settings themselves add nothing);
  - `ages.band` = `2`, `5`, `10` or `20` and `ages.openFrom` > 0 (computed bands, on numeric ages); `pyramid.excess` = `shade` or `outline` (surplus of one side, with two sides); `catAxis.birthYears` (with a known year); `ageLines.median` and `ageLines.mean` (Analytics pane, numeric ages);
  - the `compare` role ("Comparison ★") and the comparison with a frame of the play axis (`comparison.source` = `first`, `previous` or `frame`): outline, ghost bars or markers;
  - `generation.follow` (follow a generation: the cohort born in a given year is highlighted and climbs while playing) and `generation.marks` (generation markers: "1946-1964 = Baby boom");
  - `indicators.show` (demographic indicators: population, median and mean age, shares of young and older people, dependency ratio, ageing index, side ratio);
  - `projection.show` (frames from a given year drawn hatched, pale or dashed, with a "Projection" tag);
  - the `stack` role ("Sub-category ★", stacked from the center) and the `multiples` role ("Small multiples ★").
- The watermark depends on features actually applied: a generation or birth years with no known year (no play axis, `ages.year` = 0), a comparison without its field, bands or median / mean lines on non-numeric categories, or a surplus with a single side draw nothing and show no watermark.
- Without a valid key, a premium feature in use shows, in edit mode, a "Premium preview" note in the footer; in reading view, **"Plume Visuals · Premium preview"** (French « Plume Visuals · Aperçu premium ») is repeated lightly across the whole visual, without catching the mouse. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`), the **first card** of the Format pane.
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `population-pyramid` or the whole catalog. Licenses last one year (one-time payment, no automatic renewal). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack.

## Expected data shape

One row per age (or band), per sex and, to animate, per year: `Population[Age]` (whole number or text band), `Population[Sex]` (two values), `Population[Year]` (whole number or date), `Population[Residents]`. The measure is a plain sum.

```dax
Number of residents = SUM ( Population[Residents] )
// Comparison ★ with the whole country while a slicer picks one area (compare shapes with pyramid.measure = pctTotal)
Residents of all areas = CALCULATE ( [Number of residents], REMOVEFILTERS ( Population[Area] ) )
// Comparison ★ with a fixed year
Residents in 1975 = CALCULATE ( [Number of residents], REMOVEFILTERS ( Population[Year] ), Population[Year] = 1975 )
```

Butterfly chart: no `side` field, two measures in `value` (e.g. satisfied managers and satisfied employees), any category in `age`; `ages.order` = `valueDesc` for a tornado; `pyramid.scaleMode` = `perSide` for measures with different units.

## Interactions with the report

- Click a bar: cross-filter on its age (or band: every age in it) and side; the selection is **not** tied to the year, so it stays while playing. Ctrl for several; click a side header = all bars of that side; click an empty area = clear. Cross-highlighting from other visuals draws the highlighted part inside dimmed bars. Context menu everywhere, including the landing screen.
- Hover: Power BI tooltip with age, side, value, share of the total and of the side, comparison and difference, Tooltips measures (summed when ages are grouped); report-page tooltips are supported.
- Keyboard: Tab to the play bar (Space play / pause, arrows, Home, End) or to the chart (arrows browse bars, Enter selects, Esc clears). High contrast, ARIA labels, French and English.

## Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `title.text`, `pyramid.measure`, `generation.birthFrom`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key.

```dax
// renamed title.text
Title = "Age pyramid: " & SELECTEDVALUE ( Population[Area], "all areas" )
```

## Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `pyramid`, `ages`, `catAxis`, `valAxis`, `labels`, `legend`, `comparison`, `generation`, `indicators`, `projection`, `smallMultiples`, `play`, `ageLines` (Analytics pane), `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `pyramid`, `ages`, `labels`, `catAxis`, `valAxis`, `gridlines`, `legend`, `comparison`, `generation`, `indicators`, `projection`, `smallMultiples`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`; Analytics pane: `ageLines`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`auto` | `single`), `single`, `fill`, `excessColor`.
- `pyramid`: `measure` (`value` | `pctTotal` | `pctSide`), `swap`, `sideHeaders` (on), `headerShare` (on), `headerSize` (7–24, 11), `thickness` (20–100, 88), `radius` (0–12, 1), `opacity` (10–100, 100), `border`, `excess` (`none` | `shade` ★ | `outline` ★), `fixedScale` (on), `scaleMode` (`shared` | `perSide`), `max`.
- `ages`: `order` (`auto` | `model` | `valueDesc` | `valueAsc` | `labelAsc`), `direction` (`auto` | `bottomUp` | `topDown`), `band` (`1` | `2` ★ | `5` ★ | `10` ★ | `20` ★), `openFrom` ★ (0–150, 0), `year` (0–3000, 0), `convention` (`reached` | `completed`).
- `catAxis`: `show` (on), `position` (`center` | `left` | `right`), `fontSize` (6–24, 9), `color`, `every` (`auto` | `1` | `5` | `10`), `gap` (0–40, 2), `showTitle` (on), `titleText`, `birthYears` ★.
- `valAxis`: `show` (on), `fontSize` (6–24, 9), `color`, `units` (`auto` | `none` | `k` | `m` | `b`), `decimals` (-1–6, -1), `prefix`, `suffix`, `ticks` (1–10, 3), `showTitle`, `titleText`, `gridlines.vShow` (on), `gridlines.vStyle` (`solid` | `dashed` | `dotted`), `gridlines.vColor`.
- `labels`: `show`, `content` (`value` | `pctTotal` | `pctSide` | `valuePct`), `minRow` (4–40, 10), `fontSize` (6–24, 10), `color`, `bold`, `halo` (on), `declutter` (on), `units` (`auto` | `none` | `k` | `m` | `b`), `decimals` (-1–6, -1), `prefix`, `suffix`.
- `legend`: `show` (on), `position` (`top` | `bottom` | `right` | `left`), `align` (`left` | `center` | `right`), `showTitle`, `titleText`, `fontSize` (6–24, 9), `color`, `interactive` (on).
- `comparison`: `show` (on), `source` (`field` | `first` ★ | `previous` ★ | `frame` ★), `frameName`, `style` (`outline` | `ghost` | `marker`), `color`, `width` (0.5–6, 1.5), `lineStyle` (`solid` | `dashed` | `dotted`), `label`.
- `generation`: `follow` ★, `birthFrom` (1000–3000, 1946), `birthTo` (0–3000, 0), `label`, `color`, `marks` ★, `marksColor`.
- `indicators`: `show` ★, `position` (`topLeft` | `topRight` | `bottomLeft` | `bottomRight`), `total` (on), `median` (on), `mean`, `youngShare` (on), `oldShare` (on), `dependency` (on), `ageing`, `ratio`, `youngMax` (1–40, 20), `oldMin` (40–100, 65), `fontSize` (7–20, 10).
- `projection`: `show` ★, `from`, `style` (`hatch` | `pale` | `outline`), `label`.
- `smallMultiples`: `columns` (0–12, 0), `gap` (0–60, 14), `titleSize` (6–24, 10), `titleTotal` (on), `border`.
- `play` (card « Lecture ★ » / "Playback ★", shown with the Play axis ★ field): `start` (`last` | `first`), `speed` (100–10000, 1000), `loop`, `autoPlay`, `transition` (on), `controls` (on), `position` (`bottom` | `top`), `ticks` (`auto` | `all` | `none`), `tickLabels` (on), `stepButtons` (on), `speedButton` (on), `showLabel` (on), `labelSize` (12–160, 44), `labelPosition` (`bottomRight` | `topRight` | `topLeft` | `bottomLeft` | `center`; default `topRight`).
- `ageLines` (Analytics pane): `median` ★, `mean` ★, `per` (`side` | `total`), `color`, `style` (`solid` | `dashed` | `dotted`; default `dashed`), `width` (0.5–6, 1.5), `showLabel` (on).
- `interaction`: `hover` (on), `dim` (5–80, 25).
- `ages.year` (0 = read from the play axis) and `ages.convention` (`reached`: born in 1946 = 74 in 2020; `completed`: 73 on January 1, 2020) are used by birth years and generations. `pyramid.max` is text (e.g. `500000`, or `5` for 5 % in percent mode).

## Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumePopulationPyramid247171417FEF4CFEA0FEE64FE39F53DF",
  "query": {
    "queryState": {
      "age":   { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Population" } }, "Property": "Age" } }, "queryRef": "Population.Age", "nativeQueryRef": "Age" } ] },
      "side":  { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Population" } }, "Property": "Sex" } }, "queryRef": "Population.Sex", "nativeQueryRef": "Sex" } ] },
      "value": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Population" } }, "Property": "Number of residents" } }, "queryRef": "Population.Number of residents", "nativeQueryRef": "Number of residents" } ] },
      "play":  { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Population" } }, "Property": "Year" } }, "queryRef": "Population.Year", "nativeQueryRef": "Year" } ] }
    }
  },
  "objects": {
    "ages":       [ { "properties": { "band": { "expr": { "Literal": { "Value": "'5'" } } }, "openFrom": { "expr": { "Literal": { "Value": "90D" } } } } } ],
    "pyramid":    [ { "properties": { "measure": { "expr": { "Literal": { "Value": "'pctTotal'" } } }, "excess": { "expr": { "Literal": { "Value": "'shade'" } } } } } ],
    "generation": [ { "properties": { "follow": { "expr": { "Literal": { "Value": "true" } } }, "birthFrom": { "expr": { "Literal": { "Value": "1946D" } } } } } ],
    "license":    [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

## Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. Side colors default to series colors 1 and 2 of the style; colors chosen in Data colors win.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text. Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

## Common pitfalls

- Bands in alphabetical order: the labels contain no number ("Young", "Seniors"); use labels with ages or a sort-by column with `ages.order` = `model`.
- Both sides named after the measure: no `side` field (butterfly mode); put the sex in `side` and a single measure in `value`.
- "only … and … are drawn": the side field has more than two values.
- The pyramid adds up every year: no year is filtered and the year is not in `play` ★.
- No generation band, no birth years: unknown year (no play axis in years, `ages.year` = 0), or ages not numeric / not in automatic order; the generation is older than the last age.
- No data labels: rows shorter than `labels.minRow`; group ages or lower it.
- Watermark visible: play axis, computed bands, surplus of one side, birth years, median or mean age lines, comparison, followed generation, generation markers, indicators, projection, sub-category, small multiples, a ★ style or a theme JSON, without a valid key.
- The visual makes no network request: data and license key stay in the report; no R or Python.

## Features that do NOT exist (do not suggest them)

More than two sides (a third side value is ignored), error bars or vertical reference lines at a value, sorting one side independently of the other, images or flags, a population projection computed by the visual (projections come from the data; the visual only draws them differently), saving the playing year in the report, exporting the animation as a video or GIF.

## Data fields (wells)

Internal name = data role name (PBIP `queryState` key). Labels as shown in Power BI (English / French). ★ = premium.

| Internal name | Label (EN) | Label (FR) | Kind | Max fields | Description |
|---|---|---|---|---|---|
| `age` | Age (or age band, category) | Âge (ou tranche, catégorie) | column | 1 | One row per age or age band (0, 1, 2… or "0-4", "5-9", "100+"): sorted in natural numeric order. Any category for a butterfly chart. |
| `side` | Side (sex or any two-value field) | Côté (sexe ou champ à deux valeurs) | column | 1 | Two values face to face (men / women, before / after…). Without it, put two measures in Value. |
| `value` | Value (or two measures face to face) | Valeur (ou deux mesures face à face) | measure | 2 | Population, headcount… Negative values (the usual workaround) are read as positive. Without Side: two measures, one per side. |
| `play` | Play axis ★ | Axe de lecture ★ | column | 1 | Premium: year or date: the pyramid moves from one year to the next (play button), bars animated. |
| `compare` | Comparison ★ | Comparaison ★ | measure | 2 | Premium: another year, another territory or a target, drawn as an outline over the bars (one measure, or one per side without Side). |
| `stack` | Sub-category ★ | Sous-catégorie ★ | column | 1 | Premium: splits each bar (nationality, activity, region…), stacked from the center. |
| `multiples` | Small multiples ★ | Petits multiples ★ | column | 1 | Premium: one pyramid per value (region, country…), same scale. |
| `tooltips` | Tooltips | Infobulles | measure | 5 |  |
| `format` | Dynamic format | Format dynamique | measure | several | Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX |

Data view: categorical, categories = `age` + `play` + `stack` + `multiples` + `side` (one row per combination), 30,000 rows per data window (more fetched automatically); measures = `value`, `compare`, `tooltips`, `format`.
Capabilities: supportsHighlight, supportsKeyboardFocus, supportsMultiVisualSelection, supportsLandingPage, supportsEmptyDataView.
Network access: none (no privileges requested, no external request).

## Format pane options (197)

Columns: option ID (`object.property`), labels EN / FR as shown in Power BI, control type, PBIP literal type, default value, allowed values, notes.

### Plume Studio License / Licence Plume Studio (`license`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `license.buy` | Get a license | Obtenir une licence | info | text | `plumevisuals.com` |  |  |
| `license.key` | License key | Clé de licence | text | text | (empty) |  | Paste the key received after purchase on plumevisuals.com (starts with PLUM1.). Checked offline. |
| `license.showOwner` | Show license holder (edit mode) | Afficher le titulaire (mode édition) | toggle | bool | `true` | true / false |  |

### Style (`style`, Format pane)

**Style**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `style.preset` | Style | Style | dropdown | enumeration | `none` | `none` None; `minimal` Minimal; `blackWhite` Black & White; `press` Newspaper ★; `vintage` Vintage (antique plate) ★; `earth` Earth ★; `nordic` Nordic ★; `executive` Executive ★; `accessible` Accessible (high legibility) ★; `pastel` Pastel ★; `bauhaus` Bauhaus (pop) ★; `climate` Climate ★; `blueprint` Blueprint ★; `unknownPleasures` Unknown Pleasures ★; `dark` Graphite (dark) ★; `neon` Neon ★; `terminal` Terminal (Matrix) ★; `infographic` Infographic ★; `cockpit` Cockpit (HUD) ★; `hologram` Hologram ★ | Complete look shared by all Plume visuals: colors, three palettes, fonts, frame, table header, marks and effects. Customize colors below. |
| `style.themeJson` | Theme JSON ★ | Thème JSON ★ | textarea | text | (empty) |  | Paste a JSON theme: see the 'JSON themes' tutorial on plumevisuals.com |
| `style.followTheme` | Follow report theme | Suivre le thème du rapport | toggle | bool | `false` | true / false | Text, background, accent and data colors come from the Power BI report theme. |
| `style.reverse` | Reverse gradients | Inverser les dégradés | toggle | bool | `false` | true / false |  |

**Custom colors / Couleurs personnalisées**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `style.customColors` | Customize colors | Personnaliser les couleurs | toggle | bool | `false` | true / false | Start from the style and pick your own colors. A color left empty keeps the style's color. |
| `style.colorBackground` | Background | Fond | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorText` | Text | Texte | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorMuted` | Secondary text | Texte secondaire | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorGrid` | Lines and grid | Traits et grille | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorAccent` | Accent | Accent | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorPositive` | Favorable | Favorable | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorNegative` | Unfavorable | Défavorable | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series1` | Series 1 | Série 1 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series2` | Series 2 | Série 2 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series3` | Series 3 | Série 3 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series4` | Series 4 | Série 4 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series5` | Series 5 | Série 5 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series6` | Series 6 | Série 6 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series7` | Series 7 | Série 7 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series8` | Series 8 | Série 8 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.palette` | Gradient palette | Palette du dégradé | dropdown | enumeration | `auto` | `auto` Style or theme palette; `crest` Plume (sequential); `crestDiverging` Plume (diverging); `viridis` Viridis ★; `magma` Magma ★; `inferno` Inferno ★; `cividis` Cividis (colorblind-safe) ★; `warmingStripes` Warming stripes ★; `rdYlBu` Red–Yellow–Blue ★; `brBG` Brown–Teal (drought) ★; `spectral` Spectral ★; `blues` Blues ★; `reds` Reds ★; `grays` Grays ★; `press` Press (ink and paper) ★; `nordic` Nordic ★; `earth` Earth (ochre to umber) ★; `pastel` Pastel ★; `okabeIto` Okabe-Ito (colorblind-safe) ★ | Visible when `style.customColors` = `true`. Gradient from the catalog (Viridis, Magma…). The start, middle and end colors below replace it. |
| `style.scaleLow` | Gradient: start | Dégradé : début | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.scaleMid` | Gradient: middle (diverging) | Dégradé : milieu (écarts) | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.scaleHigh` | Gradient: end | Dégradé : fin | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |

**Text / Texte**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `style.fontFamily` | Font | Police | font | formatting | `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif` |  | Used by every text of the visual (title, axes, labels, cells). |

**Animations**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `style.animate` | Animations | Animations | toggle | bool | `true` | true / false | Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion. |

### Data colors / Couleurs des données (`dataColors`, Format pane)

Per-item card: Power BI shows it once per series, category, column or KPI (an "Apply settings to" list where relevant). In PBIP `visual.json`, each entry of `objects.dataColors` carries a `selector` (`metadata` = the field's queryRef, or `data` for a category value); an entry without a selector applies to all items.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `dataColors.mode` | Coloring | Coloration | dropdown | enumeration | `auto` | `auto` One color per side (or per sub-category); `single` Single color |  |
| `dataColors.single` | Color | Couleur | color | fill | (empty) | hex color |  |
| `dataColors.fill` | Color | Couleur | color | fill | (empty) | hex color |  |
| `dataColors.excessColor` | Surplus (empty = darker shade of the side) | Excédent (vide = teinte foncée du côté) | color | fill | (empty) | hex color |  |

### Pyramid / Pyramide (`pyramid`, Format pane)

**Displayed values / Valeurs affichées**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `pyramid.measure` | Show | Afficher | dropdown | enumeration | `value` | `value` Counts (values); `pctTotal` % of the total population; `pctSide` % of each side | In %, two pyramids of different sizes (two territories, two years) compare by their shape. |
| `pyramid.swap` | Swap sides | Inverser les côtés | toggle | bool | `false` | true / false | By default, "Men" (or the first value) on the left. |
| `pyramid.sideHeaders` | Side headers (name and total) | En-tête des côtés (nom et total) | toggle | bool | `true` | true / false |  |
| `pyramid.headerShare` | Share of each side in the header | Part de chaque côté dans l'en-tête | toggle | bool | `true` | true / false | Visible when `pyramid.sideHeaders` = `true` |
| `pyramid.headerSize` | Header size | Taille de l'en-tête | number | formatting | `11` | 7 to 24 | Visible when `pyramid.sideHeaders` = `true` |

**Bars / Barres**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `pyramid.thickness` | Bar thickness (%) | Épaisseur des barres (%) | number | integer | `88` | 20 to 100 |  |
| `pyramid.radius` | End rounding | Arrondi du bout | number | integer | `1` | 0 to 12 |  |
| `pyramid.opacity` | Opacity (%) | Opacité (%) | number | integer | `100` | 10 to 100 |  |
| `pyramid.border` | Outline | Contour | toggle | bool | `false` | true / false |  |
| `pyramid.excess` | Surplus of one side | Excédent d'un côté | dropdown | enumeration | `none` | `none` Not marked; `shade` Hatching at the end of the bar ★; `outline` Outline of the opposite side ★ | The part of a bar beyond the opposite one (e.g. more women at old ages): hatched in the side color, with an outline, so it is not read as a second series. |
| `pyramid.excessLegend` | Surplus legend | Légende de l'excédent | toggle | bool | `true` | true / false | Visible when `pyramid.excess` = `shade` or `outline`. A "Surplus" key under the pyramid explains the hatching (or the outline). |

**Scale / Échelle**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `pyramid.fixedScale` | Same scale for every frame of the play axis | Échelle fixe sur toutes les images du lecteur | toggle | bool | `true` | true / false | Off: the scale adapts to each year. |
| `pyramid.scaleMode` | Scale of both sides | Échelle des deux côtés | dropdown | enumeration | `shared` | `shared` Shared; `perSide` Own scale per side (two measures) | Own scale per side: two measures with different units (headcount and seniority). |
| `pyramid.max` | Scale maximum | Maximum de l'échelle | text | text | (empty) |  |  |

### Ages and categories / Âges et catégories (`ages`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `ages.order` | Order | Ordre | dropdown | enumeration | `auto` | `auto` Automatic (ages in numeric order); `model` Model order; `valueDesc` Total, descending (tornado); `valueAsc` Total, ascending; `labelAsc` Name A → Z | Automatic: "5-9" before "10-14", "100+" last, no sort column needed. |
| `ages.direction` | Direction | Sens | dropdown | enumeration | `auto` | `auto` Automatic (young at the bottom); `bottomUp` First category at the bottom; `topDown` First category at the top |  |
| `ages.band` | Group ages | Regrouper les âges | dropdown | enumeration | `1` | `1` No (ages as in the data); `2` 2-year bands ★; `5` 5-year bands ★; `10` 10-year bands ★; `20` 20-year bands ★ | Computed by the visual from single ages (0, 1, 2…): no band column to create. |
| `ages.openFrom` | Open last band from (0 = no) ★ | Dernière tranche ouverte à partir de (0 = non) ★ | number | integer | `0` | 0 to 150 | E.g. 90: everyone aged 90 and over in "90+". |
| `ages.year` | Observation year (0 = play axis) | Année d'observation (0 = axe de lecture) | number | integer | `0` | 0 to 3000 | Used for birth years and generations. Read from the play axis when it is a year or a date. |
| `ages.convention` | Age counted as | Âge compté | dropdown | enumeration | `reached` | `reached` Age reached during the year; `completed` Completed age on January 1 | Born in 1946: 74 in 2020 (age reached) or 73 on January 1, 2020 (completed age). |
| `ages.vocabulary` | Wording | Vocabulaire | dropdown | enumeration | `auto` | `auto` Automatic (ages when the field is about age); `ages` Ages (years, median age…); `neutral` Neutral (categories, values) | Neutral: tooltips, indicators and markers say "category", "median", "under 20" instead of "age", "median age", "under 20 years". |

### Data labels / Étiquettes de données (`labels`, Format pane)

The card header toggle is `labels.show`.

**Labels / Étiquettes**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `labels.show` | Show | Afficher | toggle | bool | `false` | true / false |  |
| `labels.content` | Content | Contenu | dropdown | enumeration | `value` | `value` Value; `pctTotal` Share of the total population; `pctSide` Share of its side; `valuePct` Value and share of the total |  |
| `labels.minRow` | Minimum row height (px) | Hauteur de ligne minimale (px) | number | integer | `10` | 4 to 40 | Labels are hidden when a row is shorter (many single ages). |
| `labels.fontSize` | Size | Taille | number | formatting | `10` | 6 to 24 |  |
| `labels.color` | Color (empty = automatic) | Couleur (vide = automatique) | color | fill | (empty) | hex color | Automatic: readable color depending on the background (inside bars: white or dark). |
| `labels.bold` | Bold | Gras | toggle | bool | `false` | true / false |  |
| `labels.halo` | Text halo | Halo autour du texte | toggle | bool | `true` | true / false |  |
| `labels.declutter` | Hide overlapping labels | Masquer les étiquettes qui se chevauchent | toggle | bool | `true` | true / false |  |

**Numbers / Nombres**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `labels.units` | Display units | Unités d'affichage | dropdown | enumeration | `auto` | `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions |  |
| `labels.decimals` | Decimals (-1 = auto) | Décimales (-1 = auto) | number | integer | `-1` | -1 to 6 |  |
| `labels.prefix` | Prefix | Préfixe | text | text | (empty) |  |  |
| `labels.suffix` | Suffix (e.g. €) | Suffixe (ex. €) | text | text | (empty) |  |  |

### Category axis / Axe des catégories (`catAxis`, Format pane)

The card header toggle is `catAxis.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `catAxis.show` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `catAxis.position` | Position | Position | dropdown | enumeration | `center` | `center` Center (between the sides); `left` Left; `right` Right |  |
| `catAxis.fontSize` | Size | Taille | number | formatting | `9` | 6 to 24 |  |
| `catAxis.color` | Color (empty = secondary text) | Couleur (vide = texte secondaire) | color | fill | (empty) | hex color |  |
| `catAxis.every` | Labels | Étiquettes | dropdown | enumeration | `auto` | `auto` Automatic (no overlap); `1` All; `5` Every 5 years; `10` Every 10 years |  |
| `catAxis.gap` | Center gap (px) | Espace au centre (px) | number | integer | `2` | 0 to 40 | Visible when `catAxis.position` = `left` or `right` |
| `catAxis.showTitle` | Axis title | Titre de l'axe | toggle | bool | `true` | true / false |  |
| `catAxis.titleText` | Text | Texte | text | text | (empty) |  | Visible when `catAxis.showTitle` = `true` |
| `catAxis.birthYears` | Birth years alongside ★ | Années de naissance en regard ★ | toggle | bool | `false` | true / false | On the right, the birth year of each age (observation year known). |

### Value axis / Axe des valeurs (`valAxis`, Format pane)

The card header toggle is `valAxis.show`.

**Labels / Étiquettes**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `valAxis.show` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `valAxis.fontSize` | Size | Taille | number | formatting | `9` | 6 to 24 |  |
| `valAxis.color` | Color (empty = secondary text) | Couleur (vide = texte secondaire) | color | fill | (empty) | hex color |  |
| `valAxis.units` | Display units | Unités d'affichage | dropdown | enumeration | `auto` | `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions |  |
| `valAxis.decimals` | Decimals (-1 = auto) | Décimales (-1 = auto) | number | integer | `-1` | -1 to 6 |  |
| `valAxis.prefix` | Prefix | Préfixe | text | text | (empty) |  |  |
| `valAxis.suffix` | Suffix (e.g. €) | Suffixe (ex. €) | text | text | (empty) |  |  |
| `valAxis.ticks` | Ticks per side (approx.) | Graduations par côté (environ) | number | integer | `3` | 1 to 10 |  |

**Axis title / Titre de l'axe**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `valAxis.showTitle` | Axis title | Titre de l'axe | toggle | bool | `false` | true / false |  |
| `valAxis.titleText` | Text | Texte | text | text | (empty) |  | Visible when `valAxis.showTitle` = `true` |

### Gridlines / Quadrillage (`gridlines`, Format pane)

**Vertical (values) / Vertical (valeurs)**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `gridlines.vShow` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `gridlines.vColor` | Color (empty = style grid) | Couleur (vide = grille du style) | color | fill | (empty) | hex color |  |
| `gridlines.vWidth` | Width | Épaisseur | number | numeric | `1` | 0.5 to 6 |  |
| `gridlines.vStyle` | Line style | Style de trait | dropdown | enumeration | `solid` | `solid` Solid; `dashed` Dashed; `dotted` Dotted |  |

### Legend / Légende (`legend`, Format pane)

The card header toggle is `legend.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `legend.show` | Show | Afficher | toggle | bool | `true` | true / false | Shown when the chart has several series. |
| `legend.position` | Position | Position | dropdown | enumeration | `top` | `top` Top; `bottom` Bottom; `right` Right; `left` Left |  |
| `legend.align` | Alignment | Alignement | dropdown | enumeration | `left` | `left` Start; `center` Center; `right` End | Visible when `legend.position` = `top` or `bottom` |
| `legend.showTitle` | Legend title | Titre de la légende | toggle | bool | `false` | true / false |  |
| `legend.titleText` | Title text | Texte du titre | text | text | (empty) |  | Visible when `legend.showTitle` = `true` |
| `legend.fontSize` | Size | Taille | number | formatting | `9` | 6 to 24 |  |
| `legend.color` | Color (empty = secondary text) | Couleur (vide = texte secondaire) | color | fill | (empty) | hex color |  |
| `legend.interactive` | Click = select the series | Clic = sélectionner la série | toggle | bool | `true` | true / false |  |

### Comparison ★ / Comparaison ★ (`comparison`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

The card header toggle is `comparison.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `comparison.show` | Show | Afficher | toggle | bool | `true` | true / false | Drawn with the "Comparison ★" field, or from a frame of the play axis. |
| `comparison.source` | Compare with | Comparer à | dropdown | enumeration | `field` | `field` "Comparison" field; `first` First frame of the play axis ★; `previous` Previous frame of the play axis ★; `frame` Named frame of the play axis ★ | Play axis frame: the pyramid of a fixed year stays drawn as an outline while playing. |
| `comparison.frameName` | Frame (e.g. 1975) | Image (ex. 1975) | text | text | (empty) |  | Visible when `comparison.source` = `frame` |
| `comparison.style` | Drawing | Dessin | dropdown | enumeration | `outline` | `outline` Step outline; `ghost` Ghost bars behind; `marker` Marker at the end of each bar |  |
| `comparison.color` | Color (empty = text) | Couleur (vide = texte) | color | fill | (empty) | hex color |  |
| `comparison.width` | Width | Épaisseur | number | numeric | `1.5` | 0.5 to 6 |  |
| `comparison.lineStyle` | Line style | Style du trait | dropdown | enumeration | `solid` | `solid` Solid; `dashed` Dashed; `dotted` Dotted |  |
| `comparison.label` | Label | Libellé | text | text | (empty) |  |  |

### Generations ★ / Générations ★ (`generation`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

**Follow a generation / Suivre une génération**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `generation.follow` | Follow a generation ★ | Suivre une génération ★ | toggle | bool | `false` | true / false | The generation born in a given year is highlighted and climbs year after year while playing. |
| `generation.birthFrom` | Born in (or from) | Née en (ou de) | number | integer | `1946` | 1000 to 3000 |  |
| `generation.birthTo` | To (0 = a single year) | Jusqu'à (0 = une seule année) | number | integer | `0` | 0 to 3000 |  |
| `generation.label` | Label | Libellé | text | text | (empty) |  |  |
| `generation.color` | Color (empty = accent) | Couleur (vide = accent) | color | fill | (empty) | hex color |  |

**Generation markers / Repères de générations**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `generation.marks` | Markers ★ (birth years = text; separated by ;) | Repères ★ (années de naissance = texte ; séparés par ;) | textarea | text | (empty) |  | A band and a label at the age of each generation; they climb while playing. |
| `generation.marksColor` | Markers color (empty = secondary text) | Couleur des repères (vide = texte secondaire) | color | fill | (empty) | hex color |  |

### Demographic indicators ★ / Indicateurs démographiques ★ (`indicators`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

The card header toggle is `indicators.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `indicators.show` | Show ★ | Afficher ★ | toggle | bool | `false` | true / false | Computed by the visual for the current frame (numeric ages). |
| `indicators.position` | Position | Position | dropdown | enumeration | `topLeft` | `topLeft` Top left; `topRight` Top right; `bottomLeft` Bottom left; `bottomRight` Bottom right |  |
| `indicators.total` | Total population | Population totale | toggle | bool | `true` | true / false |  |
| `indicators.median` | Median age | Âge médian | toggle | bool | `true` | true / false |  |
| `indicators.mean` | Mean age | Âge moyen | toggle | bool | `false` | true / false |  |
| `indicators.youngShare` | Share of young people | Part des jeunes | toggle | bool | `true` | true / false |  |
| `indicators.oldShare` | Share of older people | Part des âgés | toggle | bool | `true` | true / false |  |
| `indicators.dependency` | Dependency ratio | Rapport de dépendance | toggle | bool | `true` | true / false | (young + older) per 100 people of working age. |
| `indicators.ageing` | Ageing index | Indice de vieillissement | toggle | bool | `false` | true / false | Older people per 100 young people. |
| `indicators.ratio` | Side ratio (left per 100 right) | Rapport entre les côtés (gauche pour 100 droite) | toggle | bool | `false` | true / false | Sex ratio when the sides are the sexes. |
| `indicators.youngMax` | Young: under (years) | Jeunes : moins de (ans) | number | integer | `20` | 1 to 40 |  |
| `indicators.oldMin` | Older: from (years) | Âgés : à partir de (ans) | number | integer | `65` | 40 to 100 |  |
| `indicators.fontSize` | Size | Taille | number | formatting | `10` | 7 to 20 |  |

### Projection ★ (`projection`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

The card header toggle is `projection.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `projection.show` | Mark projections ★ | Marquer les projections ★ | toggle | bool | `false` | true / false | Play axis frames from a given year on are drawn differently and flagged "Projection". |
| `projection.from` | Projection from | Projection à partir de | text | text | (empty) |  |  |
| `projection.style` | Bar drawing | Dessin des barres | dropdown | enumeration | `hatch` | `hatch` Hatched; `pale` Pale; `outline` Dashed outline |  |
| `projection.label` | Tag | Mention | text | text | (empty) |  |  |

### Small multiples / Petits multiples (`smallMultiples`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `smallMultiples.columns` | Columns (0 = automatic) | Colonnes (0 = automatique) | number | integer | `0` | 0 to 12 |  |
| `smallMultiples.gap` | Spacing (px) | Espacement (px) | number | integer | `14` | 0 to 60 |  |
| `smallMultiples.titleSize` | Title size | Taille des titres | number | formatting | `10` | 6 to 24 |  |
| `smallMultiples.titleTotal` | Total in the title | Total dans le titre | toggle | bool | `true` | true / false |  |
| `smallMultiples.border` | Panel border | Cadre des panneaux | toggle | bool | `false` | true / false |  |

### Playback ★ / Lecture ★ (`play`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

**Playback / Lecture**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `play.start` | Frame shown on opening | Image affichée à l'ouverture | dropdown | enumeration | `last` | `last` The last one (most recent); `first` The first one |  |
| `play.speed` | Duration of a frame (ms) | Durée d'une image (ms) | number | integer | `1000` | 100 to 10000 | At speed ×1; the speed button of the play bar multiplies it (×0.5 to ×4) for the session. |
| `play.loop` | Loop | Lecture en boucle | toggle | bool | `false` | true / false |  |
| `play.autoPlay` | Play automatically on opening | Lecture automatique à l'ouverture | toggle | bool | `false` | true / false | Once, from the first frame. Not when animations are reduced (Style › Animations or the system) nor on a dashboard tile. |
| `play.transition` | Animated transitions | Transitions animées | toggle | bool | `true` | true / false | Values, positions and colors move smoothly from one frame to the next. |

**Play bar / Barre de lecture**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `play.controls` | Play bar | Barre de lecture | toggle | bool | `true` | true / false |  |
| `play.position` | Bar position | Position de la barre | dropdown | enumeration | `bottom` | `bottom` Bottom; `top` Top | Visible when `play.controls` = `true` |
| `play.ticks` | Tick marks | Graduations | dropdown | enumeration | `auto` | `auto` Automatic; `all` Every frame; `none` None | Visible when `play.controls` = `true` |
| `play.tickLabels` | Tick labels | Étiquettes des graduations | toggle | bool | `true` | true / false | Visible when `play.controls` = `true` |
| `play.stepButtons` | Start and end buttons | Boutons début et fin | toggle | bool | `true` | true / false | Visible when `play.controls` = `true` |
| `play.speedButton` | Speed button | Bouton de vitesse | toggle | bool | `true` | true / false | Visible when `play.controls` = `true` |

**Large value / Valeur en grand**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `play.showLabel` | Current value in large type | Valeur en cours en grand | toggle | bool | `true` | true / false |  |
| `play.labelSize` | Large value size | Taille de la valeur en grand | number | formatting | `44` | 12 to 160 | Visible when `play.showLabel` = `true` |
| `play.labelPosition` | Large value position | Position de la valeur en grand | dropdown | enumeration | `topRight` | `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center | Visible when `play.showLabel` = `true` |

### Median and mean age ★ / Âges médian et moyen ★ (`ageLines`, Analytics pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `ageLines.median` | Median age ★ | Âge médian ★ | toggle | bool | `false` | true / false |  |
| `ageLines.mean` | Mean age ★ | Âge moyen ★ | toggle | bool | `false` | true / false |  |
| `ageLines.per` | Computed for | Calculé pour | dropdown | enumeration | `side` | `side` Each side; `total` Everyone |  |
| `ageLines.color` | Color (empty = text) | Couleur (vide = texte) | color | fill | (empty) | hex color |  |
| `ageLines.style` | Line style | Style du trait | dropdown | enumeration | `dashed` | `solid` Solid; `dashed` Dashed; `dotted` Dotted |  |
| `ageLines.width` | Width | Épaisseur | number | numeric | `1.5` | 0.5 to 6 |  |
| `ageLines.showLabel` | Label with the value | Libellé avec la valeur | toggle | bool | `true` | true / false |  |

### Interactions (`interaction`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `interaction.hover` | Highlight on hover | Mettre en avant au survol | toggle | bool | `true` | true / false |  |
| `interaction.dim` | Dimmed items opacity (%) | Opacité des éléments estompés (%) | number | integer | `25` | 5 to 80 |  |

### Tooltips / Infobulles (`tooltip`, Format pane)

The card header toggle is `tooltip.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `tooltip.show` | Show | Afficher | toggle | bool | `true` | true / false | Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips). |

### Title / Titre (`title`, Format pane)

The card header toggle is `title.show`.

**Title / Titre**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `title.show` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `title.text` | Text | Texte | text | text | (empty) |  | Leave empty for an automatic title built from the fields. |
| `title.fontSize` | Size | Taille | number | formatting | `14` | 7 to 40 |  |
| `title.bold` | Bold | Gras | toggle | bool | `true` | true / false |  |
| `title.italic` | Italic | Italique | toggle | bool | `false` | true / false |  |
| `title.underline` | Underline | Souligné | toggle | bool | `false` | true / false |  |
| `title.color` | Color (empty = text) | Couleur (vide = texte) | color | fill | (empty) | hex color |  |
| `title.bgColor` | Background color | Couleur d'arrière-plan | color | fill | (empty) | hex color |  |
| `title.align` | Horizontal alignment | Alignement horizontal | dropdown | enumeration | `left` | `left` Left; `center` Center; `right` Right |  |
| `title.wrap` | Text wrap | Retour automatique à la ligne | toggle | bool | `true` | true / false |  |

**Subtitle / Sous-titre**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `title.subtitle` | Subtitle | Sous-titre | text | text | (empty) |  | Several lines allowed: type \n to go to the next line. |
| `title.subFontSize` | Size | Taille | number | formatting | `11` | 7 to 30 | Visible when `title.subtitle` =  |
| `title.subColor` | Color (empty = secondary text) | Couleur (vide = texte secondaire) | color | fill | (empty) | hex color | Visible when `title.subtitle` =  |
| `title.subItalic` | Italic | Italique | toggle | bool | `false` | true / false | Visible when `title.subtitle` =  |

**Divider / Séparateur**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `title.divider` | Show divider | Afficher le séparateur | toggle | bool | `false` | true / false |  |
| `title.dividerColor` | Color (empty = lines) | Couleur (vide = traits) | color | fill | (empty) | hex color | Visible when `title.divider` = `true` |
| `title.dividerStyle` | Line style | Style de trait | dropdown | enumeration | `solid` | `solid` Solid; `dashed` Dashed; `dotted` Dotted | Visible when `title.divider` = `true` |
| `title.dividerWidth` | Width | Épaisseur | number | integer | `1` | 1 to 6 | Visible when `title.divider` = `true` |

**Spacing / Espacement**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `title.spaceBelow` | Space below the title (px) | Espace sous le titre (px) | number | integer | `4` | 0 to 40 |  |

### Source note / Note de source (`source`, Format pane)

The card header toggle is `source.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `source.show` | Show | Afficher | toggle | bool | `false` | true / false |  |
| `source.text` | Text | Texte | text | text | (empty) |  |  |
| `source.fontSize` | Size | Taille | number | formatting | `9` | 6 to 20 |  |
| `source.italic` | Italic | Italique | toggle | bool | `false` | true / false |  |
| `source.color` | Color (empty = secondary text) | Couleur (vide = texte secondaire) | color | fill | (empty) | hex color |  |
| `source.align` | Alignment | Alignement | dropdown | enumeration | `left` | `left` Left; `center` Center; `right` Right |  |

### Frame / Cadre (`container`, Format pane)

**Background / Arrière-plan**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `container.bgShow` | Background | Arrière-plan | toggle | bool | `false` | true / false |  |
| `container.bgColor` | Color | Couleur | color | fill | `#FFFFFF` | hex color | Visible when `container.bgShow` = `true` |
| `container.bgColor2` | Gradient end (optional) | Fin du dégradé (optionnel) | color | fill | (empty) | hex color | Visible when `container.bgShow` = `true` |
| `container.bgTransparency` | Transparency (%) | Transparence (%) | slider | numeric | `0` | 0 to 100 | Visible when `container.bgShow` = `true` |

**Border / Bordure**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `container.border` | Border | Bordure | toggle | bool | `false` | true / false |  |
| `container.borderColor` | Color (empty = lines) | Couleur (vide = traits) | color | fill | (empty) | hex color | Visible when `container.border` = `true` |
| `container.borderWidth` | Width | Épaisseur | number | integer | `1` | 0 to 6 | Visible when `container.border` = `true` |
| `container.radius` | Rounded corners | Coins arrondis | number | integer | `8` | 0 to 24 |  |

**Shadow / Ombre**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `container.shadow` | Shadow | Ombre | toggle | bool | `false` | true / false |  |
| `container.shadowColor` | Color (empty = soft) | Couleur (vide = douce) | color | fill | (empty) | hex color | Visible when `container.shadow` = `true` |
| `container.shadowSize` | Blur (px) | Flou (px) | number | integer | `12` | 0 to 40 | Visible when `container.shadow` = `true` |

**Spacing / Marges**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `container.padding` | Inner padding | Marge intérieure | number | integer | `8` | 0 to 40 |  |

### Language and numbers / Langue et nombres (`texts`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `texts.language` | Interface language | Langue de l'interface | dropdown | enumeration | `auto` | `auto` Same as Power BI; `fr` French; `en` English |  |
| `texts.numberLocale` | Number format locale (e.g. en-GB) | Format des nombres (ex. fr-FR) | text | text | (empty) |  | Thousands and decimal separators. Empty: same as Power BI. |

### Other objects (not in the Format pane cards above)

- `ageAxis`: `ageAxis.show` (bool), `ageAxis.position` (enumeration), `ageAxis.fontSize` (formatting), `ageAxis.color` (fill), `ageAxis.every` (enumeration), `ageAxis.gap` (integer), `ageAxis.showTitle` (bool), `ageAxis.titleText` (text), `ageAxis.birthYears` (bool).
