返回 ppt-master
shared-standards-core.md
根目录 / skills / ppt-master / references / shared-standards-core.md
1 # Shared SVG Core Standards
2
3 Mandatory reference for every route that authors or regenerates slide visuals through SVG. It owns XML validity, the closed generated-authoring surface, basic converter compatibility, page closure, semantic grouping, shared visual-quality defaults, and fidelity vocabulary.
4
5 **Conditional module routing**:
6
7 | Trigger | Load |
8 |---|---|
9 | Default or Quick Generate; otherwise noncanonical/alpha paint, advanced line or text treatment, gradient/filter/effect, transform, freeform/radial geometry, or constructed style | [`svg-effects.md`](./svg-effects.md) |
10 | A page will use a preset pattern fill or evaluate native chart/table replacement | [`native-data-interface.md`](./native-data-interface.md) before deciding eligibility or emitting metadata |
11 | `pptx_structure.mode: structured` | [`pptx-structure-interface.md`](./pptx-structure-interface.md) |
12
13 **Default — shared aesthetic baseline (may be overridden by explicit user, installed template / brand, or locked / Quick-resolved visual-style requirements)**: Required / Forbidden technical contracts remain absolute. When a higher authority is silent, build clear hierarchy through typography and leading, alignment, negative space, purposeful imagery / icons, and restrained repetition before decoration. Deliberate tightness, imbalance, off-axis placement, or container-heavy structure remains valid when that authority calls for it.
14
15 | Concern | Shared default |
16 |---|---|
17 | Text-block rhythm | Use §4.2 leading. Make the baseline step into a new paragraph visibly larger than the intra-paragraph line step; keep the extra gap between list items smaller than paragraph separation but large enough to scan each item. Repeated peer blocks share one rhythm unless their hierarchy differs. |
18 | Natural wrapping | Break at semantic phrase or punctuation boundaries where possible. Reflow the text frame or adjust neighboring geometry before using any permitted local size reduction. Let the final line run naturally shorter; avoid mechanically equal lines or a stranded single-character / single-word line when an earlier natural break preserves meaning. |
19 | Alignment and proximity | Establish shared axes from the current composition. Align related titles, copy, labels, images, and diagram nodes to those edges, centers, or baselines; group related elements more tightly than unrelated groups so spacing carries hierarchy. Break an axis only when the offset performs hierarchy, direction, or tension. |
20 | Visual weight | Judge weight from area, darkness, saturation, density, stroke, image detail, and elevation together. Distribute it to support the focal path; symmetry is optional, and deliberate imbalance may create direction. |
21 | Containers | Use a card or panel when it expresses grouping, hierarchy, boundary, capacity, or a distinct material plane. Otherwise prefer spacing, rules, or direct text / geometry; peer containers share treatment unless a semantic difference justifies contrast. |
22
23 **Default — active effects vocabulary (may resolve to no added technique when no visual job is diagnosed)**: Default and Quick Generate run the already-loaded [`svg-effects.md`](./svg-effects.md) §6.1 Visual Job Router before completing each page; apply a compatible technique only for a diagnosed visual job.
24
25 **Fidelity labels**:
26
27 | Label | Meaning |
28 |---|---|
29 | `Native-stable` | Generated PPTX uses the corresponding native DrawingML property or object and retains the documented semantics within the technique-specific limits. |
30 | `Native-normalized` | Export targets an editable DrawingML equivalent, but normalizes the SVG into another structure such as a freeform, run property, or simplified paint/effect. |
31 | `Approximate` | DrawingML has no exact SVG equivalent; export targets the intended effect through a documented approximation, and material differences require output review. |
32 | `Bake-required` | The runtime effect is outside the native contract; pre-render it into an image or rebuild it with explicit supported geometry. |
33
34 **Reading rules**:
35
36 - **Required** / **Forbidden** statements are non-negotiable technical boundaries.
37 - **Conditional** contracts apply only when the corresponding feature is used.
38 - **Reference — not a constraint** passages expose capabilities and recipes; they do not require every page or visual style to use them.
39 - The locked `visual_style` controls whether and how strongly a compatible effect is used. It never expands the technical boundary.
40
41 **Hard rule — generated authoring is fail-closed**: `svg_output/` and reusable
42 template SVGs may use only properties and conditional interfaces explicitly
43 listed in this file or a triggered module in the routing table above. `svg_quality_checker.py` rejects unknown inline visual
44 properties and conditional contracts that have no reliable compatibility
45 mapping; documented fallback forms remain valid and receive warnings.
46
47 **Default — recommended authoring and supported input stay separate (may
48 preserve supported input)**: generated SVG uses one predictable default
49 spelling, while converter-supported equivalent spellings remain valid input.
50 The checker may recommend normalization, but such warnings do not require
51 modification or block export. Only invalid, unsafe, or unreliably convertible
52 input is an error; do not remove converter support to enforce a narrower
53 generation preference.
54
55 **Hard rule — one-way fidelity vocabulary**: the labels above describe the
56 `svg_output/` → generated PPTX path. They do not promise reconstruction of the
57 original SVG syntax, `<defs>` graph, `<use>` structure, path commands, or
58 `<tspan>` layout after PPTX-to-SVG import, nor pixel identity across PowerPoint,
59 LibreOffice, Keynote, and WPS.
60
61 **Hard rule — capability boundary**: a recipe never expands converter support.
62 Use only the target elements and syntax documented by each conditional
63 contract. Unsupported element tags fail preflight; browser-rendered attributes
64 outside these contracts must not be assumed to have a DrawingML mapping.
65
66 ---
67
68
69 ## 1. Required Foundation, Forbidden Features, and Conditional Interfaces
70
71 ### 1.0 Text characters: must be well-formed XML
72
73 SVG is strict XML. Two rules for all text and attribute values:
74
75 | Character category | Required form | Forbidden form |
76 |---|---|---|
77 | Typography & symbols (em dash, en dash, ©, ®, →, ·, NBSP, full-width punctuation, emoji…) | **Raw Unicode characters** — write `—` `–` `©` `®` `→` directly | HTML named entities — `&mdash;` `&ndash;` `&copy;` `&reg;` `&rarr;` `&middot;` `&nbsp;` `&hellip;` `&bull;` etc. |
78 | XML reserved characters (`&`, `<`, `>`, `"`, `'`) | **XML entities only** — `&amp;` `&lt;` `&gt;` `&quot;` `&apos;` (e.g. `R&amp;D`, `error &lt; 5%`) | Bare `&` `<` `>` (e.g. `R&D`, `error < 5%`) |
79
80 One offending character invalidates the file and aborts export.
81
82 **Structural blacklist** (in addition to the character rules above):
83
84 | Banned Feature | Description |
85 |----------------|-------------|
86 | `mask` | Masks |
87 | `<style>` | Embedded stylesheets |
88 | `class` | CSS selector attributes |
89 | External CSS | External stylesheet links |
90 | `<foreignObject>` | Embedded external content |
91 | `textPath` | Text along a path |
92 | `@font-face` | Custom font declarations |
93 | `<animate*>` / `<set>` | SVG animations |
94 | `<script>` / event attributes | Scripts and interactivity |
95 | `<iframe>` | Embedded frames |
96
97 The blacklist above is exhaustive for globally forbidden structural syntax.
98 It is not a positive allowlist for every browser-rendered property. Features
99 that require a restricted form are valid only under the conditional contracts
100 below; unlisted visual properties are unsupported.
101
102 **Hard rule — inline visual-property allowlist**:
103
104 | Property family | Allowed inline `style` properties |
105 |---|---|
106 | Paint and line | `fill`, `stroke`, `stroke-width`, `stroke-dasharray`, `stroke-linecap`, `stroke-linejoin`, `fill-opacity`, `stroke-opacity`, `vector-effect` |
107 | Text | `font-family`, `font-size`, `font-weight`, `font-style`, `text-anchor`, `letter-spacing`, `text-decoration` |
108 | Alpha and definition paint | `opacity`, `stop-color`, `stop-opacity`, `flood-color`, `flood-opacity` |
109 | Literal geometry | The element-specific properties in §2.1 |
110 | Preview-only | `shape-rendering`; it does not change native geometry |
111
112 **Default — ordinary generated paint**: the table allows inline placement of
113 those property names. New solid paint uses uppercase six-digit `#RRGGBB`;
114 `fill` / `stroke` may instead use lowercase `none` or an exact local
115 `url(#id)`. Load [`svg-effects.md`](./svg-effects.md) before authoring any
116 alternative compatible color spelling, alpha/opacity channel, dash/cap/join,
117 gradient, filter, or constructed paint/effect. Existing compatible alternatives
118 remain valid input and receive recommendation warnings rather than errors.
119
120 Conditional properties with a required XML form stay out of inline style:
121 write `filter="url(#id)"`, `clip-path="url(#id)"`, and
122 `marker-start` / `marker-end` as direct attributes. `!important`, unknown CSS
123 properties, blend modes, isolation, and backdrop filters fail quality check.
124
125 The table registers property names, not arbitrary CSS values. Ordinary generated
126 text uses a non-empty `font-family`, a finite positive unitless-px `font-size`,
127 `font-weight` of `normal` / `bold` / an integer hundred from `100` through
128 `900`, `font-style` of `normal` / `italic`, and `text-anchor` of `start` /
129 `middle` / `end`. Inheritable text declarations belong only on `<svg>`, `<g>`,
130 `<text>`, or `<tspan>`; `text-anchor` is invalid on `<tspan>`. Load
131 [`svg-effects.md`](./svg-effects.md) §6.7 before authoring tracking,
132 underline/strike, text outline/alpha, gradient text, or text filter effects.
133 Unknown or unmapped declarations fail Checker preflight and native export.
134
135 > **`marker-start` / `marker-end` is conditional** — see §1.1.
136 >
137 > **`clipPath` on `<image>` is conditional** — see §1.2.
138 >
139 > **Static same-document `<use>` is conditional** — see §1.3.
140 >
141 > **Imported native-shape metadata is conditional** — see §1.4.
142 >
143 > **Authored native preset fragments are conditional** — see §1.5.
144 >
145 > **Inline CSS geometry, simple gradients, filters, and approximate group
146 > opacity are conditional** — see §2 and [`svg-effects.md`](./svg-effects.md).
147 >
148 > **PPT preset patterns and native chart/table/template metadata are
149 > conditional** — see [`native-data-interface.md`](./native-data-interface.md) and [`pptx-structure-interface.md`](./pptx-structure-interface.md).
150
151 DrawingML has no arbitrary per-pixel alpha-compositing path. Effects that rely
152 on one, including text-knockout image fills and arbitrary alpha composites,
153 must be baked into a raster asset before SVG export.
154
155 ---
156
157 ### 1.1 Line-end Markers (Conditional Contract)
158
159 `marker-start` and `marker-end` are supported on `<line>` and `<path>` only
160 when the referenced marker fits this native-arrow contract:
161
162 | Concern | Required form |
163 |---|---|
164 | Reference | Exact local `url(#id)` to a `<marker>` in `<defs>` |
165 | Orientation | `orient="auto"` or `orient="auto-start-reverse"`; the latter reverses `marker-start` while behaving like `auto` at `marker-end` |
166 | Shape | One direct shape representing a DrawingML `triangle`, `stealth`, `arrow`, `diamond`, or `oval` line end: a 3-vertex `<polygon>` / closed path (triangle), a simple concave 4-vertex `<polygon>` / closed path (stealth), an open 3-vertex path (arrow), a simple convex 4-vertex `<polygon>` / closed path (diamond), or one `<circle>` / `<ellipse>` (oval) |
167 | Path grammar | Use one explicit `M`/`L` command per vertex. Triangle, stealth, and diamond paths end in `Z`; arrow paths remain open after the third vertex. Do not use `H`, `V`, curves, or an implicit multi-point `L` command inside a marker path |
168 | Color parity | Triangle, stealth, diamond, and oval use a fill matching the parent line stroke. The open arrow uses `fill="none"` and a stroke matching the parent line stroke. DrawingML line ends inherit the line color |
169
170 The converter maps these five shapes to their corresponding DrawingML line-end
171 types. Prefer `<polygon>` for the closed triangle, stealth, and diamond forms;
172 the open arrow form requires `<path>`. Four-vertex shapes must be simple and
173 non-degenerate: convex geometry maps to diamond and concave geometry maps to
174 stealth. Checker and exporter preflight consume this same contract; other
175 marker shapes have no native mapping and block export instead of being silently
176 dropped.
177
178 PPTX import compatibility, tolerant recovery, strict-mode rejection, and
179 diagnostic behavior are indexed in
180 [`conversion.md`](../scripts/docs/conversion.md#import-compatibility-and-recovery-boundary).
181
182 ---
183
184 ### 1.2 Image Clipping (Conditional Contract)
185
186 `clip-path` maps natively only on SVG `<image>` (including an exact crop
187 wrapper's inner image) under this contract. Legacy imported crops may retain
188 an outer-wrapper clip as compatible input:
189
190 | Concern | Required form |
191 |---|---|
192 | SVG-namespace `<clipPath>` defined inside `<defs>` | Converter looks up one exact local id; missing, duplicate, foreign-namespace, or malformed references fail |
193 | Contains exactly one direct SVG-namespace supported shape child | Multiple shapes are not composited |
194 | Shape is one of: `<circle>`, `<ellipse>`, `<rect>` (optional rx/ry), `<path>`, `<polygon>` | These map to DrawingML geometry (preset or custom) |
195 | No `clip-rule` or `fill-rule`, whether direct or in inline `style` | DrawingML picture geometry has no equivalent winding-rule control |
196 | Used only on `<image>` or a compatible legacy imported crop wrapper | Shapes, groups, text, and generalized nested SVG targets are **forbidden** |
197
198 | SVG clip shape | DrawingML output |
199 |---|---|
200 | `<circle>` / `<ellipse>` | Full-frame `<a:prstGeom prst="ellipse"/>`; the child must exactly cover the image frame. A `userSpaceOnUse` circle requires a square physical frame; a normalized `objectBoundingBox` circle may fill any frame |
201 | `<rect>` / `<rect rx="..."/>` | A plain full-frame rect is a compatible no-op; rounded form maps to full-frame `<a:prstGeom prst="roundRect"/>` with one physical radius adjustment. The rect must exactly cover the image frame and cannot express non-uniform physical corner radii |
202 | `<path>` / `<polygon>` | `<a:custGeom>` with coordinates mapped into the image frame |
203
204 `clip-path` on shapes, groups, or text is forbidden; author the target geometry
205 directly instead. Use a path/polygon clip when the intended contour does not
206 cover the full picture frame. A contour that depends on even-odd or another
207 explicit winding rule is outside this mapping and must be rebuilt as one
208 unambiguous visible contour or pre-rendered.
209
210 ---
211
212 ### 1.3 Static Same-Document `<use>` (Conditional Contract)
213
214 **Expansion contract**: Static local reuse is compile-time authoring shorthand. `finalize_svg.py` and
215 native export replace each qualifying instance with cloned primitive content;
216 PPTX-to-SVG import emits the resulting primitives and does **not** reconstruct
217 the original `<use>` / `<symbol>` structure.
218
219 | Concern | Required form |
220 |---|---|
221 | Reference syntax | Author new SVG with the SVG 2 form `href="#id"`. Legacy `xlink:href="#id"` remains read-compatible and Live Preview normalizes it to `href`; if both attributes exist, their values MUST match. |
222 | Referenced target | One of `<symbol>`, `<g>`, `<use>`, `<rect>`, `<circle>`, `<ellipse>`, `<line>`, `<path>`, `<polygon>`, `<polyline>`, `<text>`, or `<image>`. Nested local `<use>` is recursively expanded. |
223 | Instance position | Generated `<use x>` / `<use y>` use finite unitless values; an explicit `px` suffix is read-compatible. Omitted values default to `0`. |
224 | Symbol viewport | A referenced `<symbol>` MUST have a finite four-number `viewBox` with positive width/height. Its `<use>` MUST have positive finite unitless `width` and `height`; an explicit `px` suffix is read-compatible. |
225 | Aspect ratio | Default/aligned `meet` values and plain `preserveAspectRatio="none"` are supported. `slice`, `refX`, and `refY` are forbidden. |
226 | Viewport boundary | Symbol artwork MUST stay inside its `viewBox`; expansion does not reproduce symbol overflow clipping. |
227 | Internal references | Author exact `href="#id"` and `url(#id)` fragments. The expander also reads legacy `xlink:href="#id"` and rewrites all instance-local cloned IDs. |
228 | Structural metadata | Neither the `<use>` instance nor its referenced subtree may carry `data-pptx-layer*`, chart/table replacement metadata (`data-pptx-replace-with`, `data-pptx-replacement-*`, `data-pptx-import-source`, or `data-pptx-fallback-*`), or `data-pptx-placeholder*`. Author those objects directly instead of reusing them. |
229 | Safety limits | A reachable reference chain may contain at most 64 instances, and one SVG may expand at most 10,000 local `<use>` instances. |
230
231 **Forbidden — unsafe local references**:
232
233 - External/file/data URLs, missing targets, conflicting `href` / `xlink:href`,
234 unsupported target elements, and circular reference chains
235 - Duplicate IDs on the referenced target, the `<use>` instance, or anywhere in
236 the reused subtree
237 - Quoted/whitespace CSS fragment variants such as `url('#id')`; use exact
238 `url(#id)` when an internal paint/filter/clip reference must be rewritten
239
240 **Contract example**:
241
242 ```xml
243 <svg xmlns="http://www.w3.org/2000/svg">
244 <defs>
245 <symbol id="statusDot" viewBox="0 0 20 20" preserveAspectRatio="xMidYMid meet">
246 <circle cx="10" cy="10" r="8" fill="#16A34A"/>
247 </symbol>
248 <g id="legendRow">
249 <rect width="120" height="32" rx="8" fill="#F1F5F9"/>
250 <text x="42" y="22" font-size="16" fill="#0F172A">Ready</text>
251 </g>
252 </defs>
253 <use href="#statusDot" x="80" y="120" width="32" height="32"/>
254 <use href="#legendRow" x="120" y="120"/>
255 </svg>
256 ```
257
258 ---
259
260 ### 1.4 Imported Native PowerPoint Shapes (Conditional Contract)
261
262 `pptx_to_svg.py` emits rendering-neutral metadata when a visible SVG object
263 originates from `p:sp`, `p:cxnSp`, or `p:grpSp`. This contract is for lossless
264 import SVGs and unchanged imported objects that remain Slide-local or inside a
265 slot during mirror materialization. Ordinary authored SVG does not need these
266 attributes, and no separate source-payload opt-in marker exists.
267
268 | Metadata | Placement | Required behavior |
269 |---|---|---|
270 | `data-pptx-object` | Logical `<g>` and native carrier | `shape`, `connector`, `group`, or `picture`; never infer the object kind from path appearance. |
271 | `data-pptx-shape-id` + `data-pptx-shape-scope` | Logical `<g>` and carrier | Preserve the source part-scoped identity. Export remaps duplicate Master/Layout/Slide ids into page-unique ids before rebinding connector references. |
272 | `data-pptx-frame="x y width height"` | Logical `<g>` and carrier | Own native `a:xfrm` position and size. Lossless import SVGs and tool-side native records use sufficient precision for exact EMU recovery; the model-facing authoring IR may use the compact page-coordinate spelling defined below. Path bounds, stroke, markers, shadows, and text glyph bounds never replace this frame. |
273 | `data-pptx-prst` | Preset carrier and logical `<g>` | One of the locked 187 DrawingML `ST_ShapeType` values. |
274 | `data-pptx-av-*` | Preset carrier and logical `<g>` | Preserve the complete validated DrawingML adjustment formula, including non-`val` formulas. |
275 | `data-pptx-part="geometry"` | One hidden carrier path | The single native export authority for frame, base fill/line/effect, preset/custom geometry, and object identity. |
276 | `data-pptx-part="geometry-preview"` / `geometry-detail` | Visible preview group/paths | Render the preset's independent path fill/stroke layers. A hash-locked preview group may mirror the carrier's one filter so a multi-path preset renders one aggregate imported effect; these elements are never emitted as duplicate PowerPoint shapes. |
277 | `data-pptx-preview-sha256` | Logical preset `<g>` and carrier | Detect edits to visible preset paths or paint. A stale preview fails quality check/export instead of silently reusing old native metadata. |
278 | `data-pptx-geometry-kind="custom"` + `data-pptx-custgeom` or `data-pptx-custgeom-ref` | Custom-geometry carrier | Preserve the validated original `a:custGeom` subtree. If the visible path hash is unchanged, export writes formulas, handles, connection sites, text rectangle, and path list exactly; edited paths compile from current SVG geometry. |
279 | `data-pptx-start/end-shape-id/site` | Connector logical `<g>` and carrier | Restore `a:stCxn` / `a:endCxn` after scoped shape-id allocation. A connector may retain one zero frame axis; it must not be expanded from visible stroke or marker bounds. |
280 | `data-pptx-shape-style` or `data-pptx-shape-style-ref` | Native carrier | Preserve a relationship-free `p:style` independently of text, including shapes with no visible text. |
281 | `data-pptx-effect-status="unsupported"` + `data-pptx-effect-reason` | Imported `p:sp` / `p:cxnSp` logical object and native carrier; imported `p:pic` carrier and logical object; imported `p:grpSp` logical group; imported table `p:graphicFrame` logical group | Record why an encountered source object or text-run `effectLst` / `effectDag` cannot enter the registered target-specific effect mapping without changing semantics. Checker and export stop with the recorded reason; these attributes are diagnostics, not a preserved effect payload or authoring syntax. |
282 | `metadata[data-pptx-part="txbody"]` with inline Base64 or `data-pptx-ref` | Logical shape `<g>` | Preserve unchanged `p:txBody`, including an empty text body. Content, whitespace, positioning, visible typography, or incompatible child-topology edits invalidate the payload. A source payload with run-level effects then blocks checker/export instead of losing those effects; an effect-free payload uses the normal SVG text fallback. |
283
284 **Hard rule — compact native metadata transport**: Type A mirror
285 materialization moves `p:txBody`, relationship-free `p:style`, and
286 `a:custGeom` payloads into the content-addressed
287 `templates/native_payloads.json.gz` store. It also deduplicates repeated native
288 restoration fields—object identity, frame, preset/custom-geometry guards,
289 preview/text hashes, connector endpoints, payload references, and adjustment
290 formulas—into short `data-pptx-native-ref` records in the same store. Checker,
291 template-structure validation, and export validate and hydrate both layers in
292 memory. Keep Master/Layout, placeholder, layer, editable-object, diagnostic,
293 and editable chart/table metadata inline. Legacy inline Base64 and v1
294 payload-only stores remain readable.
295
296 One effect reason remains its existing plain token. If one imported object has
297 multiple independent unsupported reasons, both marker copies store the same
298 deduplicated, lexicographically sorted compact JSON string array in
299 `data-pptx-effect-reason`; adding a later reason must not overwrite an earlier
300 one. This array is still diagnostic metadata, not an authoring surface.
301
302 **Import/authoring representation split**:
303
304 | Representation | Contract |
305 |---|---|
306 | Lossless import SVG | Keep complete native payload, hidden carriers, and preview evidence in the temporary analysis workspace. It is immutable native-payload backing, not the editable template source. |
307 | Authoring IR bundle | Keep editable SVGs plus model-readable `authoring_summary.json` and tool-only `authoring_manifest.json`. Exclude opaque payload and duplicate hidden carriers from model context while retaining visible shape intent and a stable document-local `data-pptx-source-ref` on each imported logical object. Compact model-facing imported frames and safe transform page coordinates to at most two decimals before hashing the IR. The summary owns the compact current-file index; the manifest owns source paths and initial hashes and never enters model context. |
308 | `standard` / `fidelity` output | Use the compact authored-preset contract (§1.5) for newly authored stock shapes; do not transplant opaque import payload or source topology. |
309 | `mirror` output | Materialize from the edited authoring IR. Rehydrate supported imported metadata only when a Slide-local/slot object's source ref and initial authoring hash still match; otherwise keep the current SVG fallback. Expand fixed Master/Layout group wrappers into direct semantic atoms while preserving source ownership, paint order, and visible appearance. |
310
311 **Hard rule — model-facing page-coordinate precision**:
312
313 | Surface | Precision contract |
314 |---|---|
315 | Imported `data-pptx-frame` in authoring IR | At most two decimals. An unchanged mirror source ref recovers the exact lossless frame before tool-side native-record externalization. |
316 | `data-pptx-bounds` in generated and final template SVG | At most two decimals. |
317 | `translate(...)`, `rotate(... cx cy)`, and `matrix(... e f)` | Translation values and rotation centers use at most two decimals. Keep the rotation angle and matrix `a b c d` coefficients unchanged. |
318 | Protected values | Do not apply this compaction to path/points geometry, normalized crop or nested `viewBox` ratios, gradient offsets, opacity, scale arguments, canonical authored-preset frames, or lossless/tool-side native frames. |
319
320 **Hard rule — authoring source refs**: `data-pptx-source-ref` is reserved for
321 the create-template authoring IR. Its value is unique within one authoring SVG,
322 not across the workspace, and must be resolved through that document's
323 `authoring_manifest.json` record by the owning tool. Models MUST NOT read that
324 machine manifest. Moving a referenced subtree into
325 `icons/imported/` for readability must preserve the attribute and record it in
326 the vector inventory; re-inlining re-establishes the same mapping. Final materialized
327 template SVGs and normal project `svg_output/` must not contain this attribute.
328
329 **Hard rule — structural-layer boundary**: An unchanged imported logical object
330 may keep currently supported metadata while it remains Slide-local or inside a
331 slot. An imported logical `<g>` cannot be assigned to Master/Layout because
332 those layers require direct semantic atoms. Mechanically expand a fixed-layer
333 source group into direct atoms, rebuilding a preset when supported and
334 otherwise retaining the visible SVG fallback. A newly authored compact preset
335 `<g>` from §1.5 is the sole group exception: validation proves that it compiles
336 to exactly one native shape/connector. Do not use this normalization to change
337 ownership or appearance.
338
339 **Hard rule — selective payload**: Do not copy every imported metadata block into
340 an authored template. Keep the full lossless import SVG separately as immutable
341 audit/fallback backing. Mirror may reuse only metadata already supported by the
342 converter on source-ref/hash-matching Slide-local/slot objects; unsupported or
343 edited objects use the current SVG fallback. `data-pptx-replace-with` remains reserved for the
344 optional PowerPoint-native Chart/Table replacement contract.
345
346 **Registry and rendering rules**:
347
348 - The hash-locked shared registry must equal the independent 187-value shape
349 catalog. Missing, duplicate, unknown, or corrupt definitions fail closed.
350 - Preset preview paths come from the shared DrawingML formula evaluator; do not
351 add per-shape Python geometry handlers.
352 - Preset size is controlled only by `data-pptx-frame` / `a:xfrm`. Adjustment
353 formulas control the contour inside that frame and are not rescaled when the
354 frame changes.
355 - A group transform may move, scale, rotate, or flip the complete logical
356 shape without invalidating its preview fingerprint. Editing a generated
357 `geometry-detail` path directly is unsupported unless the carrier metadata
358 and preview fingerprint are regenerated together.
359 - Unknown or malformed SVG transform operations fail closed. DrawingML cannot
360 represent arbitrary shear, so a non-orthogonal transform must stop native
361 export instead of being silently approximated as rotation and scale.
362 - Opaque XML payloads containing any `r:*` relationship attribute are never
363 copied into a new slide part. Relationship-bearing text content and
364 shape-level `a:blipFill` use the existing rebuilt visual fallback and are
365 not covered by atomic `p:sp + p:txBody` rehydration.
366 - Unknown future presets and explicit `unsupported` geometry status never
367 downgrade silently to `rect`; native export stops with the recorded reason.
368
369 **Fidelity boundary**: native preset/custom geometry, logical frame, scoped
370 identity, connector topology, and relationship-free unchanged horizontal
371 text-body semantics on ordinary shape fills are `Native-stable`. The SVG
372 preview paint for gradient/pattern
373 `darken`/`lighten` layers is `Native-normalized`; original group child
374 coordinates, shape-level image-fill reconstruction, and vertical-text
375 reconstruction are also normalized rather than byte-identical OOXML.
376
377 ---
378
379 ### 1.5 Authored Native PowerPoint Presets (Conditional Contract)
380
381 New SVG pages and project-owned canonical reusable templates may opt one
382 complete geometric object into a native DrawingML preset through the
383 deterministic fragment helper. Selection behavior lives in
384 [`native-shape-authoring.md`](./native-shape-authoring.md); this section owns
385 the machine contract. This compact canonical form describes the intended
386 preset, frame, adjustments, and paint once, keeps only registry-generated
387 visible SVG paths, and embeds no source OOXML or serialized preview fingerprint.
388
389 | Metadata / structure | Required behavior |
390 |---|---|
391 | `data-pptx-authoring="preset"` | Appears once on the logical `<g>`; distinguishes strict project authoring from legacy/imported metadata. |
392 | `data-pptx-object` | `shape` or `connector`; connector-family presets must use `connector`, and `connector` must use a connector-family preset. Authored connectors require `fill="none"` plus a visible stroke and export as unconnected `p:cxnSp`. |
393 | `data-pptx-prst`, `data-pptx-frame`, `data-pptx-av-*` | Generated together from the locked registry and written once on the logical group. The frame is the helper's exact four-part, space-separated ordinary-decimal spelling and remains authoritative even when visible path bounds differ; commas, scientific notation, leading `+`, and redundant decimal spellings are rejected. |
394 | Local `fill` / `stroke` plus supported paint attributes | Base paint is written once on the group; a visible stroke also carries an explicit width. Canonical page/template authoring keeps channel paint local. Compatible ancestor paint/opacity may compose under the general SVG rules and receives a recommendation warning. |
395 | Ordered direct `<path>` children | Browser-visible registry layers only. Each child writes just its required path-level fill/stroke override; labels and decorations stay outside the atomic group. |
396 | No carrier / wrapper / fingerprint | `data-pptx-part`, hidden geometry carriers, preview wrappers, and `data-pptx-preview-sha256` belong to expanded import/compatibility transport, not canonical project authoring. |
397
398 Generate one fragment at a time:
399
400 ```bash
401 python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render rightArrow \
402 --id p03-growth-arrow \
403 --frame 160 210 320 112 \
404 --fill "#2563EB" \
405 --stroke none \
406 --adjust "adj1=val 50000"
407 ```
408
409 **Hard rule — helper-only metadata**: never add or edit authored preset
410 metadata or registry paths by hand. The compact helper output is atomic.
411 Regenerate it when preset, frame, adjustment, fill, stroke, or stroke width
412 changes. Replace the whole fragment with ordinary SVG when free contour editing
413 is required.
414
415 Template ownership metadata is orthogonal to preset geometry. After inserting
416 the complete helper output, `create-template` may add only the registered
417 `data-pptx-layer`, `data-pptx-editable`, `data-pptx-carrier`, or
418 `data-pptx-role` attribute needed by the surrounding structured contract. It
419 must not change preset/frame/adjustment/paint metadata or any direct path.
420
421 **Reusable-template boundary**: a project-owned canonical template may retain
422 one complete helper-generated atomic fragment when the stock preset is an exact
423 semantic match and its paint stays inside the authoring boundary below. The
424 fragment is an executable exemplar and one semantic atom, not a freely editable
425 template primitive. It may be Slide-local, the one carrier of an `object` slot,
426 or a direct Master/Layout fixed atom. An adaptation may reuse it unchanged only
427 when preset, frame, adjustments, and paint are unchanged; otherwise regenerate
428 the whole fragment with the helper.
429 Imported, mirror, and third-party templates are never upgraded by contour
430 inference.
431
432 **Hard rule — visible page closure**: the helper prints a complete visible
433 fragment to stdout; export never invents its preview. The main Agent inserts
434 that output into the hand-authored page or canonical reusable template. The
435 helper cannot write a project, select layout, or generate a page.
436
437 **Authoring paint boundary**: v1 accepts `none` or six-digit solid HEX fill and
438 stroke, optional fill/stroke opacity, stroke width, line cap, and line join.
439 Normal generated pages use `spec_lock.md` for stable semantic color anchors and
440 choose page-local paint from the retained Design Spec, style, and composition context.
441 The lockless [`quick-generate`](../workflows/profiles/quick-generate.md) profile
442 keeps every chosen paint value explicit in the SVG.
443 `create-template` authored templates take their values from the confirmed brief
444 and template `design_spec.md`.
445 Use ordinary SVG for gradients, patterns, filters, or other treatments outside
446 this narrow contract. Registry-derived multi-path darken/lighten colors and
447 other contextual derivatives need no separate lock row unless they become a
448 recurring named role. Mirror preserves source paint under §1.4 instead.
449
450 **Validation**: quality check and export both rerender authored fragments from
451 `preset + frame + adjustments + group paint` and compare every visible path and
452 path-level paint override directly. Registry-path edits, geometry metadata that
453 leaves those paths stale, unknown adjustments, out-of-range frames/transforms,
454 zero-scale transforms, and shear/skew fail closed. Export expands the validated
455 compact group only in memory and reuses the lossless native-shape conversion
456 path. Older authored carrier/preview fragments remain compatible as ordinary
457 Slide-local input and
458 receive a non-blocking migration warning; they do not gain the new compact
459 group's structured-atom exception. `pptx_to_svg` expanded output remains the
460 lossless round-trip form and is not warned as authored input.
461
462 **Fidelity boundary**: an unchanged authored fragment is `Native-stable` as
463 one `p:sp` or `p:cxnSp`. Text remains outside the atomic fragment and may export
464 as a grouped editable text box. Authoring v1 creates only unconnected
465 `p:cxnSp`; it does not accept hand-written endpoint/site metadata. An
466 `actionButton*` preset maps visual geometry only. Preset appearance never
467 invents connector attachment, action behavior, navigation targets, or
468 hyperlinks.
469
470 ---
471
472 ## 2. Conditional Compatibility Mappings
473
474 ### 2.1 Literal Geometry Lengths and Inline Geometry
475
476 **Hard rule — direct geometry length grammar**: New generated SVG writes the
477 following XML geometry values and `stroke-width` as finite unitless ordinary
478 decimals in the page `viewBox` coordinate space, for example `x="120"` and
479 `stroke-width="2"`. The explicit `px` suffix is read-compatible and receives a
480 recommendation warning. No other unit is registered for this surface.
481
482 | Element / surface | Direct length attributes |
483 |---|---|
484 | `<svg>`, `<rect>`, `<image>`, `<use>` | `x`, `y`, `width`, `height`; `<rect>` also `rx`, `ry` |
485 | `<circle>` | `cx`, `cy`, `r` |
486 | `<ellipse>` | `cx`, `cy`, `rx`, `ry` |
487 | `<line>` | `x1`, `y1`, `x2`, `y2` |
488 | `<text>` / positional `<tspan>` | `x`, `y`; `<tspan>` also `dx`, `dy` |
489 | Any supported painted element | `stroke-width` |
490
491 `width`, `height`, `r`, `rx`, `ry`, and `stroke-width` must be non-negative;
492 the stricter positive `<use>` symbol-viewport rule remains in §1.3. `pt`,
493 `pc` / `pica`, `in`, `cm`, `mm`, `q`, `em`, `rem`, percentages, unknown units,
494 non-finite values, expressions, scientific notation, leading plus signs, and
495 trailing decimal points are invalid here even when generic SVG/CSS defines
496 them. A missing attribute may use its documented SVG/project default; an
497 explicitly supplied invalid value never falls back to that default.
498
499 The following geometry properties may appear in the same element's
500 `style="..."`. The pipeline materializes them as
501 XML geometry attributes before SVG post-processing and native PPTX conversion.
502 An inline geometry declaration overrides an existing same-name XML attribute.
503
504 | Element | Recognized properties |
505 |---|---|
506 | `<rect>` | `x`, `y`, `width`, `height`, `rx`, `ry` |
507 | `<circle>` | `cx`, `cy`, `r` |
508 | `<ellipse>` | `cx`, `cy`, `rx`, `ry` |
509 | `<image>` | `x`, `y`, `width`, `height` |
510 | `<svg>` | `x`, `y`, `width`, `height` |
511 | `<use>` | `x`, `y`, `width`, `height` |
512
513 **Hard rule — inline geometry grammar**: every non-zero value is one finite
514 `px` literal, such as `120px` or `-8.5px`; exact zero may be unitless. `width`,
515 `height`, `rx`, `ry`, and `r` must be non-negative. Percentages, `auto`,
516 `calc()`, `var()`, `!important`, `inherit`, and every other unit are forbidden.
517 Do not put geometry on an unsupported element: line endpoints, text positions,
518 path data, and polygon/polyline points remain XML attributes.
519
520 **Forbidden — CSS geometry cascade**: `<style>`, `class`, selector rules,
521 external stylesheets, and imported styles remain forbidden. This contract is
522 only for literal declarations in an element's own `style` attribute; PPT Master
523 does not compute CSS cascade or custom properties. Root canvas authority remains
524 the `viewBox`, regardless of root `<svg>` compatibility width/height values.
525
526 ### 2.2 Group Opacity Compatibility
527
528 **Default — descendant alpha (may preserve compatible group opacity)**: New
529 `svg_output/` and reusable templates put alpha on the affected descendant
530 paint, text run, picture, or supported effect. DrawingML has no isolated
531 group-alpha model, so overlapping descendants can look different when one
532 group value is distributed across them.
533
534 The converter nevertheless accepts `<g opacity="...">` and inline group
535 `opacity` by multiplying group alpha into descendants. That path is
536 `Approximate`; nested group/child alpha multiplies, and `--native-charts-and-tables`
537 rejects transparent native table/chart markers. The quality checker reports a
538 non-blocking fidelity warning so existing or intentionally authored input can
539 continue without modification.
540
541 ---
542
543 ## 3. Canvas Format Quick Reference
544
545 Use the already locked canvas id and exact viewBox. [`canvas-formats.md`](canvas-formats.md) owns format selection; this core owns only SVG conformance on that canvas. The lockless [`quick-generate`](../workflows/profiles/quick-generate.md) profile uses its first SVG to establish the canvas; every remaining page must use the identical viewBox.
546
547 ---
548
549 ## 4. Required Page Contract and Conditional Packaging
550
551 ### 4.0 Complete Page-Design Contract
552
553 | Concern | Requirement |
554 |---|---|
555 | Visible slide result | The completed `svg_output/<slide>.svg` MUST contain every visible text, image, shape, diagram, chart/table fallback, background, and template-derived layout element intended for that slide. External visual assets are valid when the SVG references them explicitly. |
556 | Template/control inputs | Templates, `design_spec.md`, and `spec_lock.md` guide authoring. Do not depend on them to add visible elements after the page SVG is complete. |
557 | PPTX translation | The exporter may map represented SVG content to DrawingML/native objects and deduplicate represented elements into Master/Layout/Slide parts. It MUST NOT invent visible slide content absent from the SVG. |
558 | Excluded package behavior | Speaker notes, animations, transitions, narration audio, PPTX relationships, and direct native-PPTX workflows remain separately owned. They are not part of the SVG page-design contract. |
559
560 **Hard rule — page-design closure**: A final page SVG is the sole visual/design authority for that page on every SVG-authoring route. SVG is not the authority for the entire PPTX package.
561
562 ### 4.1 Semantic SVG Marker Contract
563
564 Semantic markers are minimal compiler hints. Flat pages declare one root `data-pptx-page-role` and omit Master/Layout/layer/placeholder markers. Structured pages carry their final root identity, layer atoms, slots, and native-object metadata from authoring start and omit `data-pptx-page-role`. Use `data-pptx-role` with a stable `id` only when no specialized marker expresses page-frame behavior. Keep ordinary visible content in SVG attributes/text; [`semantic-svg.md`](semantic-svg.md) owns the vocabulary.
565
566 - **Canvas authority**: New authoring writes `viewBox="0 0 W H"` with positive
567 integer pixels from the lock, or from the first SVG when the explicit
568 `quick-generate` profile is active. Numerically equivalent spellings and positive
569 fractional imported dimensions remain compatible; export quantizes once at
570 `1 SVG px = 9,525 EMU`. Invalid/non-finite values, non-zero origin,
571 non-positive size, or unsupported PowerPoint dimensions are errors. All pages
572 and Layout prototypes in one normal build share the numeric canvas and match
573 `spec_lock.md canvas.viewBox`; quick-generate pages match the first SVG;
574 standalone templates match `design_spec.md canvas_viewbox`. Optional root
575 `width`/`height` do not override `viewBox`.
576 Root `<svg>` transform is forbidden; nested crop and `<symbol viewBox>` keep
577 their own contracts.
578 - **Font portability**: font families used by the deck must resolve to installed
579 export faces. `@font-face` remains forbidden; the typography contract lives in
580 [`strategist.md §g`](strategist.md).
581 - **Icon placeholders**: `<use data-icon="library/name">` is a pipeline-specific
582 form, distinct from local SVG reuse. Follow the contract in
583 [`../templates/icons/README.md`](../templates/icons/README.md).
584 - **Local reuse**: ordinary same-document `<use>` follows §1.3.
585
586 ### 4.2 Editability, Package Promotion, and Text Leading
587
588 These forms are needed only when the stated PPT behavior matters:
589
590 | Desired behavior | Required form |
591 |---|---|
592 | One editable PPT text frame with mixed formatting or multiline prose | Use one `<text>` per logical paragraph and non-positional `<tspan>` children for inline runs. Keep the first authored line as direct text; later lines use direct positioned `<tspan>` children that repeat parent `x` with positive relative `dy`; an all-`<tspan>` form may start at `dy="0"`. Default retains these breaks without PowerPoint wrapping; `--reflow-text` may join eligible lines. A font-size change, list marker, or larger accepted gap starts another paragraph. Sibling `<text>` elements are forbidden as one paragraph's line breaks; they remain valid for independent frames. |
593 | Stable object grouping or object-level animation anchor | Wrap the intended object in `<g id="...">`. Content grouping is **mandatory** per §4.3 — a top-level `<g id>` is also the animation anchor; it is not an optional convenience. |
594 | Native PowerPoint background promotion | Outside structured mode, the first eligible visual layer may be a direct full-canvas `<rect>` or one inside a simple single-child group. Its fill must have a registered native mapping (solid, linear/radial gradient, or preset pattern), and it must have no transform, filter, clip, rounding, or visible stroke. Export writes the fill as Slide `p:bg`; image elements remain pictures. Structured routes use the narrower explicit solid-background ownership contract in [`pptx-structure-interface.md`](./pptx-structure-interface.md). |
595 | Free-design / brand-only PowerPoint structure | Use `pptx_structure.mode: flat`. Keep every represented object Slide-local; export materializes one clean project-owned Master plus one Blank Layout from the current lock, removes stock content placeholders/Layout inventory, and retains only the standard date/footer/slide-number capability hooks. Do not author Master/Layout identities, layers, or placeholder slots. Quick-generate uses the same flat object ownership but converter-default theme scaffolding because no lock exists. |
596 | Reusable template-based PowerPoint Layout | Select one complete authoring SVG per page in `page_layouts`, declare each unique Master/Layout definition once, and assign pages through `page_pptx_layouts`. Strict preserves the prototype contract; adaptive retains its Master and uses a current or new Layout key already declared and assigned by Strategist. Construction cannot extend or mutate that mapping downstream. Non-mirror skin follows `spec_lock`. |
597
598 **Default — leading by role and density (may be overridden for user, template, typeface, legibility, or locked visual-style fit)**: For direct positioned `<tspan>` rows, start multiline titles around `1.2–1.3 × font-size`, dense / small body around `1.4–1.5 ×`, ordinary body around `1.5–1.6 ×`, and large / sparse / breathing body around `1.6–2.0 ×`. These are starting ranges, not checker quotas; display headlines may be tighter when the selected style calls for it. Author the spacing as positive relative `dy`, not CSS/SVG `line-height`, which has no registered DrawingML mapping.
599
600 **Hard rule — supported shape conversion**: Every PPT editability claim in this specification refers to the project converter reading `svg_output/` and emitting native DrawingML. `svg_final/` is a self-contained visual preview that may be inserted into PowerPoint as an SVG picture. PowerPoint's manual Convert-to-Shape operation is unsupported; do not narrow the authoring contract to its undocumented SVG subset.
601
602 ### 4.3 Element Grouping (Mandatory)
603
604 **Hard rule — root groups protect body-text layout**: Every visible direct root `<g>` declares positive root-coordinate `data-pptx-bounds="x y width height"`. Keep it when frame/native coordinates size one PowerPoint object; placeholder bounds also supply the slot frame. On flat pages, make each module zone as generous as the canvas and sibling layout allow without overlapping another module zone. Checker validates this subcanvas against the root `viewBox`, then recursively validates only estimable `<text>` descendants against it using the shared SVG-to-PPTX per-run width estimate and DrawingML wrapping headroom. It validates every estimable visible text carrier directly against the root `viewBox` with the same per-run estimate before that headroom. Nested groups and all shapes, images, paths, `<use>` instances, effects, and object frames are not module-boundary inputs. Per side, Checker ignores overflow through `1px`; module-boundary overflow warns through `5%` and fails above `5%`, while any larger root-`viewBox` text overflow fails. Bounds do not clip or reflow; unestimable visible text receives an advisory warning. The only page-boundary exception is a wholly off-canvas direct-root Morph endpoint marked `data-pptx-morph-staging="true"`; its own module bounds still apply, retained Morph uses an explicit pair, and the marker never excuses partial page overflow.
605
606 Wrap each logical Slide-local body unit in one descriptive top-level `<g id>`; group count follows the page's semantic units, and each group becomes one stable animation target when animation is enabled. Generic deck-wide animation gives that target one step; an explicit animation sidecar may assign it several ordered effects. Nested implementation groups may remain anonymous and need no bounds; any nested bounds are ignored. Flat pages use ordinary groups; structured slots already qualify, while titles, direct atomic Master/Layout elements, and canvas-level static framing—including background images and full-canvas scrim/decoration rectangles—may remain root primitives. On flat pages, give such static framing a stable `id` plus `data-pptx-role="background"` / `"decoration"`; never add a `<g>` solely to silence an ungrouped-element advisory.
607
608 **Reference — not a constraint**: A top-level semantic group may contain
609 descriptive nested `<g>` edit groups when its internal elements form useful
610 subunits, such as icon + title, value + label, or repeated information rows.
611 Nested groups carry no `data-pptx-bounds` and create no automatic animation
612 step; an unnecessary one-child wrapper may flatten. Choose whether and how
613 deeply to nest from the page's actual editing semantics—there is no default
614 nesting pattern, level, or quota.
615
616 **Structural atoms and slots are excluded automatically.** `data-pptx-layer` and `data-pptx-placeholder` semantics are read first; otherwise explicit `data-pptx-role` values (`background`, `decoration`, `header`, `footer`, `chrome`, `watermark`, `page-number`, `logo`) mark Slide-local static framing (§4.1, [`semantic-svg.md`](semantic-svg.md)). A normal slot group has exactly one direct compatible carrier; several drawing atoms require the explicit composite `object` proxy fallback. Native chart/table carrier groups retain their specialized [`native-data-interface.md`](./native-data-interface.md) contract.
617
618 **What to group** (one `<g id>` per unit):
619
620 | Grouping unit | Contains |
621 |---|---|
622 | Card / panel | Background rect + optional shadow (only if it floats over a photo/colored panel, [`svg-effects.md`](./svg-effects.md) §6.4) + icon + title + body text |
623 | Process step | Number/marker + icon + label + description |
624 | List item | Bullet / number + icon + title + description |
625 | Icon-text combo | Icon element + adjacent label |
626 | Page header | Title + subtitle + accent decoration |
627 | Page footer | Page number + branding |
628 | Decorative cluster | Related decorative shapes (rings, dots, orbs) |
629
630 An authored native preset fragment (§1.5) is already an atomic `<g id>` and
631 counts as one content group. Keep it top-level when it stands alone. When it
632 needs a label or decoration, place the preset and those siblings inside a
633 separate parent content group; never put them inside the preset group itself.
634
635 **Forbidden**:
636
637 - One giant `<g>` around the whole slide (collapses to a single animation step).
638 - Many ungrouped Slide-local `<rect>` / `<text>` / `<path>` atoms — they have no stable sidecar target and selection/editing degrades. Primitive fallback applies only when the root contains no top-level `<g>` at all; it is capped at 8 visible primitives.
639 - One top-level group per icon / text line / mark (too many animation steps).
640 - Anonymous top-level groups — every top-level semantic group needs a descriptive `id`.
641
642 **Naming — required.** A descriptive, page-unique `id` on every top-level content `<g>` (`card-1`, `step-discover`, `header`, `footer`) is mandatory; it is the stable SVG-side animation and trace anchor. An anonymous top-level group still converts, but `animations.json` cannot reference it; an anonymous one-child implementation wrapper may also flatten. Primitive fallback is unrelated and applies only to roots with no top-level groups.
643
644 ```xml
645 <g id="card-benefits-1" data-pptx-bounds="60 115 565 260">
646 <!-- Shadow only if the card floats over a colored panel; on flat white, omit it. -->
647 <rect x="60" y="115" width="565" height="260" rx="20" fill="#FFFFFF" filter="url(#shadow)"/>
648 <use data-icon="chunk-filled/bolt" x="108" y="163" width="44" height="44" fill="#0071E3"/>
649 <g id="card-benefits-metric">
650 <text x="105" y="270" font-size="56" font-weight="bold" fill="#0071E3">10×</text>
651 <text x="250" y="270" font-size="30" font-weight="bold" fill="#1D1D1F">Faster</text>
652 </g>
653 <text x="105" y="310" font-size="18" fill="#6E6E73">Reduce production time from days to hours.</text>
654 </g>
655 ```
656
657 ---
658
659 ## 5. Workflow Authority
660
661 The normal serial post-processing and export workflow belongs to
662 [`generate-pptx.md`](../workflows/generate-pptx.md) Step 7. The explicit
663 direct-generation exception belongs to
664 [`quick-generate.md`](../workflows/profiles/quick-generate.md). This file defines SVG
665 authoring boundaries and intentionally does not mirror commands, flags, or
666 output behavior.
667
668 ---
669
670
671 ## 8. Scope Boundary
672
673 Generate project structure, commands, quality-gate order, and export products
674 are owned by [`generate-pptx.md`](../workflows/generate-pptx.md) and its
675 selected profile. They are intentionally outside this SVG authoring policy.
676
676 lines MARKDOWN