@json-to-office/jto 2.4.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/cli.js +123 -39
  2. package/dist/cli.js.map +1 -1
  3. package/dist/client/assets/HomePage-BlzZ7qG4.js +245 -0
  4. package/dist/client/assets/HomePage-BlzZ7qG4.js.map +1 -0
  5. package/dist/client/assets/{JsonEditorPage-DjLAUBv5.js → JsonEditorPage-kWuP_kL3.js} +3 -3
  6. package/dist/client/assets/{JsonEditorPage-DjLAUBv5.js.map → JsonEditorPage-kWuP_kL3.js.map} +1 -1
  7. package/dist/client/assets/{MonacoPluginProvider-D_GUFwWQ.js → MonacoPluginProvider-Dbv1PrO2.js} +6 -6
  8. package/dist/client/assets/{MonacoPluginProvider-D_GUFwWQ.js.map → MonacoPluginProvider-Dbv1PrO2.js.map} +1 -1
  9. package/dist/client/assets/{_virtual_jto-plugin-type-libs-9elxvZT2.js → _virtual_jto-plugin-type-libs-B6KyD9RL.js} +9182 -4529
  10. package/dist/client/assets/{_virtual_jto-plugin-type-libs-9elxvZT2.js.map → _virtual_jto-plugin-type-libs-B6KyD9RL.js.map} +1 -1
  11. package/dist/client/assets/_virtual_jto-sandbox-runtime-Bzo2M5U7.js +2 -0
  12. package/dist/client/assets/_virtual_jto-sandbox-runtime-Bzo2M5U7.js.map +1 -0
  13. package/dist/client/assets/editor-CwEocOY2.js +16 -0
  14. package/dist/client/assets/editor-CwEocOY2.js.map +1 -0
  15. package/dist/client/assets/editor-monaco-json-D_oiidNg.js +24 -0
  16. package/dist/client/assets/editor-monaco-json-D_oiidNg.js.map +1 -0
  17. package/dist/client/assets/index--kF4jVbp.css +1 -0
  18. package/dist/client/assets/index-DFJaEoi0.js +27 -0
  19. package/dist/client/assets/index-DFJaEoi0.js.map +1 -0
  20. package/dist/client/assets/index-UheDso2P.js +2 -0
  21. package/dist/client/assets/index-UheDso2P.js.map +1 -0
  22. package/dist/client/assets/preview-CWdUATNl.js +4 -0
  23. package/dist/client/assets/preview-CWdUATNl.js.map +1 -0
  24. package/dist/client/assets/useQualityAnalysis-Cl4QPeOT.js +6 -0
  25. package/dist/client/assets/useQualityAnalysis-Cl4QPeOT.js.map +1 -0
  26. package/dist/client/index.html +2 -2
  27. package/dist/client/templates/client-report-blocks.docx.json +791 -0
  28. package/dist/client/templates/consulting-deck-blocks.pptx.json +455 -0
  29. package/dist/client/templates/data-report-presentation.pptx.json +108 -36
  30. package/dist/client/templates/management-plan.pptx.json +100 -22
  31. package/dist/client/templates/minimalist-pitch-deck.pptx.json +172 -101
  32. package/dist/prompts/instructions-edit-document-pptx-blocks.md +77 -0
  33. package/dist/prompts/instructions-edit-document-pptx-slides.md +15 -21
  34. package/dist/prompts/instructions-edit-document-pptx.md +34 -53
  35. package/dist/prompts/instructions-edit-pptx.md +9 -8
  36. package/dist/prompts/instructions-generate-pptx.md +13 -17
  37. package/dist/prompts/pptx-core.md +104 -127
  38. package/dist/prompts/pptx-design.md +115 -109
  39. package/package.json +10 -9
  40. package/dist/client/assets/HomePage-mtUb6jxc.js +0 -251
  41. package/dist/client/assets/HomePage-mtUb6jxc.js.map +0 -1
  42. package/dist/client/assets/_virtual_jto-sandbox-runtime-Dqq17bow.js +0 -2
  43. package/dist/client/assets/_virtual_jto-sandbox-runtime-Dqq17bow.js.map +0 -1
  44. package/dist/client/assets/editor-ZbEHVEFs.js +0 -16
  45. package/dist/client/assets/editor-ZbEHVEFs.js.map +0 -1
  46. package/dist/client/assets/editor-monaco-json-FaaVfftD.js +0 -24
  47. package/dist/client/assets/editor-monaco-json-FaaVfftD.js.map +0 -1
  48. package/dist/client/assets/editor-refs-store-DAEAPqEk.js +0 -2
  49. package/dist/client/assets/editor-refs-store-DAEAPqEk.js.map +0 -1
  50. package/dist/client/assets/index-Bj6ZAKUc.css +0 -1
  51. package/dist/client/assets/index-DRbATnbJ.js +0 -5
  52. package/dist/client/assets/index-DRbATnbJ.js.map +0 -1
  53. package/dist/client/assets/preview-CM2ywF-8.js +0 -4
  54. package/dist/client/assets/preview-CM2ywF-8.js.map +0 -1
  55. package/dist/client/assets/useQualityAnalysis-ClgkaIc2.js +0 -6
  56. package/dist/client/assets/useQualityAnalysis-ClgkaIc2.js.map +0 -1
  57. package/dist/prompts/instructions-edit-document-pptx-templates.md +0 -63
