# UI Layout Editor Fields for AI Agents

> UI layout editor field ids for AI agents: widgets, their style, region layout, state keys and previews in the DiceyTable item editor, with kinds and ranges.

- Question: Which UI layout fields, including style and region layout, can an agent set?
- Source: https://diceytable.com/docs/ai-agents/reference/fields/ui-layout-editor
- Last verified: 2026-10-13

These are the fields of the item editor's UI Layout tab: the layout itself, the preview canvas, the selected widget (with its style), region layout, state keys and preview fixtures. Each id takes the layout you have open, plus a row for a widget, a region, a state key or a fixture. A style field writes at the scope chosen by `item.ui-layout.widget.style.scope`.

## Panels in this group

4 panels, with the id prefix `item.ui-layout`. The [field catalogue](https://diceytable.com/docs/ai-agents/reference/fields) lists every group.

| Panel | Label | Tab | Fields | Actions |
|---|---|---|---|---|
| [`item.ui-layout`](https://diceytable.com/docs/ai-agents/reference/fields/ui-layout-editor#itemui-layout) | UI Layout tab | `editor` | 24 | 17 |
| [`item.ui-layout.widget`](https://diceytable.com/docs/ai-agents/reference/fields/ui-layout-editor#itemui-layoutwidget) | UI Layout ▸ Widget | `editor` | 131 | 14 |
| [`item.ui-layout.state`](https://diceytable.com/docs/ai-agents/reference/fields/ui-layout-editor#itemui-layoutstate) | UI Layout ▸ State | `editor` | 5 | 2 |
| [`item.ui-layout.preview`](https://diceytable.com/docs/ai-agents/reference/fields/ui-layout-editor#itemui-layoutpreview) | UI Layout ▸ Previews | `editor` | 5 | 3 |

## `item.ui-layout`

**UI Layout tab** · surface `editor` · target `asset`

How it opens: Hierarchy ▸ UI Layouts ▸ a layout ▸ Edit (or the Game row's Scene scripts & UI block). The target is the layout id.

**Fields** (24)

| Field id | Label | Kind | Unit | Target | Class | Range / options | Description |
|---|---|---|---|---|---|---|---|
| `item.ui-layout.name` | Name | `text` | — | `asset` | W | — | The layout's display name (the id stays fixed; scripts and attachments use the id). |
| `item.ui-layout.description` | Description | `multiline` | — | `asset` | W | — | Notes for authors. Not shown to players. "" clears it. |
| `item.ui-layout.font` | Font | `select` | — | `asset` | W | `platform`, `serif`, `display-classic`, `display-bold`, `sci-fi`, `mono`, `retro`, `handwritten` | The default font for every widget in the layout (a widget's own Theme ▸ Font wins). Self-hosted fonts only. |
| `item.ui-layout.view.device` | Device | `select` | — | `asset` | W | `desktop`, `desktop-1080`, `laptop`, `tablet`, `tablet-landscape`, `phone`, `phone-landscape`, `phone-android`, `phone-android-landscape`, `phone-small`, `phone-small-landscape`, `vr` | Which screen the preview canvas draws, at its real CSS-pixel size: `desktop` (1280x720), `desktop-1080` (1920x1080) and `laptop` (1440x900) draw the desktop HUD; `tablet` (820x1180) and `tablet-landscape` (1180x820) the touch HUD; the phone frames (`phone` 390x844, `phone-landscape` 844x390, `phone-android` 412x915, `phone-android-landscape` 915x412, `phone-small` 360x740, `phone-small-landscape` 740x360) the compact phone HUD; `vr` the VR tray as a flat projection. View state only. |
| `item.ui-layout.view.fixture` | Preview state | `select` | — | `asset` | W | — | Which preview fixture's state values the canvas uses: "" for the declared defaults, else the fixture's index as a string. View state only. |
| `item.ui-layout.view.as` | View as | `select` | — | `asset` | W | — | Whose screen the canvas shows: `host`, `spectator`, or `seat:<seat id>` (private widgets and seat-private state appear only for their own seat). View state only. |
| `item.ui-layout.view.moments` | Moments | `select` | — | `asset` | W | `all`, `selected`, `none` | Which on-demand widgets (banners, prompts, choices, results, timers, card spotlights — shown only when a script calls ui.show) the canvas draws: all, only the selected one, or none. Furniture widgets always draw. View state only. |
| `item.ui-layout.view.button-state` | Button state | `select` | — | `asset` | W | `default`, `hover`, `pressed`, `active`, `disabled` | The button state the selected widget's buttons are DRAWN in on the canvas and EDITED in by the button style fields (default, hover, pressed, active, disabled). View state only. |
| `item.ui-layout.add-kind` | Widget kind | `select` | — | `asset` | W | `status`, `banner`, `prompt`, `actions`, `choice`, `result`, `player-panel`, `counter`, `meter`, `log`, `hint`, `timer`, `panel`, `card` | The kind `item.ui-layout.widget.add` adds. View state only. |
| `item.ui-layout.json.text` | Layout JSON | `code` | — | `asset` | W | — | The layout document as JSON (the JSON sub-tab). Edits stay local until `item.ui-layout.json.apply`. |
| `item.ui-layout.view.chrome` | Show table chrome | `boolean` | — | `asset` | W | — | Draw the platform's own controls (menu, toolbar, status pills, dice, hand drawer, chat) as placeholders in the preview frame, where they sit at the table, so you can see what the HUD must leave clear. View state only. |
| `item.ui-layout.region-style.region` | Region | `select` | — | `asset` | W | `upper-start`, `upper`, `upper-end`, `start`, `center`, `end`, `lower-start`, `lower`, `lower-end` | Which region the REGION LAYOUT fields edit. View state only. |
| `item.ui-layout.region-style.scope` | Applies to | `select` | — | `asset` | W | `all`, `desktop`, `tablet`, `phone` | Which screens the REGION LAYOUT fields edit: `all` writes `regions.<region>`, `desktop` / `tablet` / `phone` write its `devices.<class>`, merged over it on that screen only. Shares its value with the widget STYLE section's Applies to. View state only. |
| `item.ui-layout.region-style.direction` | Direction | `select` | — | `asset` | W | ``, `column`, `row` | Stack the region's widgets (column, the platform's) or set them side by side (row). Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.align` | Align | `select` | — | `asset` | W | ``, `start`, `center`, `end`, `stretch` | Where the widgets sit across the region. Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.justify` | Justify | `select` | — | `asset` | W | ``, `start`, `center`, `end`, `between` | How the widgets spread along the region's direction (between = edge to edge). Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.gap` | Gap | `number` | — | `asset` | W | ≥ 0, ≤ 32 | Space between the region's widgets, px (0-32). Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.wrap` | Wrap | `select` | — | `asset` | W | ``, `wrap`, `nowrap` | A row region wraps onto more rows when its widgets do not fit (wrap), or keeps one line (nowrap). Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.max-width.unit` | Max width unit | `select` | — | `asset` | W | ``, `px`, `%` | px or % of the table screen; "" clears it. Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.max-width.value` | Max width | `number` | — | `asset` | W | ≥ 0, ≤ 1600 | How wide the region may grow, in the chosen unit (never past the screen). Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.max-height.unit` | Max height unit | `select` | — | `asset` | W | ``, `px`, `%` | px or % of the table screen; "" clears it. Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.max-height.value` | Max height | `number` | — | `asset` | W | ≥ 0, ≤ 1600 | How tall the region may grow, in the chosen unit; more scrolls. Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.offset-x` | Nudge X | `number` | — | `asset` | W | ≥ -200, ≤ 200 | Move the whole region sideways, px (+-200). Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.offset-y` | Nudge Y | `number` | — | `asset` | W | ≥ -200, ≤ 200 | Move the whole region up (negative) or down, px (+-200). Writes `regions.<region>` of the layout at the scope chosen by `item.ui-layout.region-style.scope` (all devices = the entry itself; one screen class = its `devices.<class>`, merged over it on that screen only). A phone applies it to the compact slot that region's widgets land in. "" clears the key at that scope. The target is `<layout id>#region:<region>`. |

**Actions** (17)

| Action id | Label | Class | Target | Description |
|---|---|---|---|---|
| `item.ui-layout.show-widget` | Widget | R | `asset` | Switch the inspector to the Widget sub-tab. View state only. |
| `item.ui-layout.show-state` | State | R | `asset` | Switch the inspector to the State sub-tab. View state only. |
| `item.ui-layout.show-previews` | Previews | R | `asset` | Switch the inspector to the Previews sub-tab. View state only. |
| `item.ui-layout.show-problems` | Problems | R | `asset` | Switch the inspector to the Problems sub-tab. View state only. |
| `item.ui-layout.show-json` | JSON | R | `asset` | Switch the inspector to the JSON sub-tab. View state only. |
| `item.ui-layout.export` | Export JSON | R | `asset` | Download the layout as `<id>.layout.json` (the exact JSON scripts use). Nothing in the project changes. |
| `item.ui-layout.json.apply` | Apply JSON | W | `asset` | Replace the layout with the JSON sub-tab's text (the id is kept). Refuses text that is not a JSON object; schema problems are listed and can be fixed afterwards. |
| `item.ui-layout.json.revert` | Revert | R | `asset` | Discard unapplied edits in the JSON sub-tab (reload the layout's current JSON). The layout is not changed. |
| `item.ui-layout.problem.go` | Show problem | R | `asset` | Select the widget a problem is about. The target is `<layout id>#problem:<index>`. |
| `item.ui-layout.widget.add` | + Add widget | W | `asset` | Add a widget of the kind chosen in `item.ui-layout.add-kind` (valid defaults) and select it. |
| `item.ui-layout.widget.select` | Select widget | R | `asset` | Select a widget so its inspector shows. The target is `<layout id>#widget:<widget id>`. |
| `item.ui-layout.widget.move-up` | Move up | W | `asset` | Move a widget one place earlier in its region. The target is `<layout id>#widget:<widget id>`. |
| `item.ui-layout.widget.move-down` | Move down | W | `asset` | Move a widget one place later in its region. The target is `<layout id>#widget:<widget id>`. |
| `item.ui-layout.widget.duplicate` | Duplicate | W | `asset` | Copy a widget under a fresh id, right after it. The target is `<layout id>#widget:<widget id>`. |
| `item.ui-layout.widget.remove` | Remove | D | `asset` | Delete a widget from the layout. The target is `<layout id>#widget:<widget id>`. |
| `item.ui-layout.region.move` | Move selected here | W | `asset` | Move the selected widget into a region of the region map (the same as dragging it there). The target is `<layout id>#region:<region>`. |
| `item.ui-layout.region-style.reset` | Reset region | W | `asset` | Remove a region's layout (`regions.<region>`), so the platform's own applies. The target is `<layout id>#region:<region>`. |

## `item.ui-layout.widget`

**UI Layout ▸ Widget** · surface `editor` · target `asset`

How it opens: UI Layout tab ▸ Widget sub-tab (the selected widget's inspector).

**Fields** (131)

| Field id | Label | Kind | Unit | Target | Class | Range / options | Description |
|---|---|---|---|---|---|---|---|
| `item.ui-layout.widget.id` | Id | `text` | — | `asset` | W | — | The widget id scripts use (`ui.show("<id>")`, `event.widgetId`). Unique in the layout. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.kind` | Kind | `select` | — | `asset` | W | `status`, `banner`, `prompt`, `actions`, `choice`, `result`, `player-panel`, `counter`, `meter`, `log`, `hint`, `timer`, `panel`, `card` | The widget kind. Changing it keeps the shared fields; fields the new kind does not use are ignored by the renderer. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.region` | Region | `select` | — | `asset` | W | ``, `upper-start`, `upper`, `upper-end`, `start`, `center`, `end`, `lower-start`, `lower`, `lower-end`, `sheet` | Where the widget sits on a flat screen. "" removes the region (an attached widget then draws at its attachment; otherwise the kind's default region). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.order` | Order | `integer` | — | `asset` | W | ≥ -1000, ≤ 1000 | Sort position within the region (lower first). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.attach.to` | Attach to | `select` | — | `asset` | W | ``, `seat`, `entity`, `zone` | Attach the widget to a seat, an entity or a zone (drawn there as a world billboard on every device, and placed there in VR). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.attach.seat` | Seat | `select` | — | `asset` | W | — | For a seat attachment: one seat id, or "" for every seat (each seat's own copy). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.attach.entity` | Entity id | `text` | — | `asset` | W | — | For an entity attachment by id. Setting it clears the tag. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.attach.tag` | Entity tag | `text` | — | `asset` | W | — | For an entity attachment by tag (the first entity carrying it). Setting it clears the id. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.attach.zone` | Zone id | `text` | — | `asset` | W | — | For a zone attachment: the zone id. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.devices.desktop.region` | Desktop | `select` | — | `asset` | W | ``, `hidden`, `upper-start`, `upper`, `upper-end`, `start`, `center`, `end`, `lower-start`, `lower`, `lower-end`, `sheet` | On a desktop (mouse) screen only: a different region, "hidden" to leave it off desktop screens, or "" for the widget's own Region. A prompt or choice is never hidden. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.devices.tablet.region` | Tablet | `select` | — | `asset` | W | ``, `hidden`, `upper-start`, `upper`, `upper-end`, `start`, `center`, `end`, `lower-start`, `lower`, `lower-end`, `sheet` | On a tablet-size touch screen only: a different region, "hidden", or "" for the widget's own Region. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.devices.phone.region` | Phone | `select` | — | `asset` | W | ``, `hidden`, `upper-start`, `upper`, `upper-end`, `start`, `center`, `end`, `lower-start`, `lower`, `lower-end`, `sheet` | On a phone (a small touch screen) only: a different region, "hidden", or "" for the widget's own Region. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.devices.desktop.menu` | Desktop: fold into a menu button | `boolean` | — | `asset` | W | — | An actions widget only: on desktop screens, show one button that opens its buttons. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.devices.tablet.menu` | Tablet: fold into a menu button | `boolean` | — | `asset` | W | — | An actions widget only: on tablets, show one button that opens its buttons. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.devices.phone.menu` | Phone: fold into a menu button | `boolean` | — | `asset` | W | — | An actions widget only: on phones, show one button that opens its buttons (for controls a player rarely needs, so the dock stays small). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.scope` | Applies to | `select` | — | `asset` | W | `all`, `desktop`, `tablet`, `phone` | Which screens the STYLE fields edit: `all` writes the widget's `style`; `desktop` / `tablet` / `phone` write `placement.devices.<class>.style`, merged over it on that screen only. View state only. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.width.unit` | Width unit | `select` | — | `asset` | W | ``, `px`, `%`, `auto`, `fill` | How the width is given: px, % of the table screen, auto (fit the content) or fill (as wide as its region). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.width.value` | Width | `number` | — | `asset` | W | ≥ 0, ≤ 1600 | The width in the chosen unit (px 0-1600, % 1-100). Never wider than the screen. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.min-width.unit` | Min width unit | `select` | — | `asset` | W | ``, `px`, `%` | px or % of the table screen. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.min-width.value` | Min width | `number` | — | `asset` | W | ≥ 0, ≤ 1600 | The smallest width, in the chosen unit. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.max-width.unit` | Max width unit | `select` | — | `asset` | W | ``, `px`, `%` | px or % of the table screen. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.max-width.value` | Max width | `number` | — | `asset` | W | ≥ 0, ≤ 1600 | The largest width, in the chosen unit (may go past the region's own width, never past the screen's). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.height.unit` | Height unit | `select` | — | `asset` | W | ``, `px`, `%`, `auto` | px, % of the table screen, or auto. A fixed height scrolls its content. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.height.value` | Height | `number` | — | `asset` | W | ≥ 0, ≤ 1600 | The height in the chosen unit (never more than 85% of the screen). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.max-height.unit` | Max height unit | `select` | — | `asset` | W | ``, `px`, `%` | px or % of the table screen. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.max-height.value` | Max height | `number` | — | `asset` | W | ≥ 0, ≤ 1600 | The largest height, in the chosen unit; taller content scrolls. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.align` | Align in region | `select` | — | `asset` | W | ``, `start`, `center`, `end`, `stretch` | Where the widget sits across its region: start, center, end, or stretch to the region's width. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.offset-x` | Nudge X | `number` | — | `asset` | W | ≥ -200, ≤ 200 | Move the widget sideways from where the platform puts it, px (+-200; positive = right). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.offset-y` | Nudge Y | `number` | — | `asset` | W | ≥ -200, ≤ 200 | Move the widget up (negative) or down from where the platform puts it, px (+-200). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.padding.mode` | Padding | `select` | — | `asset` | W | ``, `all`, `sides` | How padding is given: one number for every side, or per side. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.padding.all` | Padding (all) | `number` | — | `asset` | W | ≥ 0, ≤ 48 | Padding on every side, px (0-48). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.padding.above` | Padding above | `number` | — | `asset` | W | ≥ 0, ≤ 48 | Padding above the content, px. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.padding.below` | Padding below | `number` | — | `asset` | W | ≥ 0, ≤ 48 | Padding below the content, px. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.padding.start` | Padding start | `number` | — | `asset` | W | ≥ 0, ≤ 48 | Padding on the start side (the left, in left-to-right text), px. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.padding.end` | Padding end | `number` | — | `asset` | W | ≥ 0, ≤ 48 | Padding on the end side, px. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.margin.mode` | Margin | `select` | — | `asset` | W | ``, `all`, `sides` | How the margin is given: one number for every side, or per side. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.margin.all` | Margin (all) | `number` | — | `asset` | W | ≥ 0, ≤ 64 | Space outside the widget on every side, px (0-64). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.margin.above` | Margin above | `number` | — | `asset` | W | ≥ 0, ≤ 64 | Space above the widget, px. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.margin.below` | Margin below | `number` | — | `asset` | W | ≥ 0, ≤ 64 | Space below the widget, px. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.margin.start` | Margin start | `number` | — | `asset` | W | ≥ 0, ≤ 64 | Space on the start side, px. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.margin.end` | Margin end | `number` | — | `asset` | W | ≥ 0, ≤ 64 | Space on the end side, px. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.gap` | Gap | `number` | — | `asset` | W | ≥ 0, ≤ 32 | Space between the widget's own children (buttons, chips, rows), px (0-32). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.background` | Background | `text` | — | `asset` | W | — | The background colour: A palette name (red, orange, yellow, green, teal, blue, purple, pink, gray) or #rrggbb. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.background-opacity` | Background opacity | `number` | — | `asset` | W | ≥ 0, ≤ 100 | How opaque the background is, 0-100 (default 92). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.color` | Text colour | `text` | — | `asset` | W | — | The text colour: A palette name (red, orange, yellow, green, teal, blue, purple, pink, gray) or #rrggbb. Lightened or darkened until it reads on the background. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.border-width` | Border width | `number` | — | `asset` | W | ≥ 0, ≤ 8 | px (0-8). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.border-color` | Border colour | `text` | — | `asset` | W | — | A palette name (red, orange, yellow, green, teal, blue, purple, pink, gray) or #rrggbb; "" keeps the tone's border. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.border-style` | Border style | `select` | — | `asset` | W | ``, `none`, `solid`, `dashed`, `dotted`, `double` | none, solid, dashed, dotted or double. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.radius` | Corner radius | `number` | — | `asset` | W | ≥ 0, ≤ 48 | px (0-48). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.shadow` | Shadow | `select` | — | `asset` | W | ``, `none`, `soft`, `strong` | none, soft or strong. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.font-size` | Font size | `number` | — | `asset` | W | ≥ 10, ≤ 32 | px (10-32); headings and labels scale with it. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.font-weight` | Font weight | `select` | — | `asset` | W | ``, `regular`, `medium`, `semibold`, `bold`, `heavy` | regular, medium, semibold, bold or heavy. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.text-align` | Text align | `select` | — | `asset` | W | ``, `start`, `center`, `end` | start, center or end. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.line-clamp` | Max lines | `number` | — | `asset` | W | ≥ 1, ≤ 12 | Cut each paragraph of the body to this many lines (1-12), with an ellipsis. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.buttons.direction` | Buttons: direction | `select` | — | `asset` | W | ``, `column`, `row` | An actions / prompt / choice widget's buttons in a row or a column. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.buttons.wrap` | Buttons: wrap | `select` | — | `asset` | W | ``, `wrap`, `nowrap` | Whether a row of buttons wraps onto more lines or stays one scrolling line. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.buttons.size` | Buttons: size | `select` | — | `asset` | W | ``, `sm`, `md`, `lg` | sm, md (the platform's) or lg. Small buttons stay at least 40 px tall on touch screens. Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.buttons.presentation` | Buttons: icon & label | `select` | — | `asset` | W | ``, `beside`, `under`, `icon-only`, `label-only` | How each button shows its icon and label. Icon only keeps the label as the accessible name (a button without an icon keeps its label). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.style.buttons.align` | Buttons: align | `select` | — | `asset` | W | ``, `start`, `center`, `end`, `stretch` | Where the buttons sit in their row (stretch = share the row). Writes at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; one screen class = `placement.devices.<class>.style`, merged over it). "" clears the key at that scope. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.audience` | Audience | `select` | — | `asset` | W | `all`, `host`, `players`, `spectators`, `seats`, `teams`, `seat-each`, `actor` | Who sees the widget. Only `all` is public; every other audience travels privately to its viewers. `seat-each` is one private copy per seat; `actor` is whoever triggered the script handler that shows it. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.audience.list` | Seats / teams | `text` | — | `asset` | W | — | For the `seats` / `teams` audiences: a comma-separated list of seat ids or team names. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.allow-spectators` | Spectators may press | `boolean` | — | `asset` | W | — | Let spectators press this widget's buttons (default: never). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.when.join` | Match | `select` | — | `asset` | W | `all`, `any` | Whether every condition row must hold (all) or one is enough (any). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.when.state` | State | `select` | — | `asset` | W | — | The state reference a condition row reads (`key` or `seat.key` — the VIEWER's own seat). The target is `<layout id>#widget:<widget id>/when:<index>`. |
| `item.ui-layout.widget.when.op` | Test | `select` | — | `asset` | W | `is`, `is-not`, `in`, `truthy`, `falsy`, `variant` | A condition row's test. `in` and `variant` take a comma-separated list. The target is `<layout id>#widget:<widget id>/when:<index>`. |
| `item.ui-layout.widget.when.value` | Value | `text` | — | `asset` | W | — | A condition row's value, typed by the key's declaration (numbers and true/false are converted). The target is `<layout id>#widget:<widget id>/when:<index>`. |
| `item.ui-layout.widget.timing.duration` | Duration (s) | `number` | — | `asset` | W | ≥ 0, ≤ 600, step 0.5 | How long the widget stays once shown, in seconds (0.5–600). 0 clears it (stays until hidden). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.timing.until` | Until | `select` | — | `asset` | W | ``, `dismissed`, `action`, `hidden` | What ends the widget: being dismissed, any action on it, or only ui.hide. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.theme.tone` | Tone | `select` | — | `asset` | W | ``, `neutral`, `info`, `success`, `warning`, `danger`, `accent` | The widget's tone (its colour stripe and emphasis). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.theme.accent` | Accent | `text` | — | `asset` | W | — | An accent colour: a palette name (red, orange, yellow, green, teal, blue, purple, pink, gray) or #rrggbb. Contrast-clamped by the renderer. "" clears it. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.theme.icon` | Icon | `select` | — | `asset` | W | — | An icon from the HUD icon list, or "" for none. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.theme.icon-image` | Icon image | `select` | — | `asset` | W | — | An image drawn where the icon would be (wins over it): a PNG / JPEG / WebP file of this project, or ONE string state binding whose value is such a path ("{seat.sideIcon}", "{key}", optionally "{seat.sideIcon\|ui/fallback.png}"), or "" for none. A bound value is drawn only when it is a project raster path. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.theme.font` | Font | `select` | — | `asset` | W | ``, `platform`, `serif`, `display-classic`, `display-bold`, `sci-fi`, `mono`, `retro`, `handwritten` | This widget's font (overrides the layout font). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.theme.density` | Density | `select` | — | `asset` | W | ``, `compact`, `comfortable` | Compact or comfortable spacing. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.theme.emphasis` | Emphasis | `select` | — | `asset` | W | ``, `subtle`, `normal`, `strong` | How strongly the widget stands out. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.title` | Title | `text` | — | `asset` | W | — | Title text. Bindings like {phase} or {seat.force\|0} are filled from state, as text. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.body` | Body | `multiline` | — | `asset` | W | — | Body text (bindings, **bold**, *italic*, [color=name]…[/color], bullets). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.text` | Text | `multiline` | — | `asset` | W | — | The text of a banner or hint. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.headline` | Headline | `text` | — | `asset` | W | — | A result widget's headline (added to the game-over window; never replaces its chrome). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.note` | Note | `text` | — | `asset` | W | — | A player panel's note. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.label` | Label | `text` | — | `asset` | W | — | A counter, meter or timer label. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.value` | Value | `text` | — | `asset` | W | — | A counter or meter value — usually a binding like {seat.force}. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.min` | Min | `number` | — | `asset` | W | — | A meter's minimum. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.max` | Max | `number` | — | `asset` | W | — | A meter's maximum. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.lines` | Lines | `multiline` | — | `asset` | W | — | A result widget's extra lines, one per line (20 at most). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.binding.field` | Insert into | `select` | — | `asset` | W | — | Which text field the binding picker inserts into (title, body, text, headline, note, label, value). View state only. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.binding.insert` | Insert binding | `select` | — | `asset` | W | — | Choosing a declared key appends {key} (or {seat.key}) to the field chosen in Insert into. The control resets to "" after inserting. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.image` | Image | `select` | — | `asset` | W | — | A header image: a PNG / JPEG / WebP file of this project (repo-relative path), or ONE string state binding whose value is such a path ("{seat.sideIcon}", "{key}", optionally "{seat.sideIcon\|ui/fallback.png}"), or "" for none. Prompt, result, choice, panel and player panel only. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.background-image` | Background image | `select` | — | `asset` | W | — | A panel's background image (a project raster file), or "" for none. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.timeout` | Time limit (s) | `number` | — | `asset` | W | ≥ 0, ≤ 600 | A prompt's time limit; when it runs out the default action is taken. 0 clears it. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.default-action` | Default action | `select` | — | `asset` | W | — | The action taken when a prompt times out ("" for none). Must be one of the widget's buttons. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.dismissible` | Dismissible | `boolean` | — | `asset` | W | — | Whether a prompt can be dismissed without answering. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.max-lines` | Max lines | `integer` | — | `asset` | W | ≥ 1, ≤ 200 | How many lines a log widget keeps (newest first). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.seconds` | Seconds | `number` | — | `asset` | W | ≥ 1, ≤ 3600 | A timer's countdown length, from when it is shown. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.choices.min` | Pick at least | `integer` | — | `asset` | W | ≥ 0, ≤ 200 | A choice list's minimum picks. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.choices.max` | Pick at most | `integer` | — | `asset` | W | ≥ 1, ≤ 200 | A choice list's maximum picks (above 1 needs a confirm button). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.choices.confirm` | Confirm button | `text` | — | `asset` | W | — | The confirm button's label for a multi-pick list; "" removes the button. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.choices.search` | Search box | `select` | — | `asset` | W | `auto`, `on`, `off` | A choice list's filter box (`choices.search`): `auto` shows it above 12 options (the field omitted), `on` always (`true`, or `{ placeholder }` when a placeholder is set), `off` never (`false`). VR shows a letter strip instead. The typed text stays on the player's screen; a pick is still an option id. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.choices.search-placeholder` | Search placeholder | `text` | — | `asset` | W | — | The hint inside the filter box (at most 80 characters); "" uses the platform's. Only with Search box `on` (`search: { placeholder }`). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.children` | Basic widgets (JSON) | `code` | — | `asset` | W | — | A panel widget's basic-widget children as a JSON array (the mod UI element shape). Applied on commit when it parses. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.button.id` | Action id | `text` | — | `asset` | W | — | The id a press sends to the script (`event.actionId`). Unique in the widget. The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.label` | Label | `text` | — | `asset` | W | — | The button's label (bindings allowed). Edits the button state chosen by `item.ui-layout.view.button-state` (`default` writes the base field; other states write `states.<state>` overrides that inherit the rest). The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.icon` | Icon | `select` | — | `asset` | W | — | An icon from the HUD icon list, or "". Edits the button state chosen by `item.ui-layout.view.button-state` (`default` writes the base field; other states write `states.<state>` overrides that inherit the rest). The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.icon-image` | Icon image | `select` | — | `asset` | W | — | A small project image drawn where an icon would be, or "". Edits the button state chosen by `item.ui-layout.view.button-state` (`default` writes the base field; other states write `states.<state>` overrides that inherit the rest). The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.image` | Image face | `select` | — | `asset` | W | — | A full image face (the label stays as accessible text), or "". Edits the button state chosen by `item.ui-layout.view.button-state` (`default` writes the base field; other states write `states.<state>` overrides that inherit the rest). The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.tone` | Tone | `select` | — | `asset` | W | ``, `neutral`, `info`, `success`, `warning`, `danger`, `accent` | The button's tone. Edits the button state chosen by `item.ui-layout.view.button-state` (`default` writes the base field; other states write `states.<state>` overrides that inherit the rest). The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.accent` | Accent | `text` | — | `asset` | W | — | A palette name or #rrggbb. Edits the button state chosen by `item.ui-layout.view.button-state` (`default` writes the base field; other states write `states.<state>` overrides that inherit the rest). The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.emphasis` | Emphasis | `select` | — | `asset` | W | ``, `subtle`, `normal`, `strong` | The button's emphasis. Edits the button state chosen by `item.ui-layout.view.button-state` (`default` writes the base field; other states write `states.<state>` overrides that inherit the rest). The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.confirm` | Confirm question | `text` | — | `asset` | W | — | Ask "Are you sure?" with this text before sending (drawn by the platform). "" clears it. The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.enabled-when` | Enabled when | `select` | — | `asset` | W | — | A state reference that must be true for the button to be pressable ("" = always). The host re-checks it. The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.active-when` | Active when | `select` | — | `asset` | W | — | A state reference that draws the button in its active (toggled) state while true ("" = never). The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.description` | Description | `text` | — | `asset` | W | — | A choice option's description. The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.card-id` | Card id | `text` | — | `asset` | W | — | A choice option drawn as this card's face ("" for none). The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.counter.label` | Label | `text` | — | `asset` | W | — | A counter's label. The target is `<layout id>#widget:<widget id>/counter:<index>`. |
| `item.ui-layout.counter.value` | Value | `text` | — | `asset` | W | — | A counter's value — a binding like {seat.force}. The target is `<layout id>#widget:<widget id>/counter:<index>`. |
| `item.ui-layout.counter.max` | Max | `text` | — | `asset` | W | — | A counter's maximum (a number or binding), or "". The target is `<layout id>#widget:<widget id>/counter:<index>`. |
| `item.ui-layout.counter.icon` | Icon | `select` | — | `asset` | W | — | A counter's icon from the HUD icon list, or "". The target is `<layout id>#widget:<widget id>/counter:<index>`. |
| `item.ui-layout.counter.icon-image` | Icon image | `select` | — | `asset` | W | — | A counter's image instead of its icon: a project raster file, or ONE string state binding whose value is such a path ("{seat.sideIcon}", "{key}", optionally "{seat.sideIcon\|ui/fallback.png}"), or "". In a player panel a `seat.` binding shows each seat its own image. The target is `<layout id>#widget:<widget id>/counter:<index>`. |
| `item.ui-layout.badge.text` | Text | `text` | — | `asset` | W | — | A badge's text. The target is `<layout id>#widget:<widget id>/badge:<index>`. |
| `item.ui-layout.badge.icon` | Icon | `select` | — | `asset` | W | — | A badge's icon from the HUD icon list, or "". The target is `<layout id>#widget:<widget id>/badge:<index>`. |
| `item.ui-layout.badge.icon-image` | Icon image | `select` | — | `asset` | W | — | A badge's image instead of its icon: a project raster file, or ONE string state binding whose value is such a path ("{seat.sideIcon}", "{key}", optionally "{seat.sideIcon\|ui/fallback.png}"), or "". In a player panel a `seat.` binding shows each seat its own image (e.g. a faction symbol). The target is `<layout id>#widget:<widget id>/badge:<index>`. |
| `item.ui-layout.card.entity-id` | Entity id | `text` | — | `asset` | W | — | The table entity the card spotlight draws, as each viewer may see it (a hidden card draws its back), or "" for none. Usually set by the script when it shows the widget. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.card.card-id` | Card id | `text` | — | `asset` | W | — | A card id from the game's card catalogue (a disclosure: everyone the widget reaches sees that face), used when no entity is named or it is gone; "" for none. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.card.label` | Card label | `text` | — | `asset` | W | — | The card's accessible name and the fallback text when no picture can be drawn. Required. Bindings are filled from state. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.card.counters` | Show counters | `boolean` | — | `asset` | W | — | Draw the entity's counter chips over the picture with their counts, exactly as the table does (default on). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.stat.label` | Stat label | `text` | — | `asset` | W | — | A stat chip's label ("Speed"), at most 24 characters. With an icon or icon image the chip draws the symbol instead, and the label stays its accessible name and tooltip. The target is `<layout id>#widget:<widget id>/stat:<index>`. |
| `item.ui-layout.stat.value` | Stat value | `text` | — | `asset` | W | — | A stat chip's value ("40", "3/5") or a binding like {seat.attackerPower}; drawn cut to 24 characters. The target is `<layout id>#widget:<widget id>/stat:<index>`. |
| `item.ui-layout.stat.change` | Change | `select` | — | `asset` | W | `same`, `up`, `down` | How the value compares with the printed one: `same` is drawn white, `up` green, `down` red. The target is `<layout id>#widget:<widget id>/stat:<index>`. |
| `item.ui-layout.stat.icon` | Icon | `select` | — | `asset` | W | — | A stat chip's icon from the HUD icon list, drawn in place of the label text, or "". The target is `<layout id>#widget:<widget id>/stat:<index>`. |
| `item.ui-layout.stat.icon-image` | Icon image | `select` | — | `asset` | W | — | A stat chip's image instead of its icon (and of the label text): a project raster file, or ONE string state binding whose value is such a path, or "". The target is `<layout id>#widget:<widget id>/stat:<index>`. |
| `item.ui-layout.badge.when` | Shown when | `select` | — | `asset` | W | — | A state reference that must be true for the badge to show ("" = always). The target is `<layout id>#widget:<widget id>/badge:<index>`. |

**Actions** (14)

| Action id | Label | Class | Target | Description |
|---|---|---|---|---|
| `item.ui-layout.widget.style.reset` | Reset style | W | `asset` | Remove the selected widget's style at the scope chosen by `item.ui-layout.widget.style.scope` (all devices = `style`; a screen class = its `placement.devices.<class>.style`). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.when.add` | + Condition | W | `asset` | Add a condition row to the selected widget's `when`. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.widget.when.remove` | Remove condition | W | `asset` | Remove one condition row. The target is `<layout id>#widget:<widget id>/when:<index>`. |
| `item.ui-layout.widget.when.clear` | Clear condition | W | `asset` | Remove the whole `when` (including one only editable as JSON). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.button.add` | + Button | W | `asset` | Add a button (an action, or a choice option) to the selected widget. The target is `<layout id>#widget:<widget id>/button:<actions\|options>`. |
| `item.ui-layout.button.remove` | Remove button | W | `asset` | Remove a button from the selected widget. The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.move-up` | Move up | W | `asset` | Move a button one place earlier. The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.button.move-down` | Move down | W | `asset` | Move a button one place later. The target is `<layout id>#widget:<widget id>/button:<actions\|options\|confirm>:<button id>`. |
| `item.ui-layout.counter.add` | + Counter | W | `asset` | Add a counter to the selected player panel. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.counter.remove` | Remove counter | W | `asset` | Remove a counter. The target is `<layout id>#widget:<widget id>/counter:<index>`. |
| `item.ui-layout.badge.add` | + Badge | W | `asset` | Add a badge to the selected player panel. The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.stat.add` | + Stat | W | `asset` | Add a stat chip to the selected card spotlight (at most 8). The target is `<layout id>#widget:<widget id>`; the widget must be the selected one. |
| `item.ui-layout.stat.remove` | Remove stat | W | `asset` | Remove a stat chip. The target is `<layout id>#widget:<widget id>/stat:<index>`. |
| `item.ui-layout.badge.remove` | Remove badge | W | `asset` | Remove a badge. The target is `<layout id>#widget:<widget id>/badge:<index>`. |

## `item.ui-layout.state`

**UI Layout ▸ State** · surface `editor` · target `asset`

How it opens: UI Layout tab ▸ State sub-tab (declared state keys).

**Fields** (5)

| Field id | Label | Kind | Unit | Target | Class | Range / options | Description |
|---|---|---|---|---|---|---|---|
| `item.ui-layout.state.key` | Key | `text` | — | `asset` | W | — | Rename a declared state key (bindings are not rewritten). The target is `<layout id>#state:<key>`. |
| `item.ui-layout.state.type` | Type | `select` | — | `asset` | W | `string`, `number`, `boolean` | The key's value type; a default of another type is dropped. The target is `<layout id>#state:<key>`. |
| `item.ui-layout.state.scope` | Scope | `select` | — | `asset` | W | `table`, `seat` | One value for the table, or one per seat (read as `{seat.key}` — the viewer's own seat). The target is `<layout id>#state:<key>`. |
| `item.ui-layout.state.private` | Private | `boolean` | — | `asset` | W | — | Per-seat keys only: each value travels ONLY to its own seat (scripts' ui.set routes it privately). The target is `<layout id>#state:<key>`. |
| `item.ui-layout.state.default` | Default | `text` | — | `asset` | W | — | The value written when the game's scripts start (typed by Type; "" clears it). The target is `<layout id>#state:<key>`. |

**Actions** (2)

| Action id | Label | Class | Target | Description |
|---|---|---|---|---|
| `item.ui-layout.state.add` | + State key | W | `asset` | Declare a new state key (string, one value) for bindings and scripts. |
| `item.ui-layout.state.remove` | Remove key | D | `asset` | Remove a declared state key (bindings that read it then warn). The target is `<layout id>#state:<key>`. |

## `item.ui-layout.preview`

**UI Layout ▸ Previews** · surface `editor` · target `asset`

How it opens: UI Layout tab ▸ Previews sub-tab (named preview fixtures).

**Fields** (5)

| Field id | Label | Kind | Unit | Target | Class | Range / options | Description |
|---|---|---|---|---|---|---|---|
| `item.ui-layout.preview.name` | Name | `text` | — | `asset` | W | — | A preview fixture's name. The target is `<layout id>#preview:<index>`. |
| `item.ui-layout.preview.view-as` | View as | `select` | — | `asset` | W | — | Whose screen the fixture shows: `host`, `spectator` or `seat:<seat id>`. The target is `<layout id>#preview:<index>`. |
| `item.ui-layout.preview.device` | Device | `select` | — | `asset` | W | ``, `desktop`, `touch`, `vr`, `ar` | The device the fixture is meant for (informational; the canvas device is the tab's Device). The target is `<layout id>#preview:<index>`. |
| `item.ui-layout.preview.variant` | Variant | `text` | — | `asset` | W | — | The variant id `{ variant: [...] }` conditions see in this fixture ("" for none). The target is `<layout id>#preview:<index>`. |
| `item.ui-layout.preview.value` | Value | `text` | — | `asset` | W | — | One fixture state value, typed by the key's declaration ("" clears it). The target is `<layout id>#preview:<index>/value:<table\|seat id>:<key>`. |

**Actions** (3)

| Action id | Label | Class | Target | Description |
|---|---|---|---|---|
| `item.ui-layout.preview.add` | + Preview | W | `asset` | Add a named preview fixture (viewing as red) and make it the canvas's preview state. |
| `item.ui-layout.preview.remove` | Remove preview | W | `asset` | Remove a preview fixture. The target is `<layout id>#preview:<index>`. |
| `item.ui-layout.preview.use` | Preview this | R | `asset` | Make a fixture the canvas's preview state (and its viewer the canvas's View as). View state only. The target is `<layout id>#preview:<index>`. |