@@ -11,21 +11,22 @@ IMPORTANT: Produce ONLY the modified fragment that replaces the selected text ab
11
11
 
12
12
  ### PPTX selection editing rules
13
13
 
14
- - This fragment lives inside a template-based slide. The template's placeholders already define default styling.
15
- - **Don't add props the placeholder already defines** — `fontSize`, `fontFace`, `color`, `bold`, `italic`, `align`, `valign`, `margin`, `charSpacing`, `lineSpacing`, `style`, and position are inherited automatically.
16
- - Grid positions are slide-relative, not placeholder-relative.
17
- - Keep components minimal — only include props that differ from placeholder defaults.
14
+ - If the fragment is a block invocation (`"name": "block"`), keep its `ref` and change only the `slots`. An invocation takes no coordinates or styling — the definition owns them.
15
+ - If the fragment is slot content (a chart, an image, a text placed in a component slot), it may carry its data and styling but never `x`, `y`, `w`, `h`, `position` or `grid`.
16
+ - If the fragment is a block definition, keep every slot the document's invocations fill; bindings (`$slot`, `$theme` with a `default`, `$if`) stay valid.
17
+ - If the fragment is a coordinate-authored component, keep its position unless asked to move it, and prefer named `style` values and theme color names over raw sizes and hex.
18
+ - Keep components minimal; do not add props a style or a definition already provides.
18
19
 
19
20
  ### Example
20
21
 
21
22
  **Selected text:**
22
23
  ```json
23
- { "name": "text", "props": { "text": "Hello world", "fontSize": 14, "bold": false } }
24
+ { "name": "block", "props": { "ref": "action-chart", "slots": { "title": "Revenue grew 18%", "chart": { "name": "chart", "props": { "type": "bar", "data": [{ "name": "Revenue", "labels": ["Q1", "Q2"], "values": [4.2, 4.6] }] } } } } }
24
25
  ```
25
26
 
26
- **User request:** "Change to Welcome and make it bold"
27
+ **User request:** "Add a takeaway saying reliability drove the gain"
27
28
 
28
- **Correct output** (omit fontSize if placeholder provides it):
29
+ **Correct output** (same ref, one more slot):
29
30
  ```json
30
- { "name": "text", "props": { "text": "Welcome", "bold": true } }
31
+ { "name": "block", "props": { "ref": "action-chart", "slots": { "title": "Revenue grew 18%", "chart": { "name": "chart", "props": { "type": "bar", "data": [{ "name": "Revenue", "labels": ["Q1", "Q2"], "values": [4.2, 4.6] }] } }, "takeaway": "Reliability, not price, drove the gain." } } }
31
32
  ```
@@ -2,25 +2,21 @@ The user wants you to generate a complete presentation JSON from scratch.
2
2
 
3
3
  Produce a full PPTX JSON wrapped in a ```json code block:
4
4
 
5
- - Define 2–3 template slides (TITLE_TEMPLATE, CONTENT_TEMPLATE, and optionally TWO_COLUMN_TEMPLATE)
6
- - Templates should include header bars, footer bars, and branding text as `objects`
7
- - **Every component** (in `objects[]`, `placeholders`, `children[]`) MUST use `{ "name": "<type>", "props": { ... } }`. Never `{ "type": "...", ... }` with flat props
8
- - The presentation MUST include a `"grid"` prop on `pptx.props` (e.g. `"grid": { "columns": 12, "rows": 6, "margin": 0.5, "gutter": 0.2 }`)
9
- - Templates with header/footer bars MUST set `"grid": { "margin": { "top": <header-height + 0.2> } }` so row 0 starts below the header
10
- - Generate 5–8 slides that reference these templates and fill their placeholders
11
- - Mix component types: text, shapes, tables where appropriate
12
- - Include a title slide and a closing/thank-you slide
13
- - Use `charSpacing` on wordmarks, uppercase labels, and section identifiers for professional typography
14
- - For refined/elegant designs, use light font variants (e.g. `"Inter Light"`) via `fontFace` instead of relying on bold alone
5
+ - Set `theme` (prefer `consulting`), `slideWidth: 13.333` and `slideHeight: 7.5` on `pptx.props`
6
+ - Define the blocks the deck needs in `pptx.props.blocks`: copy the reference blocks you invoke verbatim, and define your own (a cover, a statement, a two-column comparison, a metric row) as percentage frames with type-role bindings and `$if` around optional slots
7
+ - Generate 5–8 slides; every standard slide invokes a block with `{ "name": "block", "props": { "ref": "...", "slots": { ... } } }` and supplies content only — no coordinates on an invocation or in slot content
8
+ - Include a cover slide and a closing slide
9
+ - Coordinate-authored slides are for one-off layouts only
10
+ - **Every component** (in a block `body`, a component slot, or `slide.children`) MUST use `{ "name": "<type>", "props": { ... } }`. Never `{ "type": "...", ... }` with flat props
11
+ - Use `charSpacing` on wordmarks and uppercase labels; use theme color names, not hex
15
12
 
16
13
  Before finalizing, verify:
17
14
 
18
- - [ ] No two text/shape components share the same position
19
- - [ ] Headings fit their container (short text or reduced fontSize)
20
- - [ ] `slideNumber` is in the bottom-right, not overlapping content
21
- - [ ] All `ellipse` shapes intended as circles have equal `w` and `h`
22
- - [ ] Initials and short labels inside shapes have no `\n` line breaks
23
- - [ ] Every template with a header/footer bar sets `grid.margin` to push content clear
15
+ - [ ] Every `ref` names a definition present in `props.blocks`
16
+ - [ ] Every `required` slot of every invocation is filled; slot text respects `maxWords` and `oneLine`
17
+ - [ ] No `templates`, `template`, `placeholders` or `layout` keys anywhere
18
+ - [ ] Block bodies use percentage frames and `fit` on titles; theme bindings carry a `default`
19
+ - [ ] Page numbers and trackers live in block bodies, not overlapping content
24
20
  - [ ] Tables specify `rowH` (0.4–0.55") and `margin` ([3, 6, 3, 6])
25
- - [ ] Tables use `borderRadius` (0.1–0.2) for polished appearance
21
+ - [ ] `ellipse` shapes intended as circles have equal `w` and `h`
26
22
  - [ ] Cells with Unicode symbols (✓, —) use `fontFace: "Arial"`
@@ -2,153 +2,133 @@
2
2
 
3
3
  ## Architecture
4
4
 
5
- A PPTX presentation has this structure:
5
+ A PPTX presentation is one JSON tree:
6
6
 
7
7
  ```
8
- pptx.props.templates[] → reusable slide layouts (defined once)
9
- pptx.children[].props.template → slide references a template by name
10
- pptx.children[].props.placeholders → slide fills template's named regions
8
+ pptx.props → deck settings: title, theme, slideWidth/slideHeight, grid
9
+ pptx.props.blocks → reusable slide layouts, defined once as JSON (name → definition)
10
+ pptx.children[] → slides
11
+ slide.children[] → content: block invocations and/or positioned components
11
12
  ```
12
13
 
13
- **Template slides are the foundation of every presentation.** Every slide MUST reference a template. Templates enforce visual consistency, reduce repetition, and let placeholders carry default styling so slides stay minimal. Custom (templateless) slides are an absolute last resort.
14
+ **Blocks are the foundation of every presentation.** A block definition owns a layout — every coordinate, every type role, every theme binding — and names the content it takes as `slots`. A slide invokes it with `{ "name": "block", "props": { "ref": "<name>", "slots": { ... } } }` and supplies only words and data. Define each standard layout once in `props.blocks` and invoke it on every slide that uses it; coordinate-authored slides are for one-off layouts only.
14
15
 
15
- ## Template Slide Definition
16
+ There are no slide templates, placeholders or a `layout` prop. Never emit `templates`, `template` or `placeholders` keys: they are rejected.
16
17
 
17
- Each template has:
18
- - `name` — unique identifier (SCREAMING_SNAKE_CASE)
19
- - `background` — optional, color or image
20
- - `objects[]` — fixed components (shapes, text, images) that appear on every slide using this template. Uses the same `{ name, props }` format as slide children
21
- - `placeholders[]` — named content regions that slides fill with components
22
- - `slideNumber` — optional, position and style of auto slide numbers
23
- - `grid` — optional grid override, merged with the presentation grid. Use this to shift the content area below header bars. Example: `"grid": { "margin": { "top": 1.1 } }` pushes row 0 below a 0.9" header.
24
-
25
- ### Fixed objects in `objects[]`
26
-
27
- Template objects use the **same `{ name, props }` component format** as slide children. Any content component (shape, text, image, table, chart) can be used as a template object.
28
-
29
- **Important:** Fixed decorations (header bars, footer bars) should use absolute `x`/`y`/`w`/`h`, not grid — because the template's `grid` override shifts grid positions, and decorations shouldn't shift themselves.
30
-
31
- ```json
32
- { "name": "shape", "props": { "type": "rect", "x": 0, "y": 0, "w": 10, "h": 0.9, "fill": { "color": "primary" } } }
33
- { "name": "shape", "props": { "type": "roundRect", "x": 0, "y": 0, "w": 10, "h": 0.9, "fill": { "color": "primary" }, "rectRadius": 0.15 } }
34
- { "name": "text", "props": { "text": "COMPANY", "x": 0.6, "y": 0.15, "w": 4, "h": 0.6, "fontSize": 14, "bold": true, "color": "FFFFFF" } }
35
- { "name": "shape", "props": { "type": "line", "x": 0.5, "y": 2, "w": 9, "h": 0, "line": { "color": "accent", "width": 1 } } }
36
- { "name": "image", "props": { "path": "logo.png", "x": 8.5, "y": 0.15, "w": 1, "h": 0.6 } }
37
- ```
38
-
39
- Template objects support all component props including `rectRadius`, `shadow`, `rotate`, `fill.transparency`, `line.dashType`, rich text segments, etc.
40
-
41
- ### Placeholder definition
42
-
43
- ```json
44
- {
45
- "name": "body",
46
- "grid": { "column": 0, "row": 2, "columnSpan": 12, "rowSpan": 3 },
47
- "defaults": { "name": "text", "props": { "style": "body", "fontSize": 14 } }
48
- }
49
- ```
50
-
51
- - `name` — key used in `slide.props.placeholders` to fill this region
52
- - Position via `grid` (preferred) or `x`/`y`/`w`/`h`
53
- - `defaults` — optional component stub (`{ name, props }`) whose props are inherited by the component placed in this placeholder. Supports any component type — text defaults for text placeholders, chart defaults for chart placeholders, etc.
54
-
55
- ## Grid Positioning (preferred)
56
-
57
- Grid is a **presentation-level** prop (on `pptx.props`), not a theme-level setting:
18
+ ## Block definitions
58
19
 
59
20
  ```json
60
- {
61
- "name": "pptx",
62
- "props": {
63
- "theme": "corporate",
64
- "grid": { "columns": 12, "rows": 6, "margin": { "top": 0.75, "right": 0.6, "bottom": 0.5, "left": 0.6 }, "gutter": { "column": 0.2, "row": 0.15 } }
21
+ "blocks": {
22
+ "statement": {
23
+ "description": "One sentence on an otherwise empty slide.",
24
+ "slots": {
25
+ "text": { "type": "string", "required": true, "maxWords": 30, "role": "actionTitle" },
26
+ "source": { "type": "string", "maxWords": 20, "role": "source" }
27
+ },
28
+ "body": [
29
+ {
30
+ "name": "text",
31
+ "props": {
32
+ "text": { "$slot": "/text" },
33
+ "style": "display",
34
+ "fontSize": { "$theme": "/styles/display/fontSize", "default": 28 },
35
+ "x": "3.75%", "y": "30%", "w": "92.5%", "h": "30%",
36
+ "valign": "middle",
37
+ "fit": { "maxLines": 3, "shrink": [24, 22] }
38
+ }
39
+ },
40
+ {
41
+ "$if": "/source",
42
+ "then": {
43
+ "name": "text",
44
+ "props": {
45
+ "text": { "$slot": "/source" },
46
+ "style": "source",
47
+ "fontSize": { "$theme": "/styles/source/fontSize", "default": 9 },
48
+ "x": "3.75%", "y": "94.5%", "w": "75%", "h": "5%"
49
+ }
50
+ }
51
+ }
52
+ ]
65
53
  }
66
54
  }
67
55
  ```
68
56
 
69
- Use the 12-column × 6-row grid instead of absolute x/y/w/h:
57
+ - `slots` — named inputs: `type` (`string`, `number`, `integer`, `boolean`, `object`, `array`, `component`), `required`, `default`, `description`, constraints (`maxWords`, `oneLine`, `minItems`/`maxItems`, `enum`), and an optional `role` (`actionTitle`, `takeaway`, `source`, `tracker`, `footer`) so a quality profile can require or measure it.
58
+ - `body` — ordinary slide content, expanded at the invocation. Bindings read inputs: `{ "$slot": "/title" }`, `{ "$theme": "/styles/display/fontSize", "default": 28 }` (always give theme bindings a `default`), `{ "$context": "/slide/width" }`, `{ "$if": "/source", "then": [...] , "else": [...] }` (an omitted optional slot collapses its region, decorations included), `{ "$each": "/items", "template": { ... } }` with `{ "$item": "/label" }`, `{ "$count": "/items" }`, `{ "$join": [...], "separator": " " }`, `{ "$measure": "width", "fraction": 0.5, "unit": "in" }`.
59
+ - A component slot is placed with `{ "$slot": "/chart", "props": { "x": "0%", "y": "29%", "w": "68%", "h": "62%", ... } }`: the definition's props sit beneath the slot content's own. The content may not carry `x`, `y`, `w`, `h`, `position` or `grid`.
60
+ - `slide` — optional `{ "background", "notes", "grid" }` the invoking slide inherits unless it states its own.
61
+ - **Geometry as percentages of the slide** (`"x": "3.75%"`) so the definition lays out on every canvas; sizes bound to type roles with defaults so it renders on every theme.
70
62
 
71
- ```json
72
- "grid": { "column": 0, "row": 1, "columnSpan": 6, "rowSpan": 2 }
73
- ```
74
-
75
- - Columns: 0–11, Rows: 0–5
76
- - Grid respects presentation-level margins (default 0.5") and gutters (default 0.2")
77
- - Use `columnSpan`/`rowSpan` to size elements
78
- - Explicit `x`/`y`/`w`/`h` override grid when both are present
63
+ ### Engine operations inside a body
79
64
 
80
- ## Filling Placeholders (Slide Level)
65
+ - **Frame** — a `group` with `x`/`y`/`w`/`h` (or `grid`) is a nested coordinate system: children position relative to it; omitted `x`/`y` or `w`/`h` mean the frame's own.
66
+ - **Distribution** — a `group` with `"direction": "row" | "column"`, optional `gap` and `weights`, gives each child an equal or weighted cell. An `$each` inside a row redistributes for two, three or four items; an `$if` child that collapsed is not counted.
67
+ - **Bounded fit** — `text.fit: { "maxLines", "shrink": [24, 22] }` steps a title down through the declared sizes when it does not fit, then fails generation rather than spilling.
68
+ - **Nested grid** — `group.gridConfig` for grid placements inside the group.
81
69
 
82
- Slides reference a template and fill each placeholder with a single component:
70
+ ## Invoking a block on a slide
83
71
 
84
72
  ```json
85
73
  {
86
74
  "name": "slide",
87
- "props": {
88
- "template": "CONTENT_TEMPLATE",
89
- "placeholders": {
90
- "heading": { "name": "text", "props": { "text": "Slide Title" } },
91
- "body": { "name": "text", "props": { "text": "Key insight here." } }
75
+ "props": { "meta": { "title": "Revenue" } },
76
+ "children": [
77
+ {
78
+ "name": "block",
79
+ "props": {
80
+ "ref": "action-chart",
81
+ "slots": {
82
+ "title": "Revenue grew 18% as on-time delivery reached 94% of contracted work",
83
+ "tracker": "Performance",
84
+ "chart": {
85
+ "name": "chart",
86
+ "props": {
87
+ "type": "bar",
88
+ "valAxisTitle": "Revenue (€m)",
89
+ "data": [{ "name": "Revenue", "labels": ["Q1", "Q2", "Q3", "Q4"], "values": [4.2, 4.6, 5.1, 5.6] }]
90
+ }
91
+ },
92
+ "takeaway": "Reliability, not price, drove the gain.",
93
+ "source": "Source: quarterly operating review, 2026."
94
+ }
95
+ }
92
96
  }
93
- }
97
+ ]
94
98
  }
95
99
  ```
96
100
 
97
- Each placeholder maps to exactly one component (not an array). The component inherits the placeholder's position and `defaults` props.
98
-
99
- ### Placeholder inheritance
101
+ - An invocation accepts only `ref` and `slots` — no coordinates, no styling. The `ref` must name a definition in this document's `props.blocks`; nothing is built in.
102
+ - Fill every `required` slot; omit an optional slot and its region disappears.
103
+ - Slot content honours the slot's constraints (`maxWords`, `oneLine`); a chart or image placed in a component slot carries its data, never its position.
104
+ - Blocks and coordinate-authored components mix freely on one slide; a block with `slide` effects must be a direct child of the slide.
105
+ - Label every slide with `"meta": { "title": "..." }` (authoring-only, never rendered) so editors show a navigable outline.
100
106
 
101
- Placeholders provide default props via `defaults`. The component placed in the placeholder inherits these — **do NOT re-specify a prop if `defaults` already defines it.**
107
+ ## Grid positioning (coordinate-authored content)
102
108
 
103
- Resolution order (most specific wins): `component props → defaults props → position from placeholder`
104
-
105
- This is a simple spread: `{ ...position, ...defaults.props, ...component.props }`.
106
-
107
- **Good** — defaults defines `fontSize: 14` and `style: "body"`, component omits them:
108
- ```json
109
- { "name": "text", "props": { "text": "Key insight here." } }
110
- ```
109
+ Grid is a **presentation-level** prop (on `pptx.props`), not a theme-level setting:
111
110
 
112
- **Bad** — redundantly re-specifying what defaults already provides:
113
111
  ```json
114
- { "name": "text", "props": { "text": "Key insight here.", "fontSize": 14, "style": "body" } }
112
+ {
113
+ "name": "pptx",
114
+ "props": {
115
+ "theme": "consulting",
116
+ "slideWidth": 13.333,
117
+ "slideHeight": 7.5,
118
+ "grid": { "columns": 12, "rows": 8, "margin": 0.5, "gutter": 0.2 }
119
+ }
120
+ }
115
121
  ```
116
122
 
117
- Only override a defaults prop when you genuinely need a different value for that specific component.
118
-
119
- ## Semantic Colors
120
-
121
- Use theme color names, not hex codes:
122
- - `primary`, `secondary`, `accent` — brand colors
123
- - `background`, `background2` — surface colors
124
- - `text`, `text2` — text colors
125
- - `accent4`, `accent5`, `accent6` — additional accents
126
-
127
- Only use hex (e.g. `"FFFFFF"`) for absolute white/black when needed.
123
+ Use the grid instead of absolute x/y/w/h for one-off slides: `"grid": { "column": 0, "row": 1, "columnSpan": 6, "rowSpan": 2 }`. Columns 0–11, rows 0–(rows−1). Explicit `x`/`y`/`w`/`h` override grid when both are present. Always declare `slideWidth`/`slideHeight` (13.333 × 7.5 for 16:9); omitted, the deck falls back to 4:3.
128
124
 
129
- ## Named Styles
125
+ ## Semantic colors
130
126
 
131
- Themes define a `styles` map with predefined text style presets. Use `"style"` on text/shape components to apply formatting without repeating props.
127
+ Use theme color names, not hex codes: `primary`, `secondary`, `accent` (brand), `background`, `background2` (surfaces), `text`, `text2` (text), `accent4`, `accent5`, `accent6` (additional accents). Only use hex (e.g. `"FFFFFF"`) for absolute white/black when needed.
132
128
 
133
- **Available style names:** `title`, `subtitle`, `heading1`, `heading2`, `heading3`, `body`, `caption`
129
+ ## Named styles
134
130
 
135
- **Usage on components:**
136
- ```json
137
- { "name": "text", "props": { "text": "My Title", "style": "title" } }
138
- { "name": "shape", "props": { "type": "roundRect", "text": "KPI", "style": "caption", "fill": { "color": "background2" } } }
139
- ```
140
-
141
- **Usage on placeholder defaults:**
142
- ```json
143
- { "name": "heading", "grid": { "column": 0, "row": 0, "columnSpan": 12 }, "defaults": { "name": "text", "props": { "style": "heading1" } } }
144
- ```
145
-
146
- **Resolution cascade (most specific wins):**
147
- `component props → component style → defaults props → defaults style → theme defaults`
148
-
149
- Explicit props always override style values. Example: `"style": "heading1", "fontSize": 32` → uses 32pt, not the style's fontSize.
150
-
151
- **Built-in defaults (all themes):**
131
+ Themes define a `styles` map of text presets. Use `"style"` on text/shape components to apply formatting without repeating props: `title`, `subtitle`, `heading1`, `heading2`, `heading3`, `body`, `caption`, plus the type roles a theme declares (`display`, `eyebrow`, `stat`, `quote`, `label`, `footer`, `tracker`, `source`). Explicit props override style values; inside a block, bind the size to the role and give it a default: `"fontSize": { "$theme": "/styles/display/fontSize", "default": 28 }`.
152
132
 
153
133
  | Style | fontSize | bold | italic | fontColor | align |
154
134
  |----------|----------|------|--------|-----------|--------|
@@ -162,19 +142,16 @@ Explicit props always override style values. Example: `"style": "heading1", "fon
162
142
 
163
143
  Heading styles (`title`, `heading1-3`) auto-use `theme.fonts.heading`; others use `theme.fonts.body`.
164
144
 
165
- Themes can override styles in the `styles` key:
166
- ```json
167
- "styles": {
168
- "title": { "fontSize": 40, "bold": true, "fontColor": "accent", "align": "left" }
169
- }
170
- ```
171
-
172
- ## Available Components
145
+ ## Available components
173
146
 
174
- Use these inside `placeholders`, `children`, or template `objects`:
175
- - **text** — headings, paragraphs, bullets. Props: `text`, `fontSize`, `bold`, `italic`, `color`, `align`, `bullet`, `lineSpacing`, `charSpacing`, `paraSpaceAfter`
176
- - **shape** — rectangles, circles, arrows, etc. Props: `type` (rect, roundRect, ellipse, triangle, etc.), `fill`, `text` (string or `[{ text, fontSize?, color?, bold?, italic?, breakLine? }]` for rich text), `fontSize`, `fontColor`, `charSpacing`
147
+ Use these inside `slide.children`, a block `body`, or a component slot:
148
+ - **text** — headings, paragraphs, bullets. Props: `text`, `style`, `fontSize`, `bold`, `italic`, `color`, `align`, `valign`, `bullet`, `lineSpacing`, `charSpacing`, `paraSpaceAfter`, `fit`
149
+ - **shape** — rectangles, circles, lines, arrows. Props: `type` (rect, roundRect, ellipse, line, triangle, …), `fill`, `line`, `text` (string or rich segments), `fontSize`, `fontColor`, `charSpacing`
177
150
  - **table** — data grids. Props: `rows` (2D array of strings or cell objects), `colW`, `rowH`, `border`, `fontSize`, `margin`, `borderRadius`
178
151
  - **image** — pictures. Props: `path` or `base64`, `sizing` ({ type: "cover"|"contain" })
179
- - **chart** — **DEFAULT for all charts.** Native PowerPoint chart — editable, no external server. Always use this unless the user explicitly asks for Highcharts. Title, legend, and axis label colors auto-default to the theme's `text` color for proper contrast on any background. Props: `type` (area, bar, bar3D, bubble, doughnut, line, pie, radar, scatter), `data` (array of `{ name?, labels?, values?, sizes? }`), `showLegend`, `showTitle`, `title`, `titleColor`, `chartColors` (hex or semantic), `legendPos`, `legendColor`, axis options (`catAxisTitle`, `valAxisTitle`, `valAxisMinVal`, `valAxisMaxVal`, `valAxisLabelFormatCode`, `catAxisLabelColor`, `valAxisLabelColor`), bar options (`barDir`, `barGrouping`, `barGapWidthPct`), line options (`lineSmooth`, `lineDataSymbol`, `lineSize`), pie/doughnut (`firstSliceAng`, `holeSize`), radar (`radarStyle`), data labels (`dataLabelColor`, `dataLabelFontSize`, `dataLabelPosition`)
180
- - **highcharts** — **ONLY use when the user explicitly requests Highcharts.** Renders charts via Highcharts as images (not editable in PowerPoint). Props: `chartOptions` (Highcharts options object), `width`, `height`
152
+ - **chart** — **DEFAULT for all charts.** Native PowerPoint chart — editable, no external server. Props: `type` (area, bar, bar3D, bubble, doughnut, line, pie, radar, scatter), `data` (array of `{ name?, labels?, values?, sizes? }`), `showLegend`, `legendPos`, `chartColors` (semantic names), `title`, axis options (`catAxisTitle`, `valAxisTitle`, `valAxisMinVal`, `valAxisMaxVal`, `valAxisLabelFormatCode`), bar options (`barDir`, `barGrouping`), line options (`lineSmooth`, `lineDataSymbol`), pie/doughnut (`holeSize`), data labels (`dataLabelPosition`)
153
+ - **highcharts** — **ONLY when the user explicitly requests Highcharts.** Renders as an image. Props: `chartOptions`, `width`, `height`
154
+ - **group** — transparent container; a frame with `x`/`y`/`w`/`h`, a row or column with `direction`
155
+ - **block** — invoke a definition from `props.blocks`
156
+
157
+ Every component is `{ "name": "<type>", "props": { ... } }`. Never `{ "type": "...", ... }` with flat props. For page numbers, use a text component with `"text": "{PAGE_NUMBER} / {PAGE_COUNT}"`.