@agent-native/core-corpus 0.214.0 → 0.217.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 (1217) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/actions/references/action-fields.md +1 -1
  3. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +61 -1
  4. package/corpus/templates/analytics/AGENTS.md +1 -1
  5. package/corpus/templates/analytics/CHANGELOG.md +2 -0
  6. package/corpus/templates/analytics/actions/get-session-replay-summary.ts +9 -65
  7. package/corpus/templates/analytics/actions/list-event-catalog.ts +1 -1
  8. package/corpus/templates/analytics/actions/list-session-outputs.ts +40 -0
  9. package/corpus/templates/analytics/actions/list-session-recordings.ts +17 -4
  10. package/corpus/templates/analytics/actions/view-screen.ts +29 -3
  11. package/corpus/templates/analytics/app/i18n/en-US.ts +27 -0
  12. package/corpus/templates/analytics/app/pages/sessions/EventCatalogPage.tsx +18 -1
  13. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +3 -1
  14. package/corpus/templates/analytics/app/pages/sessions/SessionOutputs.tsx +197 -0
  15. package/corpus/templates/analytics/app/pages/sessions/SessionsTriagePage.tsx +114 -4
  16. package/corpus/templates/analytics/changelog/2026-10-15-sessions-can-find-people-who-made-a-slides-deck-but-didn-t-p.md +6 -0
  17. package/corpus/templates/analytics/changelog/2026-10-16-the-activation-funnel-counts-visitors-who-decline-analytics-.md +6 -0
  18. package/corpus/templates/analytics/changelog/2026-10-21-session-replay-quotas-count-the-compressed-size-analytics-st.md +6 -0
  19. package/corpus/templates/analytics/server/db/schema.ts +67 -0
  20. package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +9 -0
  21. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +28 -22
  22. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +36 -1
  23. package/corpus/templates/analytics/server/lib/output-outcomes.ts +712 -0
  24. package/corpus/templates/analytics/server/lib/replay-origins.ts +33 -0
  25. package/corpus/templates/analytics/server/lib/session-event-index.ts +20 -0
  26. package/corpus/templates/analytics/server/lib/session-performance.ts +6 -40
  27. package/corpus/templates/analytics/server/lib/session-recording-associations.ts +30 -1
  28. package/corpus/templates/analytics/server/lib/session-replay-triage.ts +99 -0
  29. package/corpus/templates/analytics/server/lib/session-replay.ts +85 -40
  30. package/corpus/templates/analytics/server/lib/sessions-triage-lab.ts +8 -2
  31. package/corpus/templates/analytics/server/plugins/db.ts +46 -0
  32. package/corpus/templates/analytics/shared/output-use.ts +205 -0
  33. package/corpus/templates/analytics/shared/session-events.ts +6 -0
  34. package/corpus/templates/assets/.agents/skills/actions/references/action-fields.md +1 -1
  35. package/corpus/templates/brain/.agents/skills/actions/references/action-fields.md +1 -1
  36. package/corpus/templates/calendar/.agents/skills/actions/references/action-fields.md +1 -1
  37. package/corpus/templates/calendar/CHANGELOG.md +6 -0
  38. package/corpus/templates/calendar/actions/create-event.ts +2 -4
  39. package/corpus/templates/calendar/actions/update-event.ts +35 -6
  40. package/corpus/templates/calendar/changelog/2026-10-21-solo-events-avoid-notification-approval.md +6 -0
  41. package/corpus/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  42. package/corpus/templates/clips/.agents/skills/actions/references/action-fields.md +1 -1
  43. package/corpus/templates/community/qr/package.json +1 -1
  44. package/corpus/templates/content/.agents/skills/actions/references/action-fields.md +1 -1
  45. package/corpus/templates/content/.agents/skills/content-product-development/references/verification.md +36 -0
  46. package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +10 -0
  47. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +17 -3
  48. package/corpus/templates/content/.agents/skills/notion-integration/SKILL.md +4 -2
  49. package/corpus/templates/content/CHANGELOG.md +54 -0
  50. package/corpus/templates/content/acceptance/_writers.ts +604 -0
  51. package/corpus/templates/content/acceptance/generate-action-registry.ts +10 -0
  52. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/create-document.json +75 -0
  53. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/duplicate-page.json +75 -0
  54. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/edit-document-find-and-replace-without-a-revision.json +75 -0
  55. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/edit-document-find-and-replace.json +75 -0
  56. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/edit-document-initializecontent.json +75 -0
  57. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/import-content.json +75 -0
  58. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/local-files-import-content-source-existing-page.json +75 -0
  59. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/local-files-import-content-source-new-page.json +75 -0
  60. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/local-files-sync-local-folder-source-changed-file.json +75 -0
  61. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/local-files-sync-local-folder-source-new-file.json +75 -0
  62. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/restore-document-version.json +75 -0
  63. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/set-document-property-primary-blocks-field.json +75 -0
  64. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/set-image-alt-text.json +75 -0
  65. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/undo-content-import.json +75 -0
  66. package/corpus/templates/content/acceptance/golden/gate-off-stored-bytes/update-document-browser-full-rewrite.json +75 -0
  67. package/corpus/templates/content/acceptance/known-loss.ts +69 -0
  68. package/corpus/templates/content/acceptance/round-trip-corpus.ts +1397 -0
  69. package/corpus/templates/content/actions/_blocks-field-identity.ts +35 -1
  70. package/corpus/templates/content/actions/_browser-document-save-attempt.ts +23 -1
  71. package/corpus/templates/content/actions/_builder-cms-blob-custody.ts +467 -0
  72. package/corpus/templates/content/actions/_builder-cms-execution-lease.ts +17 -0
  73. package/corpus/templates/content/actions/_builder-cms-intent-lookup.ts +5 -0
  74. package/corpus/templates/content/actions/_builder-cms-read-client.ts +881 -21
  75. package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +28 -2
  76. package/corpus/templates/content/actions/_builder-cms-write-client.ts +109 -11
  77. package/corpus/templates/content/actions/_builder-docs-client.ts +1 -0
  78. package/corpus/templates/content/actions/_builder-private-blob.test-fixture.ts +90 -0
  79. package/corpus/templates/content/actions/_builder-source-execution-guard.ts +48 -0
  80. package/corpus/templates/content/actions/_content-database-lifecycle.ts +11 -11
  81. package/corpus/templates/content/actions/_content-database-personal-view.ts +2 -0
  82. package/corpus/templates/content/actions/_content-favorites.ts +37 -0
  83. package/corpus/templates/content/actions/_content-save-outcomes.ts +5 -0
  84. package/corpus/templates/content/actions/_database-membership-lock.ts +39 -8
  85. package/corpus/templates/content/actions/_database-navigation.ts +19 -21
  86. package/corpus/templates/content/actions/_database-row-batch.ts +41 -18
  87. package/corpus/templates/content/actions/_database-row-mutation.ts +17 -28
  88. package/corpus/templates/content/actions/_database-source-utils.ts +308 -9
  89. package/corpus/templates/content/actions/_database-utils.ts +96 -7
  90. package/corpus/templates/content/actions/_database-view-setup.ts +37 -2
  91. package/corpus/templates/content/actions/_delete-content-space.ts +8 -1
  92. package/corpus/templates/content/actions/_document-edit-mutation.ts +33 -32
  93. package/corpus/templates/content/actions/_document-flush.ts +593 -171
  94. package/corpus/templates/content/actions/_document-save-locks.ts +54 -0
  95. package/corpus/templates/content/actions/_document-save-row.ts +133 -0
  96. package/corpus/templates/content/actions/_github-source-freshness.ts +30 -4
  97. package/corpus/templates/content/actions/_github-source.ts +18 -8
  98. package/corpus/templates/content/actions/_move-page-to-space.ts +189 -25
  99. package/corpus/templates/content/actions/_nfm-syntax.ts +2 -0
  100. package/corpus/templates/content/actions/_row-lock-order.ts +115 -0
  101. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +23 -6
  102. package/corpus/templates/content/actions/cancel-prepared-builder-source-update.ts +110 -26
  103. package/corpus/templates/content/actions/change-content-database-source-role.ts +51 -7
  104. package/corpus/templates/content/actions/create-content-database.ts +11 -0
  105. package/corpus/templates/content/actions/create-document.ts +13 -1
  106. package/corpus/templates/content/actions/delete-content-database.ts +17 -14
  107. package/corpus/templates/content/actions/delete-document-property.ts +5 -0
  108. package/corpus/templates/content/actions/delete-document.ts +311 -100
  109. package/corpus/templates/content/actions/disconnect-content-database-source.ts +68 -2
  110. package/corpus/templates/content/actions/disconnect-local-folder-source.ts +33 -2
  111. package/corpus/templates/content/actions/edit-document.ts +18 -5
  112. package/corpus/templates/content/actions/execute-builder-source-execution.ts +900 -140
  113. package/corpus/templates/content/actions/export-document.ts +3 -0
  114. package/corpus/templates/content/actions/get-blocks-field-word-count.ts +22 -5
  115. package/corpus/templates/content/actions/get-document.ts +2 -0
  116. package/corpus/templates/content/actions/import-content-source.ts +170 -54
  117. package/corpus/templates/content/actions/move-document.ts +191 -73
  118. package/corpus/templates/content/actions/permanently-delete-document.ts +6 -0
  119. package/corpus/templates/content/actions/prepare-builder-source-execution.ts +155 -13
  120. package/corpus/templates/content/actions/prepare-builder-source-review.ts +299 -73
  121. package/corpus/templates/content/actions/pull-document.ts +8 -2
  122. package/corpus/templates/content/actions/remove-database-items.ts +23 -4
  123. package/corpus/templates/content/actions/restore-content-database.ts +76 -55
  124. package/corpus/templates/content/actions/restore-document-version.ts +19 -35
  125. package/corpus/templates/content/actions/restore-document.ts +65 -53
  126. package/corpus/templates/content/actions/rollback-created-slash-document.ts +11 -16
  127. package/corpus/templates/content/actions/set-document-property.ts +15 -1
  128. package/corpus/templates/content/actions/set-live-body-switch.ts +45 -0
  129. package/corpus/templates/content/actions/share-local-file-document.ts +18 -14
  130. package/corpus/templates/content/actions/suggest-document-edit.ts +2 -3
  131. package/corpus/templates/content/actions/sync-local-folder-source.ts +35 -1
  132. package/corpus/templates/content/actions/undo-content-import.ts +16 -12
  133. package/corpus/templates/content/actions/update-content-database-view.ts +2 -0
  134. package/corpus/templates/content/actions/update-document.ts +158 -34
  135. package/corpus/templates/content/actions/validate-builder-source-execution.ts +135 -26
  136. package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +1 -6
  137. package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +49 -3
  138. package/corpus/templates/content/app/components/editor/ContentImportDialog.tsx +2 -0
  139. package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +53 -11
  140. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +608 -353
  141. package/corpus/templates/content/app/components/editor/StaticDocumentBody.tsx +765 -0
  142. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +233 -80
  143. package/corpus/templates/content/app/components/editor/blockFieldSaveController.ts +32 -3
  144. package/corpus/templates/content/app/components/editor/blockFieldSaveRegistry.ts +88 -23
  145. package/corpus/templates/content/app/components/editor/comment-anchors.ts +19 -0
  146. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +228 -71
  147. package/corpus/templates/content/app/components/editor/database/GitHubSourceStatusLine.tsx +27 -2
  148. package/corpus/templates/content/app/components/editor/database/ListItemLayout.tsx +32 -8
  149. package/corpus/templates/content/app/components/editor/database/ListItemRow.tsx +27 -2
  150. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +1 -0
  151. package/corpus/templates/content/app/components/editor/document-flush-participant.ts +253 -0
  152. package/corpus/templates/content/app/components/editor/editor-transaction-meta.ts +28 -0
  153. package/corpus/templates/content/app/components/editor/extensions/AudioBlock.tsx +2 -1
  154. package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +27 -6
  155. package/corpus/templates/content/app/components/editor/extensions/LocalMdxComponentNode.tsx +0 -1
  156. package/corpus/templates/content/app/components/editor/extensions/NotionExtensions.tsx +4 -4
  157. package/corpus/templates/content/app/components/editor/extensions/SuggestionHighlight.ts +24 -2
  158. package/corpus/templates/content/app/components/editor/extensions/VideoBlock.tsx +25 -6
  159. package/corpus/templates/content/app/components/editor/pending-document-persistence.ts +59 -1
  160. package/corpus/templates/content/app/components/editor/stored-body-images.ts +27 -0
  161. package/corpus/templates/content/app/components/editor/suggestions/presentation-rebase.ts +17 -0
  162. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +11 -4
  163. package/corpus/templates/content/app/components/trash/TrashBrowser.tsx +4 -1
  164. package/corpus/templates/content/app/global.css +21 -0
  165. package/corpus/templates/content/app/hooks/use-content-database.ts +40 -2
  166. package/corpus/templates/content/app/hooks/use-content-trash.ts +8 -0
  167. package/corpus/templates/content/app/hooks/use-documents.ts +14 -0
  168. package/corpus/templates/content/app/i18n-data.ts +1 -0
  169. package/corpus/templates/content/app/import-messages.ts +25 -0
  170. package/corpus/templates/content/app/trash-messages.ts +16 -0
  171. package/corpus/templates/content/changelog/2026-10-16-a-page-open-in-a-tab-that-shows-it-s-in-the-trash-reopens-wi.md +6 -0
  172. package/corpus/templates/content/changelog/2026-10-16-a-page-restored-from-trash-returns-to-its-place-in-its-colle.md +6 -0
  173. package/corpus/templates/content/changelog/2026-10-16-agent-written-markdown-keeps-nested-lists-indented-with-spac.md +6 -0
  174. package/corpus/templates/content/changelog/2026-10-16-opening-a-page-you-can-edit-no-longer-rebuilds-its-editor-on.md +6 -0
  175. package/corpus/templates/content/changelog/2026-10-16-pages-moved-or-imported-at-the-same-time-can-no-longer-end-u.md +6 -0
  176. package/corpus/templates/content/changelog/2026-10-16-re-importing-a-markdown-export-of-a-page-no-longer-reports-t.md +6 -0
  177. package/corpus/templates/content/changelog/2026-10-16-saving-a-page-or-restoring-one-of-its-versions-no-longer-fai.md +6 -0
  178. package/corpus/templates/content/changelog/2026-10-17-agents-reading-a-page-you-have-open-no-longer-wait-or-fail-w.md +6 -0
  179. package/corpus/templates/content/changelog/2026-10-17-builder-content-avoids-retrying-a-write-when-builder-accepte.md +6 -0
  180. package/corpus/templates/content/changelog/2026-10-18-link-a-new-collection-to-a-github-folder-from-its-sources.md +1 -1
  181. package/corpus/templates/content/changelog/2026-10-19-fresh-document-reads-require-confirmation-from-every-open-ed.md +6 -0
  182. package/corpus/templates/content/changelog/2026-10-20-builder-content-sync-keeps-read-and-write-status-accurate-wh.md +6 -0
  183. package/corpus/templates/content/changelog/2026-10-20-html-table-cells-preserve-a-trailing-backslash-when-opening-.md +6 -0
  184. package/corpus/templates/content/changelog/2026-10-20-preserve-empty-paragraph-colors-and-refuse-unsupported-inlin.md +6 -0
  185. package/corpus/templates/content/changelog/2026-10-20-the-advanced-filter-and-each-filter-group-inside-it-have-the.md +6 -0
  186. package/corpus/templates/content/changelog/2026-10-21-blocks-fields-keep-unconfirmed-saves-visible-and-agent-reads.md +6 -0
  187. package/corpus/templates/content/changelog/2026-10-21-list-rows-can-show-each-pages-first-lines.md +6 -0
  188. package/corpus/templates/content/changelog/2026-10-21-preserve-compact-table-row-groups-and-report-invalid-block-colors.md +6 -0
  189. package/corpus/templates/content/changelog/2026-10-21-suggested-edits-show-an-agent-s-whole-reason-open-a-group-to.md +6 -0
  190. package/corpus/templates/content/changelog/2026-10-21-suggestions-keep-refusing-unmatched-emphasis-in-stored-markd.md +6 -0
  191. package/corpus/templates/content/changelog/2026-10-22-a-collection-linked-to-a-big-github-folder-fills-faster-and-p.md +6 -0
  192. package/corpus/templates/content/changelog/2026-10-22-accept-remaining-and-reject-remaining-show-the-result-for-ev.md +6 -0
  193. package/corpus/templates/content/changelog/2026-10-22-accepting-a-group-of-suggested-edits-saves-faster-and-adds-o.md +6 -0
  194. package/corpus/templates/content/changelog/2026-10-22-agents-read-saved-page-text-after-failed-icon-change.md +6 -0
  195. package/corpus/templates/content/changelog/2026-10-22-changes-made-from-a-menu-or-popover-such-as-an-image-s-alt-t.md +6 -0
  196. package/corpus/templates/content/changelog/2026-10-22-text-an-agent-writes-inside-a-callout-column-or-synced-block.md +6 -0
  197. package/corpus/templates/content/docs/product/capabilities/content.source.adapters.md +29 -0
  198. package/corpus/templates/content/e2e/auth-files.ts +28 -0
  199. package/corpus/templates/content/e2e/convergence-summary.ts +84 -29
  200. package/corpus/templates/content/e2e/gate-arm.ts +15 -0
  201. package/corpus/templates/content/e2e/global-setup.ts +43 -75
  202. package/corpus/templates/content/e2e/global-teardown.ts +34 -0
  203. package/corpus/templates/content/e2e/helpers.ts +598 -92
  204. package/corpus/templates/content/e2e/live-body-gate.ts +188 -0
  205. package/corpus/templates/content/e2e/playwright.config.ts +12 -3
  206. package/corpus/templates/content/e2e/server-identity.ts +47 -0
  207. package/corpus/templates/content/e2e/stored-form/collab-blocks.ts +123 -0
  208. package/corpus/templates/content/package.json +1 -1
  209. package/corpus/templates/content/parity/matrix.md +42 -42
  210. package/corpus/templates/content/parity/matrix.ts +3 -1
  211. package/corpus/templates/content/scripts/_stored-form-census-kinds.ts +30 -2
  212. package/corpus/templates/content/scripts/historical-icon-apply.ts +9 -1
  213. package/corpus/templates/content/scripts/trace-startup.mjs +460 -133
  214. package/corpus/templates/content/server/db/exec.ts +58 -0
  215. package/corpus/templates/content/server/db/schema.ts +21 -0
  216. package/corpus/templates/content/server/lib/content-trash-purge.ts +222 -144
  217. package/corpus/templates/content/server/lib/document-metadata-updated-at.ts +43 -1
  218. package/corpus/templates/content/server/lib/document-revision.ts +23 -0
  219. package/corpus/templates/content/server/lib/live-body-writer.ts +311 -0
  220. package/corpus/templates/content/server/lib/notion-sync.ts +63 -29
  221. package/corpus/templates/content/server/lib/notion.ts +5 -5
  222. package/corpus/templates/content/server/lib/suggested-edits.ts +357 -230
  223. package/corpus/templates/content/server/live-copy/binding.ts +31 -0
  224. package/corpus/templates/content/server/live-copy/bounded-task.d.ts +6 -0
  225. package/corpus/templates/content/server/live-copy/exec-db.ts +1 -0
  226. package/corpus/templates/content/server/live-copy/holds.ts +59 -0
  227. package/corpus/templates/content/server/live-copy/persist.ts +656 -0
  228. package/corpus/templates/content/server/live-copy/switch.ts +136 -0
  229. package/corpus/templates/content/server/live-copy/task-names.ts +4 -0
  230. package/corpus/templates/content/server/live-copy/tasks.ts +183 -0
  231. package/corpus/templates/content/server/live-copy/write-cause.ts +85 -0
  232. package/corpus/templates/content/server/live-copy/write.ts +85 -0
  233. package/corpus/templates/content/server/plugins/builder-private-payload-cleanup.ts +22 -0
  234. package/corpus/templates/content/server/plugins/collab.ts +3 -0
  235. package/corpus/templates/content/server/plugins/db.ts +33 -0
  236. package/corpus/templates/content/server/routes/api/documents/[id]/move.patch.ts +50 -168
  237. package/corpus/templates/content/shared/api.ts +32 -1
  238. package/corpus/templates/content/shared/blocks-fields-manifest.ts +106 -0
  239. package/corpus/templates/content/shared/database-item-layout.ts +54 -22
  240. package/corpus/templates/content/shared/database-query.ts +192 -30
  241. package/corpus/templates/content/shared/document-export.ts +12 -14
  242. package/corpus/templates/content/shared/document-flush-protocol.ts +88 -0
  243. package/corpus/templates/content/shared/document-intent-merge.ts +16 -9
  244. package/corpus/templates/content/shared/editor-save-state.ts +97 -0
  245. package/corpus/templates/content/shared/feature-flags.ts +10 -0
  246. package/corpus/templates/content/shared/import/markdown.ts +91 -7
  247. package/corpus/templates/content/shared/import/types.ts +2 -0
  248. package/corpus/templates/content/shared/inline-math.ts +6 -4
  249. package/corpus/templates/content/shared/nfm-fidelity.ts +247 -0
  250. package/corpus/templates/content/shared/nfm.ts +1933 -340
  251. package/corpus/templates/content/shared/og-description.ts +258 -36
  252. package/corpus/templates/content/shared/suggestion-diff.ts +13 -0
  253. package/corpus/templates/content/shared/suggestion-formatting.ts +143 -20
  254. package/corpus/templates/content/shared/suggestion-text.ts +39 -0
  255. package/corpus/templates/content/vitest.config.ts +10 -0
  256. package/corpus/templates/crm/.agents/skills/actions/references/action-fields.md +1 -1
  257. package/corpus/templates/design/.agents/skills/actions/references/action-fields.md +1 -1
  258. package/corpus/templates/design/.agents/skills/design-templates/SKILL.md +5 -1
  259. package/corpus/templates/design/.agents/skills/native-effects/SKILL.md +9 -2
  260. package/corpus/templates/design/.generated/bridge/shader-fill-preview.generated.ts +3 -249
  261. package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +30 -92
  262. package/corpus/templates/design/AGENTS.md +1 -3
  263. package/corpus/templates/design/CHANGELOG.md +34 -0
  264. package/corpus/templates/design/CODE_NATIVE_DESIGN_STUDIO_IMPLEMENTATION_PLAN.md +1 -6
  265. package/corpus/templates/design/DESIGN-STUDIO-PLAN.md +5 -7
  266. package/corpus/templates/design/actions/_native-local-export-server.ts +44 -31
  267. package/corpus/templates/design/actions/_native-render-contexts.ts +76 -21
  268. package/corpus/templates/design/actions/claim-native-local-export.ts +5 -0
  269. package/corpus/templates/design/actions/finish-native-local-export.ts +13 -2
  270. package/corpus/templates/design/actions/get-getting-started.ts +53 -0
  271. package/corpus/templates/design/actions/get-native-shader-approvals.ts +35 -0
  272. package/corpus/templates/design/actions/get-shader.ts +134 -219
  273. package/corpus/templates/design/actions/list-design-extensions.ts +3 -58
  274. package/corpus/templates/design/actions/request-native-local-export.ts +32 -6
  275. package/corpus/templates/design/actions/run-design-extension-action.ts +0 -29
  276. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +141 -108
  277. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +0 -218
  278. package/corpus/templates/design/app/components/design/DesignThumbnail.tsx +59 -3
  279. package/corpus/templates/design/app/components/design/EditPanel.tsx +35 -47
  280. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +242 -62
  281. package/corpus/templates/design/app/components/design/NativePreviewErrorBoundary.tsx +53 -0
  282. package/corpus/templates/design/app/components/design/bridge/codegen.ts +18 -3
  283. package/corpus/templates/design/app/components/design/bridge/native-composition-clock.ts +5 -4
  284. package/corpus/templates/design/app/components/design/bridge/native-dom.ts +37 -0
  285. package/corpus/templates/design/app/components/design/bridge/native-intrinsic-image.ts +2 -1
  286. package/corpus/templates/design/app/components/design/bridge/native-mesh-grid.ts +90 -0
  287. package/corpus/templates/design/app/components/design/bridge/native-opaque-public-asset.ts +363 -0
  288. package/corpus/templates/design/app/components/design/bridge/native-opaque-worker-lease.ts +179 -0
  289. package/corpus/templates/design/app/components/design/bridge/native-preview-geometry.ts +132 -7
  290. package/corpus/templates/design/app/components/design/bridge/native-preview-policy.ts +4 -0
  291. package/corpus/templates/design/app/components/design/bridge/native-preview-viewport-transport.ts +378 -0
  292. package/corpus/templates/design/app/components/design/bridge/native-scene-body-transform.ts +62 -0
  293. package/corpus/templates/design/app/components/design/bridge/native-scene-presentation-element.ts +10 -0
  294. package/corpus/templates/design/app/components/design/bridge/native-shader-runtime.bridge.ts +778 -246
  295. package/corpus/templates/design/app/components/design/bridge/native-source-provider.ts +512 -320
  296. package/corpus/templates/design/app/components/design/bridge/native-stateful-resource.ts +2 -2
  297. package/corpus/templates/design/app/components/design/bridge/native-stateless-compute.ts +5 -2
  298. package/corpus/templates/design/app/components/design/bridge/native-svg-source.ts +11 -1
  299. package/corpus/templates/design/app/components/design/bridge/native-worker-broker.ts +6 -0
  300. package/corpus/templates/design/app/components/design/bridge/native-worker-entry.ts +761 -303
  301. package/corpus/templates/design/app/components/design/bridge/native-worker-fill.ts +16 -6
  302. package/corpus/templates/design/app/components/design/bridge/native-worker-gpu.ts +854 -91
  303. package/corpus/templates/design/app/components/design/bridge/native-worker-host.ts +15 -1
  304. package/corpus/templates/design/app/components/design/bridge/native-worker-input-assets.ts +200 -0
  305. package/corpus/templates/design/app/components/design/bridge/native-worker-protocol.ts +40 -1
  306. package/corpus/templates/design/app/components/design/bridge/native-worker-scene-host.ts +540 -161
  307. package/corpus/templates/design/app/components/design/bridge/native-worker-source-snapshot.ts +21 -0
  308. package/corpus/templates/design/app/components/design/bridge/shader-fill-preview.bridge.ts +5 -371
  309. package/corpus/templates/design/app/components/design/bridge/shader-runtime.bridge.ts +45 -150
  310. package/corpus/templates/design/app/components/design/design-canvas/interact-document.ts +5 -9
  311. package/corpus/templates/design/app/components/design/design-canvas/native-preview-surface.ts +150 -0
  312. package/corpus/templates/design/app/components/design/design-canvas/native-public-asset-preview.ts +409 -0
  313. package/corpus/templates/design/app/components/design/design-canvas/native-public-worker-preview.ts +1086 -0
  314. package/corpus/templates/design/app/components/design/design-canvas/private-replay-screenshot-preview.ts +2 -2
  315. package/corpus/templates/design/app/components/design/design-canvas/text-content-change-result.ts +46 -12
  316. package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +15 -26
  317. package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +74 -67
  318. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +7 -19
  319. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +39 -30
  320. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +4 -0
  321. package/corpus/templates/design/app/components/design/inspector/NativeShaderColorControls.tsx +3 -7
  322. package/corpus/templates/design/app/components/design/inspector/NativeShaderPaintControls.tsx +12 -5
  323. package/corpus/templates/design/app/components/design/inspector/NativeShaderPanel.tsx +705 -190
  324. package/corpus/templates/design/app/components/design/inspector/fill-field-reading.ts +1 -2
  325. package/corpus/templates/design/app/components/design/inspector/index.ts +0 -6
  326. package/corpus/templates/design/app/components/design/inspector/native-catalog-display.ts +26 -5
  327. package/corpus/templates/design/app/components/design/inspector/native-shader-catalog-fixture.ts +42 -0
  328. package/corpus/templates/design/app/components/design/inspector/native-shader-catalog-preview.ts +51 -33
  329. package/corpus/templates/design/app/components/design/inspector/native-shader-paint.ts +1 -0
  330. package/corpus/templates/design/app/components/design/inspector/native-shader-property-draft.ts +89 -23
  331. package/corpus/templates/design/app/components/design/inspector/saved-glsl-shader.tsx +243 -0
  332. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +54 -5
  333. package/corpus/templates/design/app/components/design/shader-source-coordination.ts +66 -0
  334. package/corpus/templates/design/app/components/design/use-native-shader-approvals.ts +36 -8
  335. package/corpus/templates/design/app/components/home/DesignHomeLibrary.tsx +15 -8
  336. package/corpus/templates/design/app/components/layout/GettingStarted.tsx +50 -0
  337. package/corpus/templates/design/app/components/layout/Sidebar.tsx +3 -0
  338. package/corpus/templates/design/app/components/templates/DesignTemplateGrid.tsx +163 -0
  339. package/corpus/templates/design/app/components/templates/DesignTemplateLibrary.tsx +65 -78
  340. package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +66 -5
  341. package/corpus/templates/design/app/global.css +6 -0
  342. package/corpus/templates/design/app/i18n/en-US.ts +95 -2
  343. package/corpus/templates/design/app/lib/canvas-load-outcome.ts +147 -0
  344. package/corpus/templates/design/app/lib/canvas-outcome-tracking.ts +531 -0
  345. package/corpus/templates/design/app/lib/canvas-style-kind.ts +50 -0
  346. package/corpus/templates/design/app/pages/Index.tsx +10 -3
  347. package/corpus/templates/design/app/pages/Present.tsx +36 -1
  348. package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +1 -1
  349. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +1 -1
  350. package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +88 -32
  351. package/corpus/templates/design/app/pages/design-editor/commands/cross-screen-element-drop.ts +1 -1
  352. package/corpus/templates/design/app/pages/design-editor/commands/layer-move-to-screen.ts +1 -1
  353. package/corpus/templates/design/app/pages/design-editor/commands/paste-selection.ts +1 -1
  354. package/corpus/templates/design/app/pages/design-editor/commands/paste-svg-layer.ts +1 -1
  355. package/corpus/templates/design/app/pages/design-editor/commands/prepare-content-history-replay.ts +1 -1
  356. package/corpus/templates/design/app/pages/design-editor/commands/redo.ts +1 -1
  357. package/corpus/templates/design/app/pages/design-editor/commands/render-png-blob.ts +84 -41
  358. package/corpus/templates/design/app/pages/design-editor/commands/save-file-content.ts +38 -3
  359. package/corpus/templates/design/app/pages/design-editor/commands/shader-source-edit.ts +1 -1
  360. package/corpus/templates/design/app/pages/design-editor/commands/undo.ts +1 -1
  361. package/corpus/templates/design/app/pages/design-editor/design-editor-view.tsx +0 -2
  362. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-content-and-components.ts +4 -33
  363. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-core.ts +9 -0
  364. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-export-and-handoff.ts +2 -2
  365. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-files-and-saving.ts +2 -0
  366. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-history.ts +0 -11
  367. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-layer-models.ts +2 -55
  368. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-screen-rendering.tsx +0 -3
  369. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-selection-and-styles.ts +0 -24
  370. package/corpus/templates/design/app/pages/design-editor/text-edit-utils.ts +0 -16
  371. package/corpus/templates/design/app/pages/design-editor/use-native-local-export-requests.ts +70 -11
  372. package/corpus/templates/design/app/pages/design-editor/view/single-screen-canvas.tsx +0 -2
  373. package/corpus/templates/design/changelog/2026-10-20-folded-mesh-adds-an-animated-sculpted-fill-with-editable-col.md +6 -0
  374. package/corpus/templates/design/changelog/2026-10-20-read-only-design-views-render-native-shader-previews-in-nest.md +6 -0
  375. package/corpus/templates/design/changelog/2026-10-20-selected-screens-with-shader-effects-can-be-exported-togethe.md +6 -0
  376. package/corpus/templates/design/changelog/2026-10-20-shader-previews-reuse-validated-scene-data-while-panning-inc.md +6 -0
  377. package/corpus/templates/design/changelog/2026-10-20-shader-previews-stay-aligned-while-you-zoom.md +6 -0
  378. package/corpus/templates/design/changelog/2026-10-20-signed-out-sessions-no-longer-watch-for-private-png-export-r.md +6 -0
  379. package/corpus/templates/design/changelog/2026-10-21-a-getting-started-checklist-at-the-bottom-of-the-sidebar-tra.md +6 -0
  380. package/corpus/templates/design/changelog/2026-10-21-effect-thumbnails-show-richer-previews.md +6 -0
  381. package/corpus/templates/design/changelog/2026-10-21-native-effects-render-across-previews.md +6 -0
  382. package/corpus/templates/design/changelog/2026-10-21-native-shader-previews-use-less-gpu-memory-when-many-mesh-ef.md +6 -0
  383. package/corpus/templates/design/changelog/2026-10-21-opening-design-no-longer-shows-png-export-errors-when-no-exp.md +6 -0
  384. package/corpus/templates/design/changelog/2026-10-21-pulsing-border-controls-grouped.md +6 -0
  385. package/corpus/templates/design/changelog/2026-10-21-pulsing-border-follows-element-outlines.md +6 -0
  386. package/corpus/templates/design/changelog/2026-10-21-remove-obsolete-shader-fills.md +6 -0
  387. package/corpus/templates/design/changelog/2026-10-21-shader-previews-recover-from-temporary-gpu-and-image-failure.md +6 -0
  388. package/corpus/templates/design/changelog/2026-10-21-templates-now-open-a-read-only-preview-from-the-card-and-the.md +6 -0
  389. package/corpus/templates/design/changelog/2026-10-22-collapsed-shader-layers-no-longer-interrupt-other-shaders-on.md +6 -0
  390. package/corpus/templates/design/changelog/2026-10-22-shader-fills-and-effects-render-correctly-on-canvas-elements.md +6 -0
  391. package/corpus/templates/design/changelog/2026-10-22-shader-fills-keep-rendering-when-other-screen-content-cannot.md +6 -0
  392. package/corpus/templates/design/package.json +0 -1
  393. package/corpus/templates/design/playwright.config.ts +1 -1
  394. package/corpus/templates/design/scripts/design-export-validation/export-baseline.json +24 -0
  395. package/corpus/templates/design/scripts/runtime-budget-zoom.ts +9 -21
  396. package/corpus/templates/design/scripts/runtime-budget.ts +10 -24
  397. package/corpus/templates/design/server/lib/getting-started.ts +267 -0
  398. package/corpus/templates/design/server/plugins/agent-chat.ts +0 -2
  399. package/corpus/templates/design/server/plugins/getting-started.ts +5 -0
  400. package/corpus/templates/design/shared/design-template-presets/analytics-dashboard.ts +127 -0
  401. package/corpus/templates/design/shared/design-template-presets/design-studio.ts +98 -0
  402. package/corpus/templates/design/shared/design-template-presets/messaging-app.ts +101 -0
  403. package/corpus/templates/design/shared/design-template-presets/project-tasks.ts +120 -0
  404. package/corpus/templates/design/shared/design-template-presets.ts +8 -0
  405. package/corpus/templates/design/shared/effect-graph.ts +46 -1
  406. package/corpus/templates/design/shared/generation-output-receipt.ts +0 -1
  407. package/corpus/templates/design/shared/native-effect-animation-capability.ts +6 -0
  408. package/corpus/templates/design/shared/native-effect-folded-mesh-v1.ts +268 -0
  409. package/corpus/templates/design/shared/native-effect-folded-mesh-v2.ts +310 -0
  410. package/corpus/templates/design/shared/native-effect-folded-mesh.ts +489 -0
  411. package/corpus/templates/design/shared/native-effect-gallery-additions.ts +2 -2
  412. package/corpus/templates/design/shared/native-effect-paint.ts +8 -0
  413. package/corpus/templates/design/shared/native-effect-parameter-constraints.ts +8 -1
  414. package/corpus/templates/design/shared/native-effect-presets.ts +18 -1
  415. package/corpus/templates/design/shared/native-effect-property-presentation.ts +81 -0
  416. package/corpus/templates/design/shared/native-effect-pulsing-border-v3.ts +281 -0
  417. package/corpus/templates/design/shared/native-effect-pulsing-border-v4.ts +284 -0
  418. package/corpus/templates/design/shared/native-effect-pulsing-border.ts +300 -0
  419. package/corpus/templates/design/shared/native-effect-trust.ts +6 -0
  420. package/corpus/templates/design/shared/native-effect-wgsl.ts +12 -0
  421. package/corpus/templates/design/shared/native-effects.ts +528 -15
  422. package/corpus/templates/design/shared/native-input-resources.ts +36 -0
  423. package/corpus/templates/design/shared/native-local-export.ts +14 -0
  424. package/corpus/templates/design/shared/native-parameter-animation.ts +1 -0
  425. package/corpus/templates/design/shared/native-pointer-input.ts +9 -11
  426. package/corpus/templates/design/shared/shader-fills.ts +0 -513
  427. package/corpus/templates/design/vitest.setup.ts +7 -1
  428. package/corpus/templates/dispatch/.agents/skills/actions/references/action-fields.md +1 -1
  429. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +20 -18
  430. package/corpus/templates/factory/.agents/skills/actions/references/action-fields.md +1 -1
  431. package/corpus/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  432. package/corpus/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  433. package/corpus/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  434. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +20 -18
  435. package/corpus/templates/forms/.agents/skills/actions/references/action-fields.md +1 -1
  436. package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -1
  437. package/corpus/templates/mail/.agents/skills/actions/references/action-fields.md +1 -1
  438. package/corpus/templates/plan/.agents/skills/actions/references/action-fields.md +1 -1
  439. package/corpus/templates/slides/.agents/skills/actions/references/action-fields.md +1 -1
  440. package/corpus/templates/slides/CHANGELOG.md +6 -0
  441. package/corpus/templates/slides/actions/delete-deck.ts +7 -0
  442. package/corpus/templates/slides/changelog/2026-10-21-connected-deck-deletion-requires-approval.md +6 -0
  443. package/corpus/templates/slides/scripts/edit-fidelity/client-action.ts +61 -0
  444. package/corpus/templates/slides/scripts/edit-fidelity/run.ts +10 -0
  445. package/corpus/templates/slides-2/.agents/skills/actions/SKILL.md +199 -0
  446. package/corpus/templates/slides-2/.agents/skills/actions/references/action-fields.md +145 -0
  447. package/corpus/templates/slides-2/.agents/skills/actions/references/examples.md +96 -0
  448. package/corpus/templates/slides-2/.agents/skills/actions/references/provider-apis.md +95 -0
  449. package/corpus/templates/slides-2/.agents/skills/adding-a-feature/SKILL.md +235 -0
  450. package/corpus/templates/slides-2/.agents/skills/agent-native-docs/SKILL.md +161 -0
  451. package/corpus/templates/slides-2/.agents/skills/agent-native-toolkit/SKILL.md +314 -0
  452. package/corpus/templates/slides-2/.agents/skills/analytics-data-for-decks/SKILL.md +44 -0
  453. package/corpus/templates/slides-2/.agents/skills/apply-slide-comments/SKILL.md +63 -0
  454. package/corpus/templates/slides-2/.agents/skills/client-side-routing/SKILL.md +87 -0
  455. package/corpus/templates/slides-2/.agents/skills/context-awareness/SKILL.md +282 -0
  456. package/corpus/templates/slides-2/.agents/skills/create-deck/SKILL.md +263 -0
  457. package/corpus/templates/slides-2/.agents/skills/create-deck/references/reference-inputs.md +72 -0
  458. package/corpus/templates/slides-2/.agents/skills/create-deck/references/slide-templates.md +93 -0
  459. package/corpus/templates/slides-2/.agents/skills/create-deck/references/source-material.md +16 -0
  460. package/corpus/templates/slides-2/.agents/skills/creative-context/SKILL.md +134 -0
  461. package/corpus/templates/slides-2/.agents/skills/customizing-agent-native/SKILL.md +219 -0
  462. package/corpus/templates/slides-2/.agents/skills/deck-management/SKILL.md +182 -0
  463. package/corpus/templates/slides-2/.agents/skills/delegate-to-agent/SKILL.md +62 -0
  464. package/corpus/templates/slides-2/.agents/skills/design-systems/SKILL.md +233 -0
  465. package/corpus/templates/slides-2/.agents/skills/external-agents/SKILL.md +549 -0
  466. package/corpus/templates/slides-2/.agents/skills/external-agents/references/mcp-apps-embedding.md +169 -0
  467. package/corpus/templates/slides-2/.agents/skills/frontend-design/SKILL.md +102 -0
  468. package/corpus/templates/slides-2/.agents/skills/frontend-design/references/visual-direction.md +102 -0
  469. package/corpus/templates/slides-2/.agents/skills/image-generation-via-a2a/SKILL.md +134 -0
  470. package/corpus/templates/slides-2/.agents/skills/performance/SKILL.md +79 -0
  471. package/corpus/templates/slides-2/.agents/skills/portability/SKILL.md +108 -0
  472. package/corpus/templates/slides-2/.agents/skills/real-time-sync/SKILL.md +146 -0
  473. package/corpus/templates/slides-2/.agents/skills/reliable-mutations/SKILL.md +72 -0
  474. package/corpus/templates/slides-2/.agents/skills/secrets/SKILL.md +82 -0
  475. package/corpus/templates/slides-2/.agents/skills/security/SKILL.md +80 -0
  476. package/corpus/templates/slides-2/.agents/skills/self-modifying-code/SKILL.md +123 -0
  477. package/corpus/templates/slides-2/.agents/skills/shadcn-ui/SKILL.md +71 -0
  478. package/corpus/templates/slides-2/.agents/skills/sharing/SKILL.md +286 -0
  479. package/corpus/templates/slides-2/.agents/skills/slide-design/SKILL.md +144 -0
  480. package/corpus/templates/slides-2/.agents/skills/slide-editing/SKILL.md +284 -0
  481. package/corpus/templates/slides-2/.agents/skills/slide-editing/references/animations.md +33 -0
  482. package/corpus/templates/slides-2/.agents/skills/slide-editing/references/freeform-objects.md +22 -0
  483. package/corpus/templates/slides-2/.agents/skills/slide-editing/references/restyling.md +69 -0
  484. package/corpus/templates/slides-2/.agents/skills/slide-editing/references/transitions.md +26 -0
  485. package/corpus/templates/slides-2/.agents/skills/slide-editing/references/video.md +45 -0
  486. package/corpus/templates/slides-2/.agents/skills/slide-images/SKILL.md +136 -0
  487. package/corpus/templates/slides-2/.agents/skills/storing-data/SKILL.md +234 -0
  488. package/corpus/templates/slides-2/.agents/skills/turn-into-skill/SKILL.md +112 -0
  489. package/corpus/templates/slides-2/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  490. package/corpus/templates/slides-2/.agents/skills/workspace-conventions/SKILL.md +103 -0
  491. package/corpus/templates/slides-2/.builder/rules/deploy-app.mdc +22 -0
  492. package/corpus/templates/slides-2/.builder/rules/organize-ui.mdc +9 -0
  493. package/corpus/templates/slides-2/.dockerignore +61 -0
  494. package/corpus/templates/slides-2/.env.example +23 -0
  495. package/corpus/templates/slides-2/.ignore +3 -0
  496. package/corpus/templates/slides-2/.mcp.json +8 -0
  497. package/corpus/templates/slides-2/.oxfmtrc.json +8 -0
  498. package/corpus/templates/slides-2/AGENTS.md +66 -0
  499. package/corpus/templates/slides-2/CHANGELOG.md +76 -0
  500. package/corpus/templates/slides-2/DEVELOPING.md +157 -0
  501. package/corpus/templates/slides-2/README.md +58 -0
  502. package/corpus/templates/slides-2/THIRD_PARTY_NOTICES.md +33 -0
  503. package/corpus/templates/slides-2/_gitignore +38 -0
  504. package/corpus/templates/slides-2/actions/_agent-presence.ts +29 -0
  505. package/corpus/templates/slides-2/actions/_app-url.ts +37 -0
  506. package/corpus/templates/slides-2/actions/_deck-app-scope.ts +30 -0
  507. package/corpus/templates/slides-2/actions/_deck-tracking.ts +260 -0
  508. package/corpus/templates/slides-2/actions/_deck-write.ts +206 -0
  509. package/corpus/templates/slides-2/actions/_imported-slide-source.ts +162 -0
  510. package/corpus/templates/slides-2/actions/_inline-image-storage.ts +1013 -0
  511. package/corpus/templates/slides-2/actions/_linked-design-system.ts +83 -0
  512. package/corpus/templates/slides-2/actions/_presenter-notes.ts +83 -0
  513. package/corpus/templates/slides-2/actions/_render-artifacts.ts +111 -0
  514. package/corpus/templates/slides-2/actions/_slide-source.ts +344 -0
  515. package/corpus/templates/slides-2/actions/_tab-state.ts +51 -0
  516. package/corpus/templates/slides-2/actions/_test-brandfetch.ts +31 -0
  517. package/corpus/templates/slides-2/actions/_uploaded-files.ts +114 -0
  518. package/corpus/templates/slides-2/actions/add-deck.ts +123 -0
  519. package/corpus/templates/slides-2/actions/add-slide-comment.ts +267 -0
  520. package/corpus/templates/slides-2/actions/add-slide.ts +888 -0
  521. package/corpus/templates/slides-2/actions/analyze-brand-assets.ts +66 -0
  522. package/corpus/templates/slides-2/actions/apply-design-system.ts +111 -0
  523. package/corpus/templates/slides-2/actions/approve-deck-access-request.ts +287 -0
  524. package/corpus/templates/slides-2/actions/audit-contrast.ts +143 -0
  525. package/corpus/templates/slides-2/actions/check-image-gen.ts +17 -0
  526. package/corpus/templates/slides-2/actions/clone-context-slide.ts +340 -0
  527. package/corpus/templates/slides-2/actions/clone-creative-context-deck.ts +143 -0
  528. package/corpus/templates/slides-2/actions/control-deck-history.ts +186 -0
  529. package/corpus/templates/slides-2/actions/control-presenter.ts +117 -0
  530. package/corpus/templates/slides-2/actions/control-slide-editor.ts +267 -0
  531. package/corpus/templates/slides-2/actions/create-deck-from-template.ts +274 -0
  532. package/corpus/templates/slides-2/actions/create-deck.ts +1243 -0
  533. package/corpus/templates/slides-2/actions/create-design-system.ts +131 -0
  534. package/corpus/templates/slides-2/actions/create-share-link.ts +127 -0
  535. package/corpus/templates/slides-2/actions/db-health.ts +22 -0
  536. package/corpus/templates/slides-2/actions/delete-asset.ts +154 -0
  537. package/corpus/templates/slides-2/actions/delete-deck.ts +427 -0
  538. package/corpus/templates/slides-2/actions/delete-design-system.ts +167 -0
  539. package/corpus/templates/slides-2/actions/delete-slide-comment.ts +143 -0
  540. package/corpus/templates/slides-2/actions/delete-staged-dataset.ts +30 -0
  541. package/corpus/templates/slides-2/actions/duplicate-deck.ts +299 -0
  542. package/corpus/templates/slides-2/actions/export-google-slides.ts +41 -0
  543. package/corpus/templates/slides-2/actions/export-html.ts +770 -0
  544. package/corpus/templates/slides-2/actions/export-pptx.ts +2203 -0
  545. package/corpus/templates/slides-2/actions/extract-pdf.ts +49 -0
  546. package/corpus/templates/slides-2/actions/generate-image-api.ts +671 -0
  547. package/corpus/templates/slides-2/actions/generate-image.ts +492 -0
  548. package/corpus/templates/slides-2/actions/get-agent-access-deck.ts +52 -0
  549. package/corpus/templates/slides-2/actions/get-deck-access-status.ts +130 -0
  550. package/corpus/templates/slides-2/actions/get-deck-design-tokens.ts +62 -0
  551. package/corpus/templates/slides-2/actions/get-deck-reference-context.ts +232 -0
  552. package/corpus/templates/slides-2/actions/get-deck-template.ts +38 -0
  553. package/corpus/templates/slides-2/actions/get-deck-version.ts +85 -0
  554. package/corpus/templates/slides-2/actions/get-deck.ts +562 -0
  555. package/corpus/templates/slides-2/actions/get-design-system-decode-job-status.ts +57 -0
  556. package/corpus/templates/slides-2/actions/get-design-system-tier-limit.ts +12 -0
  557. package/corpus/templates/slides-2/actions/get-design-system.ts +453 -0
  558. package/corpus/templates/slides-2/actions/get-google-docs-status.ts +106 -0
  559. package/corpus/templates/slides-2/actions/get-google-picker-token.ts +84 -0
  560. package/corpus/templates/slides-2/actions/get-home-suggestions.ts +52 -0
  561. package/corpus/templates/slides-2/actions/get-layout-overflows.ts +192 -0
  562. package/corpus/templates/slides-2/actions/get-slide-render.ts +125 -0
  563. package/corpus/templates/slides-2/actions/get-slide-source.ts +115 -0
  564. package/corpus/templates/slides-2/actions/get-slide-theme-preview.ts +64 -0
  565. package/corpus/templates/slides-2/actions/get-slide-theme.ts +44 -0
  566. package/corpus/templates/slides-2/actions/get-slides-2-upload-storage-status.ts +17 -0
  567. package/corpus/templates/slides-2/actions/get-slides-notification-prefs.ts +37 -0
  568. package/corpus/templates/slides-2/actions/get-workspace-defaults.ts +51 -0
  569. package/corpus/templates/slides-2/actions/image-gen-status.ts +35 -0
  570. package/corpus/templates/slides-2/actions/import-code.ts +26 -0
  571. package/corpus/templates/slides-2/actions/import-design-project.ts +49 -0
  572. package/corpus/templates/slides-2/actions/import-document.ts +125 -0
  573. package/corpus/templates/slides-2/actions/import-docx.ts +57 -0
  574. package/corpus/templates/slides-2/actions/import-file.ts +1273 -0
  575. package/corpus/templates/slides-2/actions/import-from-url.ts +25 -0
  576. package/corpus/templates/slides-2/actions/import-google-doc.ts +208 -0
  577. package/corpus/templates/slides-2/actions/import-google-font.ts +110 -0
  578. package/corpus/templates/slides-2/actions/import-google-slides-reference.ts +667 -0
  579. package/corpus/templates/slides-2/actions/import-pptx.ts +564 -0
  580. package/corpus/templates/slides-2/actions/import-svgl-logo.ts +115 -0
  581. package/corpus/templates/slides-2/actions/index-design-system-with-builder.ts +181 -0
  582. package/corpus/templates/slides-2/actions/index-uploaded-design-system-files.ts +77 -0
  583. package/corpus/templates/slides-2/actions/list-assets.ts +286 -0
  584. package/corpus/templates/slides-2/actions/list-deck-templates.ts +83 -0
  585. package/corpus/templates/slides-2/actions/list-deck-versions.ts +185 -0
  586. package/corpus/templates/slides-2/actions/list-decks.ts +591 -0
  587. package/corpus/templates/slides-2/actions/list-design-systems.ts +180 -0
  588. package/corpus/templates/slides-2/actions/list-slide-comments.ts +128 -0
  589. package/corpus/templates/slides-2/actions/list-slide-themes.ts +17 -0
  590. package/corpus/templates/slides-2/actions/list-staged-datasets.ts +14 -0
  591. package/corpus/templates/slides-2/actions/logo-config.ts +13 -0
  592. package/corpus/templates/slides-2/actions/navigate.ts +158 -0
  593. package/corpus/templates/slides-2/actions/patch-deck.ts +2378 -0
  594. package/corpus/templates/slides-2/actions/provider-api-catalog.ts +25 -0
  595. package/corpus/templates/slides-2/actions/provider-api-docs.ts +83 -0
  596. package/corpus/templates/slides-2/actions/provider-api-request.ts +222 -0
  597. package/corpus/templates/slides-2/actions/query-staged-dataset.ts +83 -0
  598. package/corpus/templates/slides-2/actions/read-composer-source.ts +108 -0
  599. package/corpus/templates/slides-2/actions/request-deck-access.ts +803 -0
  600. package/corpus/templates/slides-2/actions/restore-deck-version.ts +203 -0
  601. package/corpus/templates/slides-2/actions/run.ts +2 -0
  602. package/corpus/templates/slides-2/actions/save-deck.ts +313 -0
  603. package/corpus/templates/slides-2/actions/search-google-fonts.ts +61 -0
  604. package/corpus/templates/slides-2/actions/search-images.ts +30 -0
  605. package/corpus/templates/slides-2/actions/search-logos.ts +23 -0
  606. package/corpus/templates/slides-2/actions/search-svgl-logos.ts +42 -0
  607. package/corpus/templates/slides-2/actions/set-default-design-system.ts +88 -0
  608. package/corpus/templates/slides-2/actions/set-workspace-defaults.ts +61 -0
  609. package/corpus/templates/slides-2/actions/start-design-system-upload.ts +80 -0
  610. package/corpus/templates/slides-2/actions/sync-design-system-with-builder.ts +84 -0
  611. package/corpus/templates/slides-2/actions/toggle-slide-comment-reaction.ts +150 -0
  612. package/corpus/templates/slides-2/actions/transform-slide-objects.ts +1528 -0
  613. package/corpus/templates/slides-2/actions/update-asset.ts +499 -0
  614. package/corpus/templates/slides-2/actions/update-deck-aspect-ratio.ts +95 -0
  615. package/corpus/templates/slides-2/actions/update-deck-design-tokens.ts +175 -0
  616. package/corpus/templates/slides-2/actions/update-design-system.ts +95 -0
  617. package/corpus/templates/slides-2/actions/update-slide-comment.ts +213 -0
  618. package/corpus/templates/slides-2/actions/update-slide-source.ts +353 -0
  619. package/corpus/templates/slides-2/actions/update-slide.ts +850 -0
  620. package/corpus/templates/slides-2/actions/update-slides-notification-prefs.ts +55 -0
  621. package/corpus/templates/slides-2/actions/view-screen.ts +1098 -0
  622. package/corpus/templates/slides-2/agent-native.app-skill.json +165 -0
  623. package/corpus/templates/slides-2/agent-native.config.ts +20 -0
  624. package/corpus/templates/slides-2/agent-native.json +18 -0
  625. package/corpus/templates/slides-2/app/components/ThemeToggle.tsx +47 -0
  626. package/corpus/templates/slides-2/app/components/comments/SlideCommentPins.tsx +781 -0
  627. package/corpus/templates/slides-2/app/components/comments/SlideCommentsPanel.tsx +1075 -0
  628. package/corpus/templates/slides-2/app/components/deck/DeckCard.tsx +304 -0
  629. package/corpus/templates/slides-2/app/components/deck/DeckFilterMenu.tsx +83 -0
  630. package/corpus/templates/slides-2/app/components/deck/ExcalidrawSlide.tsx +183 -0
  631. package/corpus/templates/slides-2/app/components/deck/MermaidRenderer.tsx +126 -0
  632. package/corpus/templates/slides-2/app/components/deck/SlideRenderer.tsx +1553 -0
  633. package/corpus/templates/slides-2/app/components/design-system/DesignSystemCard.tsx +235 -0
  634. package/corpus/templates/slides-2/app/components/design-system/DesignSystemSetup.tsx +2021 -0
  635. package/corpus/templates/slides-2/app/components/design-system/builder-design-system-upload.ts +200 -0
  636. package/corpus/templates/slides-2/app/components/design-system/builder-index-response.ts +104 -0
  637. package/corpus/templates/slides-2/app/components/editor/AddSlidePopover.tsx +461 -0
  638. package/corpus/templates/slides-2/app/components/editor/AiEditingMarker.tsx +24 -0
  639. package/corpus/templates/slides-2/app/components/editor/AlignmentGuides.tsx +82 -0
  640. package/corpus/templates/slides-2/app/components/editor/AnimationsPanel.tsx +698 -0
  641. package/corpus/templates/slides-2/app/components/editor/AppMenu.tsx +356 -0
  642. package/corpus/templates/slides-2/app/components/editor/AssetLibraryPanel.tsx +508 -0
  643. package/corpus/templates/slides-2/app/components/editor/BlockBubbleMenu.tsx +548 -0
  644. package/corpus/templates/slides-2/app/components/editor/DeckAccessDeniedPage.tsx +173 -0
  645. package/corpus/templates/slides-2/app/components/editor/DeckEditorSkeleton.tsx +35 -0
  646. package/corpus/templates/slides-2/app/components/editor/DeferredPopoverFallback.tsx +148 -0
  647. package/corpus/templates/slides-2/app/components/editor/EditorActionCluster.tsx +217 -0
  648. package/corpus/templates/slides-2/app/components/editor/EditorSidebar.tsx +1047 -0
  649. package/corpus/templates/slides-2/app/components/editor/EditorToolbar.tsx +1285 -0
  650. package/corpus/templates/slides-2/app/components/editor/ExportMenu.tsx +579 -0
  651. package/corpus/templates/slides-2/app/components/editor/GeneratingOverlay.tsx +21 -0
  652. package/corpus/templates/slides-2/app/components/editor/GeneratingSlidePreview.tsx +73 -0
  653. package/corpus/templates/slides-2/app/components/editor/GoogleDocImportHint.tsx +378 -0
  654. package/corpus/templates/slides-2/app/components/editor/GoogleDriveConnectionCta.tsx +154 -0
  655. package/corpus/templates/slides-2/app/components/editor/GoogleSlidesReferenceImport.tsx +299 -0
  656. package/corpus/templates/slides-2/app/components/editor/HistoryPanel.tsx +354 -0
  657. package/corpus/templates/slides-2/app/components/editor/HomeQuickStartDialog.tsx +202 -0
  658. package/corpus/templates/slides-2/app/components/editor/ImageCropOverlay.tsx +820 -0
  659. package/corpus/templates/slides-2/app/components/editor/ImageDropPromptPopover.tsx +280 -0
  660. package/corpus/templates/slides-2/app/components/editor/ImageGenPanel.tsx +244 -0
  661. package/corpus/templates/slides-2/app/components/editor/ImageOverlay.tsx +280 -0
  662. package/corpus/templates/slides-2/app/components/editor/ImageSearchPanel.tsx +183 -0
  663. package/corpus/templates/slides-2/app/components/editor/ImportDeckButton.tsx +247 -0
  664. package/corpus/templates/slides-2/app/components/editor/LogoSearchPanel.tsx +366 -0
  665. package/corpus/templates/slides-2/app/components/editor/MermaidToExcalidrawPanel.tsx +99 -0
  666. package/corpus/templates/slides-2/app/components/editor/MissingDeckAccessPane.tsx +219 -0
  667. package/corpus/templates/slides-2/app/components/editor/NewDeckReferenceStep.tsx +812 -0
  668. package/corpus/templates/slides-2/app/components/editor/PromptDialog.tsx +963 -0
  669. package/corpus/templates/slides-2/app/components/editor/QuestionFlow.tsx +119 -0
  670. package/corpus/templates/slides-2/app/components/editor/RequestDeckAccessDialog.tsx +101 -0
  671. package/corpus/templates/slides-2/app/components/editor/ShareDialog.tsx +126 -0
  672. package/corpus/templates/slides-2/app/components/editor/SlideContextToolbar.tsx +1471 -0
  673. package/corpus/templates/slides-2/app/components/editor/SlideEditor.tsx +11183 -0
  674. package/corpus/templates/slides-2/app/components/editor/SlideOverflowWarning.tsx +82 -0
  675. package/corpus/templates/slides-2/app/components/editor/SlideScrollStack.tsx +307 -0
  676. package/corpus/templates/slides-2/app/components/editor/SlideSlashCommandMenu.tsx +692 -0
  677. package/corpus/templates/slides-2/app/components/editor/SlideThumbnailContextMenu.tsx +52 -0
  678. package/corpus/templates/slides-2/app/components/editor/SlideTransitionControl.tsx +184 -0
  679. package/corpus/templates/slides-2/app/components/editor/SlidesComposerContext.tsx +789 -0
  680. package/corpus/templates/slides-2/app/components/editor/SlidesComposerContextProvider.tsx +74 -0
  681. package/corpus/templates/slides-2/app/components/editor/SlidesLayersPanel.tsx +377 -0
  682. package/corpus/templates/slides-2/app/components/editor/SpeakerNotesPanel.tsx +119 -0
  683. package/corpus/templates/slides-2/app/components/editor/TweaksPanel.tsx +77 -0
  684. package/corpus/templates/slides-2/app/components/editor/UploadStorageGate.tsx +37 -0
  685. package/corpus/templates/slides-2/app/components/editor/bullet-editing.ts +880 -0
  686. package/corpus/templates/slides-2/app/components/editor/canvas-interactions/index.ts +12 -0
  687. package/corpus/templates/slides-2/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +119 -0
  688. package/corpus/templates/slides-2/app/components/editor/commit-active-edit.ts +14 -0
  689. package/corpus/templates/slides-2/app/components/editor/editor-command-model.ts +35 -0
  690. package/corpus/templates/slides-2/app/components/editor/fit-text-object.ts +31 -0
  691. package/corpus/templates/slides-2/app/components/editor/in-place-text-session.browser-cases.json +983 -0
  692. package/corpus/templates/slides-2/app/components/editor/in-place-text-session.browser-host.ts +747 -0
  693. package/corpus/templates/slides-2/app/components/editor/in-place-text-session.ts +6891 -0
  694. package/corpus/templates/slides-2/app/components/editor/inline-edit-session.ts +26 -0
  695. package/corpus/templates/slides-2/app/components/editor/list-editing.ts +501 -0
  696. package/corpus/templates/slides-2/app/components/editor/rich-text-selection.ts +975 -0
  697. package/corpus/templates/slides-2/app/components/editor/rte-test-utils.ts +265 -0
  698. package/corpus/templates/slides-2/app/components/editor/selection-overlay-measurement.ts +191 -0
  699. package/corpus/templates/slides-2/app/components/editor/slide-escape-arbiter.ts +34 -0
  700. package/corpus/templates/slides-2/app/components/editor/slide-object-interactions.ts +6362 -0
  701. package/corpus/templates/slides-2/app/components/editor/slide-object-transform.browser-host.ts +19 -0
  702. package/corpus/templates/slides-2/app/components/editor/slide-pointer-target.ts +432 -0
  703. package/corpus/templates/slides-2/app/components/editor/slide-presence.ts +13 -0
  704. package/corpus/templates/slides-2/app/components/editor/slide-style.ts +243 -0
  705. package/corpus/templates/slides-2/app/components/editor/slide-text-targets.ts +540 -0
  706. package/corpus/templates/slides-2/app/components/editor/style-clipboard.ts +102 -0
  707. package/corpus/templates/slides-2/app/components/editor/use-prompt-import.ts +159 -0
  708. package/corpus/templates/slides-2/app/components/home/SlidesHomeLibrary.tsx +79 -0
  709. package/corpus/templates/slides-2/app/components/layout/AgentWorkIndicator.tsx +193 -0
  710. package/corpus/templates/slides-2/app/components/layout/Header.tsx +110 -0
  711. package/corpus/templates/slides-2/app/components/layout/Layout.tsx +492 -0
  712. package/corpus/templates/slides-2/app/components/layout/Sidebar.tsx +109 -0
  713. package/corpus/templates/slides-2/app/components/layout/layout-route-policy.ts +28 -0
  714. package/corpus/templates/slides-2/app/components/presentation/PresentationView.tsx +1116 -0
  715. package/corpus/templates/slides-2/app/components/presentation/PresenterView.tsx +526 -0
  716. package/corpus/templates/slides-2/app/components/presentation/SlideTransitionStage.tsx +297 -0
  717. package/corpus/templates/slides-2/app/components/presentation/present-channel.ts +31 -0
  718. package/corpus/templates/slides-2/app/components/presentation/slide-build-steps.ts +231 -0
  719. package/corpus/templates/slides-2/app/components/presentation/slide-navigation.ts +273 -0
  720. package/corpus/templates/slides-2/app/components/presentation/slide-transition-motion.ts +258 -0
  721. package/corpus/templates/slides-2/app/components/presentation/voice-navigation.ts +61 -0
  722. package/corpus/templates/slides-2/app/components/settings/notification-settings.tsx +93 -0
  723. package/corpus/templates/slides-2/app/components/slides-2-editor/Slides2AssetBrowser.tsx +726 -0
  724. package/corpus/templates/slides-2/app/components/slides-2-editor/Slides2CommandMenu.tsx +453 -0
  725. package/corpus/templates/slides-2/app/components/slides-2-editor/Slides2Comments.tsx +571 -0
  726. package/corpus/templates/slides-2/app/components/slides-2-editor/Slides2DesignTokens.tsx +345 -0
  727. package/corpus/templates/slides-2/app/components/slides-2-editor/Slides2Editor.tsx +4804 -0
  728. package/corpus/templates/slides-2/app/components/slides-2-editor/Slides2ExportMenu.tsx +671 -0
  729. package/corpus/templates/slides-2/app/components/slides-2-editor/Slides2FontBrowser.tsx +342 -0
  730. package/corpus/templates/slides-2/app/components/slides-2-editor/Slides2ImageCropControls.tsx +487 -0
  731. package/corpus/templates/slides-2/app/components/slides-2-editor/Slides2Inspector.tsx +950 -0
  732. package/corpus/templates/slides-2/app/components/slides-2-editor/Slides2SvglLogoSearchDialog.tsx +332 -0
  733. package/corpus/templates/slides-2/app/components/slides-2-editor/cross-slide-edit-history.ts +151 -0
  734. package/corpus/templates/slides-2/app/components/slides-2-editor/design-token-presets.ts +140 -0
  735. package/corpus/templates/slides-2/app/components/slides-2-editor/editor-action-errors.ts +47 -0
  736. package/corpus/templates/slides-2/app/components/slides-2-editor/editor-export-errors.ts +60 -0
  737. package/corpus/templates/slides-2/app/components/slides-2-editor/geometry.ts +275 -0
  738. package/corpus/templates/slides-2/app/components/slides-2-editor/image-crop-style.ts +82 -0
  739. package/corpus/templates/slides-2/app/components/slides-2-editor/inline-text-editor.tsx +631 -0
  740. package/corpus/templates/slides-2/app/components/slides-2-editor/keyboard-shortcuts.ts +104 -0
  741. package/corpus/templates/slides-2/app/components/slides-2-editor/object-insertion.ts +13 -0
  742. package/corpus/templates/slides-2/app/components/slides-2-editor/preview-patches.ts +54 -0
  743. package/corpus/templates/slides-2/app/components/slides-2-editor/sandbox-render-errors.ts +23 -0
  744. package/corpus/templates/slides-2/app/components/slides-2-editor/source-structure.ts +634 -0
  745. package/corpus/templates/slides-2/app/components/slides-2-editor/types.ts +85 -0
  746. package/corpus/templates/slides-2/app/components/slides-2-presenter/Slides2BlackoutOverlay.tsx +13 -0
  747. package/corpus/templates/slides-2/app/components/slides-2-presenter/Slides2ControlBar.tsx +285 -0
  748. package/corpus/templates/slides-2/app/components/slides-2-presenter/Slides2HelpDialog.tsx +72 -0
  749. package/corpus/templates/slides-2/app/components/slides-2-presenter/Slides2JumpInput.tsx +38 -0
  750. package/corpus/templates/slides-2/app/components/slides-2-presenter/Slides2LaserPointer.tsx +67 -0
  751. package/corpus/templates/slides-2/app/components/slides-2-presenter/Slides2Overview.tsx +161 -0
  752. package/corpus/templates/slides-2/app/components/slides-2-presenter/Slides2Player.tsx +839 -0
  753. package/corpus/templates/slides-2/app/components/slides-2-presenter/Slides2ProgressBar.tsx +23 -0
  754. package/corpus/templates/slides-2/app/components/slides-2-presenter/keyboard.ts +36 -0
  755. package/corpus/templates/slides-2/app/components/slides-2-presenter/presenter-channel.ts +131 -0
  756. package/corpus/templates/slides-2/app/components/slides-2-presenter/use-presenter-action-bridge.ts +296 -0
  757. package/corpus/templates/slides-2/app/components/slides-2-presenter/useSlides2TouchSwipe.ts +80 -0
  758. package/corpus/templates/slides-2/app/components/slides-2-runtime/SandboxedSlide.tsx +724 -0
  759. package/corpus/templates/slides-2/app/components/slides-2-runtime/SlideContentRenderer.tsx +137 -0
  760. package/corpus/templates/slides-2/app/components/slides-2-runtime/Slides2Canvas.tsx +99 -0
  761. package/corpus/templates/slides-2/app/components/slides-2-runtime/constants.ts +4 -0
  762. package/corpus/templates/slides-2/app/components/slides-2-runtime/protocol.ts +1400 -0
  763. package/corpus/templates/slides-2/app/components/slides-2-runtime/transition-frame.ts +439 -0
  764. package/corpus/templates/slides-2/app/components/templates/DeckTemplateLibrary.tsx +314 -0
  765. package/corpus/templates/slides-2/app/components/templates/DeckTemplatePreview.tsx +60 -0
  766. package/corpus/templates/slides-2/app/components/templates/DeckTemplateStage.tsx +45 -0
  767. package/corpus/templates/slides-2/app/components/ui/alert-dialog.tsx +1 -0
  768. package/corpus/templates/slides-2/app/components/ui/avatar.tsx +1 -0
  769. package/corpus/templates/slides-2/app/components/ui/button-group.tsx +1 -0
  770. package/corpus/templates/slides-2/app/components/ui/button.tsx +1 -0
  771. package/corpus/templates/slides-2/app/components/ui/card.tsx +1 -0
  772. package/corpus/templates/slides-2/app/components/ui/command.tsx +1 -0
  773. package/corpus/templates/slides-2/app/components/ui/context-menu.tsx +32 -0
  774. package/corpus/templates/slides-2/app/components/ui/dialog.tsx +1 -0
  775. package/corpus/templates/slides-2/app/components/ui/dropdown-menu.tsx +1 -0
  776. package/corpus/templates/slides-2/app/components/ui/filter-trigger.tsx +1 -0
  777. package/corpus/templates/slides-2/app/components/ui/input.tsx +1 -0
  778. package/corpus/templates/slides-2/app/components/ui/label.tsx +1 -0
  779. package/corpus/templates/slides-2/app/components/ui/popover.tsx +1 -0
  780. package/corpus/templates/slides-2/app/components/ui/progress.tsx +1 -0
  781. package/corpus/templates/slides-2/app/components/ui/scroll-area.tsx +1 -0
  782. package/corpus/templates/slides-2/app/components/ui/select.tsx +1 -0
  783. package/corpus/templates/slides-2/app/components/ui/separator.tsx +1 -0
  784. package/corpus/templates/slides-2/app/components/ui/sheet.tsx +1 -0
  785. package/corpus/templates/slides-2/app/components/ui/skeleton.tsx +1 -0
  786. package/corpus/templates/slides-2/app/components/ui/slider.tsx +1 -0
  787. package/corpus/templates/slides-2/app/components/ui/spinner.tsx +1 -0
  788. package/corpus/templates/slides-2/app/components/ui/switch.tsx +1 -0
  789. package/corpus/templates/slides-2/app/components/ui/tabs.tsx +59 -0
  790. package/corpus/templates/slides-2/app/components/ui/textarea.tsx +1 -0
  791. package/corpus/templates/slides-2/app/components/ui/toggle-group.tsx +1 -0
  792. package/corpus/templates/slides-2/app/components/ui/toolkit-provider.tsx +17 -0
  793. package/corpus/templates/slides-2/app/components/ui/tooltip.tsx +1 -0
  794. package/corpus/templates/slides-2/app/components/visual-editor/CanvasCommentPins.tsx +46 -0
  795. package/corpus/templates/slides-2/app/components/visual-editor/DrawOverlay.tsx +27 -0
  796. package/corpus/templates/slides-2/app/components/visual-editor/MultiSelectChip.tsx +97 -0
  797. package/corpus/templates/slides-2/app/components/visual-editor/SaveStatusIndicator.tsx +273 -0
  798. package/corpus/templates/slides-2/app/components/visual-editor/index.ts +4 -0
  799. package/corpus/templates/slides-2/app/context/DeckContext.tsx +7486 -0
  800. package/corpus/templates/slides-2/app/design-system.ts +3 -0
  801. package/corpus/templates/slides-2/app/entry.client.tsx +10 -0
  802. package/corpus/templates/slides-2/app/entry.server.tsx +10 -0
  803. package/corpus/templates/slides-2/app/global.css +1626 -0
  804. package/corpus/templates/slides-2/app/hooks/use-agent-generating.ts +517 -0
  805. package/corpus/templates/slides-2/app/hooks/use-compact-editor-layout.ts +26 -0
  806. package/corpus/templates/slides-2/app/hooks/use-contrast-audit-bridge.ts +49 -0
  807. package/corpus/templates/slides-2/app/hooks/use-deck-access-reload.ts +70 -0
  808. package/corpus/templates/slides-2/app/hooks/use-deck-access.ts +50 -0
  809. package/corpus/templates/slides-2/app/hooks/use-deck-design-system.ts +146 -0
  810. package/corpus/templates/slides-2/app/hooks/use-deck-history-action-bridge.ts +266 -0
  811. package/corpus/templates/slides-2/app/hooks/use-deck-presence.ts +89 -0
  812. package/corpus/templates/slides-2/app/hooks/use-deck-role.ts +46 -0
  813. package/corpus/templates/slides-2/app/hooks/use-deck-versions.ts +43 -0
  814. package/corpus/templates/slides-2/app/hooks/use-design-system-workflows.ts +11 -0
  815. package/corpus/templates/slides-2/app/hooks/use-design-systems.ts +31 -0
  816. package/corpus/templates/slides-2/app/hooks/use-generating-slide-preview.ts +115 -0
  817. package/corpus/templates/slides-2/app/hooks/use-navigation-state.ts +229 -0
  818. package/corpus/templates/slides-2/app/hooks/use-new-deck-generation-signal.ts +46 -0
  819. package/corpus/templates/slides-2/app/hooks/use-new-deck-generation.ts +710 -0
  820. package/corpus/templates/slides-2/app/hooks/use-sidebar-collapsed.ts +95 -0
  821. package/corpus/templates/slides-2/app/hooks/use-slide-comments.ts +202 -0
  822. package/corpus/templates/slides-2/app/hooks/use-slide-file-storage-status.ts +55 -0
  823. package/corpus/templates/slides-2/app/hooks/use-undo-selection.ts +66 -0
  824. package/corpus/templates/slides-2/app/hooks/use-workspace-defaults.ts +31 -0
  825. package/corpus/templates/slides-2/app/i18n/en-US.ts +1507 -0
  826. package/corpus/templates/slides-2/app/i18n/index.ts +19 -0
  827. package/corpus/templates/slides-2/app/lib/agent-visible-message.ts +21 -0
  828. package/corpus/templates/slides-2/app/lib/aspect-ratios.ts +7 -0
  829. package/corpus/templates/slides-2/app/lib/asset-error-copy.ts +59 -0
  830. package/corpus/templates/slides-2/app/lib/canvas-zoom.ts +47 -0
  831. package/corpus/templates/slides-2/app/lib/composer-context.ts +152 -0
  832. package/corpus/templates/slides-2/app/lib/composer-draft.ts +34 -0
  833. package/corpus/templates/slides-2/app/lib/contrast-audit.ts +390 -0
  834. package/corpus/templates/slides-2/app/lib/contrast-resolve.ts +240 -0
  835. package/corpus/templates/slides-2/app/lib/create-deck-generation.ts +938 -0
  836. package/corpus/templates/slides-2/app/lib/deck-access-lost.ts +4 -0
  837. package/corpus/templates/slides-2/app/lib/deck-backup.ts +186 -0
  838. package/corpus/templates/slides-2/app/lib/deck-editor-loading.ts +91 -0
  839. package/corpus/templates/slides-2/app/lib/deck-export-file-client.ts +77 -0
  840. package/corpus/templates/slides-2/app/lib/deck-filter.ts +52 -0
  841. package/corpus/templates/slides-2/app/lib/deck-list-loading.ts +16 -0
  842. package/corpus/templates/slides-2/app/lib/deck-preview-frame.ts +15 -0
  843. package/corpus/templates/slides-2/app/lib/deck-share-links.ts +9 -0
  844. package/corpus/templates/slides-2/app/lib/deck-sorting.ts +19 -0
  845. package/corpus/templates/slides-2/app/lib/deferred-editor-surfaces.ts +24 -0
  846. package/corpus/templates/slides-2/app/lib/design-system-selection.ts +11 -0
  847. package/corpus/templates/slides-2/app/lib/design-systems.ts +231 -0
  848. package/corpus/templates/slides-2/app/lib/dynamic-import.ts +50 -0
  849. package/corpus/templates/slides-2/app/lib/editor-agent-handoff.ts +92 -0
  850. package/corpus/templates/slides-2/app/lib/editor-shortcuts.ts +153 -0
  851. package/corpus/templates/slides-2/app/lib/export-google-slides-client.ts +168 -0
  852. package/corpus/templates/slides-2/app/lib/export-pdf-client.ts +684 -0
  853. package/corpus/templates/slides-2/app/lib/export-pptx-client.ts +2420 -0
  854. package/corpus/templates/slides-2/app/lib/generation-lifecycle.ts +24 -0
  855. package/corpus/templates/slides-2/app/lib/generation-state.ts +247 -0
  856. package/corpus/templates/slides-2/app/lib/google-docs-client.ts +110 -0
  857. package/corpus/templates/slides-2/app/lib/google-slides-export-availability-client.ts +53 -0
  858. package/corpus/templates/slides-2/app/lib/google-slides-reference-source.ts +18 -0
  859. package/corpus/templates/slides-2/app/lib/image-download.ts +85 -0
  860. package/corpus/templates/slides-2/app/lib/image-drop-to-agent.ts +210 -0
  861. package/corpus/templates/slides-2/app/lib/import-uploaded-deck.ts +132 -0
  862. package/corpus/templates/slides-2/app/lib/inline-edit-remote.ts +55 -0
  863. package/corpus/templates/slides-2/app/lib/localize-slides-changelog.ts +47 -0
  864. package/corpus/templates/slides-2/app/lib/mermaid-blocks.ts +18 -0
  865. package/corpus/templates/slides-2/app/lib/new-deck-reference-selection.ts +174 -0
  866. package/corpus/templates/slides-2/app/lib/normalize-slide-padding.ts +74 -0
  867. package/corpus/templates/slides-2/app/lib/pending-deck-changes.ts +33 -0
  868. package/corpus/templates/slides-2/app/lib/portaled-layer.ts +7 -0
  869. package/corpus/templates/slides-2/app/lib/pptx-google-slides.ts +204 -0
  870. package/corpus/templates/slides-2/app/lib/prompt-attachment-adapter.ts +37 -0
  871. package/corpus/templates/slides-2/app/lib/prompt-file-uploads.ts +557 -0
  872. package/corpus/templates/slides-2/app/lib/recent-references.ts +106 -0
  873. package/corpus/templates/slides-2/app/lib/reference-document-hydration.ts +406 -0
  874. package/corpus/templates/slides-2/app/lib/register-chat-renderers.tsx +645 -0
  875. package/corpus/templates/slides-2/app/lib/reveal-after-delete.ts +55 -0
  876. package/corpus/templates/slides-2/app/lib/sanitize-slide-html.ts +752 -0
  877. package/corpus/templates/slides-2/app/lib/slide-agent-context.ts +148 -0
  878. package/corpus/templates/slides-2/app/lib/slide-animation-elements.ts +900 -0
  879. package/corpus/templates/slides-2/app/lib/slide-clipboard.ts +534 -0
  880. package/corpus/templates/slides-2/app/lib/slide-comment-anchor.ts +286 -0
  881. package/corpus/templates/slides-2/app/lib/slide-content-merge.ts +295 -0
  882. package/corpus/templates/slides-2/app/lib/slide-image-replacement.ts +1919 -0
  883. package/corpus/templates/slides-2/app/lib/slide-live-remote.ts +215 -0
  884. package/corpus/templates/slides-2/app/lib/slide-scroll.ts +56 -0
  885. package/corpus/templates/slides-2/app/lib/slide-source-map.ts +1099 -0
  886. package/corpus/templates/slides-2/app/lib/slide-video.ts +390 -0
  887. package/corpus/templates/slides-2/app/lib/slides-relay-tracking.ts +114 -0
  888. package/corpus/templates/slides-2/app/lib/streaming-slide-html.ts +77 -0
  889. package/corpus/templates/slides-2/app/lib/tab-id.ts +3 -0
  890. package/corpus/templates/slides-2/app/lib/template-navigation.ts +15 -0
  891. package/corpus/templates/slides-2/app/lib/text-tool-shortcut.ts +75 -0
  892. package/corpus/templates/slides-2/app/lib/undo-reveal.ts +332 -0
  893. package/corpus/templates/slides-2/app/lib/upload-response.ts +107 -0
  894. package/corpus/templates/slides-2/app/lib/utils.ts +38 -0
  895. package/corpus/templates/slides-2/app/lib/validate-native-slide-html.ts +177 -0
  896. package/corpus/templates/slides-2/app/lib/video-upload.ts +354 -0
  897. package/corpus/templates/slides-2/app/pages/DeckEditor.tsx +6158 -0
  898. package/corpus/templates/slides-2/app/pages/DesignSystems.tsx +363 -0
  899. package/corpus/templates/slides-2/app/pages/Index.tsx +3254 -0
  900. package/corpus/templates/slides-2/app/pages/NotFound.tsx +33 -0
  901. package/corpus/templates/slides-2/app/pages/Presentation.tsx +120 -0
  902. package/corpus/templates/slides-2/app/pages/SharedPresentation.tsx +174 -0
  903. package/corpus/templates/slides-2/app/pages/SlideThemeDetail.tsx +227 -0
  904. package/corpus/templates/slides-2/app/pages/SlideThemes.tsx +155 -0
  905. package/corpus/templates/slides-2/app/pages/Slides2EditorPage.tsx +1618 -0
  906. package/corpus/templates/slides-2/app/pages/Slides2PresenterConsolePage.tsx +937 -0
  907. package/corpus/templates/slides-2/app/pages/Slides2PresenterPage.tsx +979 -0
  908. package/corpus/templates/slides-2/app/pages/Templates.tsx +32 -0
  909. package/corpus/templates/slides-2/app/root.tsx +391 -0
  910. package/corpus/templates/slides-2/app/routes/$.tsx +10 -0
  911. package/corpus/templates/slides-2/app/routes/_index.tsx +1 -0
  912. package/corpus/templates/slides-2/app/routes/access-request.approve.tsx +276 -0
  913. package/corpus/templates/slides-2/app/routes/agent.tsx +19 -0
  914. package/corpus/templates/slides-2/app/routes/chat.$threadId.tsx +1 -0
  915. package/corpus/templates/slides-2/app/routes/chat.tsx +190 -0
  916. package/corpus/templates/slides-2/app/routes/deck.$id.tsx +10 -0
  917. package/corpus/templates/slides-2/app/routes/deck.$id_.present.tsx +10 -0
  918. package/corpus/templates/slides-2/app/routes/design-systems.tsx +10 -0
  919. package/corpus/templates/slides-2/app/routes/extensions.$id.$slug.tsx +2 -0
  920. package/corpus/templates/slides-2/app/routes/extensions.$id.tsx +5 -0
  921. package/corpus/templates/slides-2/app/routes/extensions._index.tsx +5 -0
  922. package/corpus/templates/slides-2/app/routes/extensions.tsx +5 -0
  923. package/corpus/templates/slides-2/app/routes/home-layout.tsx +31 -0
  924. package/corpus/templates/slides-2/app/routes/home.tsx +22 -0
  925. package/corpus/templates/slides-2/app/routes/p.$id.tsx +195 -0
  926. package/corpus/templates/slides-2/app/routes/settings.$.tsx +1 -0
  927. package/corpus/templates/slides-2/app/routes/settings.tsx +131 -0
  928. package/corpus/templates/slides-2/app/routes/share.$token.tsx +137 -0
  929. package/corpus/templates/slides-2/app/routes/slide.tsx +209 -0
  930. package/corpus/templates/slides-2/app/routes/team.tsx +11 -0
  931. package/corpus/templates/slides-2/app/routes/templates.tsx +1 -0
  932. package/corpus/templates/slides-2/app/routes/themes.$id.tsx +1 -0
  933. package/corpus/templates/slides-2/app/routes/themes.tsx +1 -0
  934. package/corpus/templates/slides-2/app/routes.ts +24 -0
  935. package/corpus/templates/slides-2/app/vite-env.d.ts +24 -0
  936. package/corpus/templates/slides-2/changelog/2026-10-17-find-and-switch-decks-from-the-presenter-console.md +6 -0
  937. package/corpus/templates/slides-2/changelog/2026-10-17-meet-slides-2-create-and-refine-editable-slide-decks-with-an.md +6 -0
  938. package/corpus/templates/slides-2/changelog/2026-10-17-pptx-image-export.md +6 -0
  939. package/corpus/templates/slides-2/changelog/2026-10-17-visual-editor.md +6 -0
  940. package/corpus/templates/slides-2/changelog/2026-10-18-apply-an-accessible-design-system-to-an-existing-deck-before.md +6 -0
  941. package/corpus/templates/slides-2/changelog/2026-10-18-choose-a-template-or-start-a-new-presentation-from-the-slide.md +6 -0
  942. package/corpus/templates/slides-2/changelog/2026-10-18-generate-decks-from-a-prompt-then-edit-slide-elements-direct.md +6 -0
  943. package/corpus/templates/slides-2/changelog/2026-10-18-generate-presentation-decks-from-a-prompt-and-edit-every-sli.md +6 -0
  944. package/corpus/templates/slides-2/changelog/2026-10-18-new-presentation-drafts-save-before-generation-starts-so-you.md +6 -0
  945. package/corpus/templates/slides-2/changelog/2026-10-18-the-assistant-can-undo-redo-and-save-pending-edits-in-the-vi.md +6 -0
  946. package/corpus/templates/slides-2/changelog/2026-10-19-agents-can-insert-duplicate-and-delete-canvas-objects-in-sou.md +6 -0
  947. package/corpus/templates/slides-2/changelog/2026-10-19-browse-slide-themes.md +6 -0
  948. package/corpus/templates/slides-2/changelog/2026-10-19-clicking-a-slide-preview-in-overview-selects-that-slide.md +6 -0
  949. package/corpus/templates/slides-2/changelog/2026-10-19-create-decks-from-a-prompt-and-edit-slides-directly-on-the-c.md +6 -0
  950. package/corpus/templates/slides-2/changelog/2026-10-19-creating-and-editing-decks-now-starts-with-the-tools-most-re.md +6 -0
  951. package/corpus/templates/slides-2/changelog/2026-10-19-deleting-decks-revokes-public-links.md +7 -0
  952. package/corpus/templates/slides-2/changelog/2026-10-19-escape-cancels-an-in-progress-slide-drag-without-losing-earl.md +6 -0
  953. package/corpus/templates/slides-2/changelog/2026-10-19-import-failures-now-show-clear-localized-descriptions-instea.md +6 -0
  954. package/corpus/templates/slides-2/changelog/2026-10-19-presenter-controls-stay-responsive-when-moving-over-the-slid.md +6 -0
  955. package/corpus/templates/slides-2/changelog/2026-10-19-presenter-notes-stay-private-from-viewers-and-commenters.md +6 -0
  956. package/corpus/templates/slides-2/changelog/2026-10-19-preview-generated-slides-in-chat.md +6 -0
  957. package/corpus/templates/slides-2/changelog/2026-10-19-remote-image-previews-accept-supported-raster-formats.md +6 -0
  958. package/corpus/templates/slides-2/changelog/2026-10-19-search-the-svgl-catalog-and-add-svg-logos-to-a-deck-or-the-g.md +6 -0
  959. package/corpus/templates/slides-2/changelog/2026-10-19-slide-generation-explains-when-react-effect-hooks-cannot-run.md +6 -0
  960. package/corpus/templates/slides-2/changelog/2026-10-19-the-editor-highlights-hovered-objects-and-keeps-image-replac.md +6 -0
  961. package/corpus/templates/slides-2/changelog/2026-10-19-the-slide-editor-uses-the-shared-agent-native-controls.md +6 -0
  962. package/corpus/templates/slides-2/changelog/2026-10-20-deck-editing-controls-match-the-workspace.md +6 -0
  963. package/corpus/templates/slides-2/changelog/2026-10-20-google-slides-imports-now-report-missing-image-data-instead-.md +6 -0
  964. package/corpus/templates/slides-2/changelog/2026-10-20-imports-and-previews-handle-large-content-safely.md +6 -0
  965. package/corpus/templates/slides-2/changelog/2026-10-20-public-deck-pages-can-export-source-backed-slides-to-pdf.md +6 -0
  966. package/corpus/templates/slides-2/changelog/2026-10-20-saved-slide-images-stay-available.md +6 -0
  967. package/corpus/templates/slides-2/changelog/2026-10-20-scope-global-media-picks-to-assets-the-current-deck-can-reso.md +6 -0
  968. package/corpus/templates/slides-2/components.json +20 -0
  969. package/corpus/templates/slides-2/drizzle.config.ts +3 -0
  970. package/corpus/templates/slides-2/learnings.defaults.md +5 -0
  971. package/corpus/templates/slides-2/netlify.toml +24 -0
  972. package/corpus/templates/slides-2/package.json +147 -0
  973. package/corpus/templates/slides-2/public/agent-native-icon-dark.svg +10 -0
  974. package/corpus/templates/slides-2/public/agent-native-icon-light.svg +10 -0
  975. package/corpus/templates/slides-2/public/agent-native-logo-dark.svg +21 -0
  976. package/corpus/templates/slides-2/public/agent-native-logo-light.svg +21 -0
  977. package/corpus/templates/slides-2/public/assets/builder-logo-white.svg +15 -0
  978. package/corpus/templates/slides-2/public/assets/generated/preview.html +61 -0
  979. package/corpus/templates/slides-2/public/assets/intuit-logo-white.svg +6 -0
  980. package/corpus/templates/slides-2/public/assets/walmart-logo-white.svg +6 -0
  981. package/corpus/templates/slides-2/public/chatgpt-plugin-icon.svg +7 -0
  982. package/corpus/templates/slides-2/public/favicon.svg +1 -0
  983. package/corpus/templates/slides-2/public/icon-180.svg +1 -0
  984. package/corpus/templates/slides-2/public/icon-192.svg +1 -0
  985. package/corpus/templates/slides-2/public/icon-512.svg +1 -0
  986. package/corpus/templates/slides-2/public/manifest.json +20 -0
  987. package/corpus/templates/slides-2/public/placeholder.svg +1 -0
  988. package/corpus/templates/slides-2/public/robots.txt +14 -0
  989. package/corpus/templates/slides-2/public/visual-edit-structure-proof.html +99 -0
  990. package/corpus/templates/slides-2/react-router.config.ts +7 -0
  991. package/corpus/templates/slides-2/scripts/edit-fidelity/README.md +499 -0
  992. package/corpus/templates/slides-2/scripts/edit-fidelity/authoring-fuzz.ts +9517 -0
  993. package/corpus/templates/slides-2/scripts/edit-fidelity/baseline.json +16427 -0
  994. package/corpus/templates/slides-2/scripts/edit-fidelity/dev-server-url.ts +10 -0
  995. package/corpus/templates/slides-2/scripts/edit-fidelity/lib/in-page.ts +1975 -0
  996. package/corpus/templates/slides-2/scripts/edit-fidelity/lib/metrics.ts +1401 -0
  997. package/corpus/templates/slides-2/scripts/edit-fidelity/retry-infra.ts +7 -0
  998. package/corpus/templates/slides-2/scripts/edit-fidelity/run-options.ts +21 -0
  999. package/corpus/templates/slides-2/scripts/edit-fidelity/run-outcomes.ts +127 -0
  1000. package/corpus/templates/slides-2/scripts/edit-fidelity/run.ts +8451 -0
  1001. package/corpus/templates/slides-2/scripts/export-fidelity/README.md +116 -0
  1002. package/corpus/templates/slides-2/scripts/export-fidelity/compare-layout-lib.ts +241 -0
  1003. package/corpus/templates/slides-2/scripts/export-fidelity/compare-layout.ts +30 -0
  1004. package/corpus/templates/slides-2/scripts/export-fidelity/diff.ts +222 -0
  1005. package/corpus/templates/slides-2/scripts/export-fidelity/export.ts +765 -0
  1006. package/corpus/templates/slides-2/scripts/export-fidelity/fixtures/agent-dark-deck.json +48 -0
  1007. package/corpus/templates/slides-2/scripts/export-fidelity/generate-calibration.ts +765 -0
  1008. package/corpus/templates/slides-2/scripts/export-fidelity/google-export.ts +137 -0
  1009. package/corpus/templates/slides-2/scripts/export-fidelity/google-layout.ts +82 -0
  1010. package/corpus/templates/slides-2/scripts/export-fidelity/resolve-pkg.ts +29 -0
  1011. package/corpus/templates/slides-2/scripts/migrate-production.ts +22 -0
  1012. package/corpus/templates/slides-2/server/db/index.ts +73 -0
  1013. package/corpus/templates/slides-2/server/db/schema.ts +189 -0
  1014. package/corpus/templates/slides-2/server/handlers/assets-url.ts +13 -0
  1015. package/corpus/templates/slides-2/server/handlers/assets.ts +3217 -0
  1016. package/corpus/templates/slides-2/server/handlers/decks.ts +185 -0
  1017. package/corpus/templates/slides-2/server/handlers/demo.ts +9 -0
  1018. package/corpus/templates/slides-2/server/handlers/design-systems.ts +219 -0
  1019. package/corpus/templates/slides-2/server/handlers/google-docs-auth.ts +165 -0
  1020. package/corpus/templates/slides-2/server/handlers/image-gen.ts +153 -0
  1021. package/corpus/templates/slides-2/server/handlers/image-providers/gemini.ts +209 -0
  1022. package/corpus/templates/slides-2/server/handlers/image-providers/index.ts +61 -0
  1023. package/corpus/templates/slides-2/server/handlers/image-providers/openai.ts +288 -0
  1024. package/corpus/templates/slides-2/server/handlers/image-providers/types.ts +35 -0
  1025. package/corpus/templates/slides-2/server/handlers/import/docx-parser.ts +31 -0
  1026. package/corpus/templates/slides-2/server/handlers/import/html-converter.ts +1534 -0
  1027. package/corpus/templates/slides-2/server/handlers/import/pdf-fidelity-parser.ts +1039 -0
  1028. package/corpus/templates/slides-2/server/handlers/import/pdf-sidecar-reader.ts +81 -0
  1029. package/corpus/templates/slides-2/server/handlers/import/pdf-style-digest.ts +187 -0
  1030. package/corpus/templates/slides-2/server/handlers/import/pptx-assets.ts +155 -0
  1031. package/corpus/templates/slides-2/server/handlers/import/pptx-parser.ts +57 -0
  1032. package/corpus/templates/slides-2/server/handlers/request-auth-context.ts +108 -0
  1033. package/corpus/templates/slides-2/server/handlers/share.ts +52 -0
  1034. package/corpus/templates/slides-2/server/handlers/uploads-chunked.ts +1066 -0
  1035. package/corpus/templates/slides-2/server/handlers/uploads.ts +457 -0
  1036. package/corpus/templates/slides-2/server/lib/access-request-email.ts +66 -0
  1037. package/corpus/templates/slides-2/server/lib/assets-image-delegation.ts +331 -0
  1038. package/corpus/templates/slides-2/server/lib/bounded-multipart.ts +49 -0
  1039. package/corpus/templates/slides-2/server/lib/builder-design-system-proxy.ts +122 -0
  1040. package/corpus/templates/slides-2/server/lib/chat-attachments.ts +425 -0
  1041. package/corpus/templates/slides-2/server/lib/chatgpt-directory-tools.ts +246 -0
  1042. package/corpus/templates/slides-2/server/lib/chunked-upload-session.ts +195 -0
  1043. package/corpus/templates/slides-2/server/lib/comment-notifications.ts +184 -0
  1044. package/corpus/templates/slides-2/server/lib/deck-access-requests.ts +102 -0
  1045. package/corpus/templates/slides-2/server/lib/deck-asset-scope.ts +150 -0
  1046. package/corpus/templates/slides-2/server/lib/deck-export-tracking.ts +119 -0
  1047. package/corpus/templates/slides-2/server/lib/deck-templates/a-case-study.ts +154 -0
  1048. package/corpus/templates/slides-2/server/lib/deck-templates/a-company.ts +160 -0
  1049. package/corpus/templates/slides-2/server/lib/deck-templates/a-pitch.ts +151 -0
  1050. package/corpus/templates/slides-2/server/lib/deck-templates/a-quarterly.ts +264 -0
  1051. package/corpus/templates/slides-2/server/lib/deck-templates/a-shared.ts +35 -0
  1052. package/corpus/templates/slides-2/server/lib/deck-templates/a-update.ts +188 -0
  1053. package/corpus/templates/slides-2/server/lib/deck-templates/a-workshop.ts +196 -0
  1054. package/corpus/templates/slides-2/server/lib/deck-templates/b-keynote.ts +131 -0
  1055. package/corpus/templates/slides-2/server/lib/deck-templates/b-lesson.ts +209 -0
  1056. package/corpus/templates/slides-2/server/lib/deck-templates/b-manifesto.ts +149 -0
  1057. package/corpus/templates/slides-2/server/lib/deck-templates/b-portfolio.ts +144 -0
  1058. package/corpus/templates/slides-2/server/lib/deck-templates/b-research.ts +221 -0
  1059. package/corpus/templates/slides-2/server/lib/deck-templates/b-roadmap.ts +264 -0
  1060. package/corpus/templates/slides-2/server/lib/deck-templates/b-shared.ts +44 -0
  1061. package/corpus/templates/slides-2/server/lib/deck-templates/group-a.ts +16 -0
  1062. package/corpus/templates/slides-2/server/lib/deck-templates/group-b.ts +16 -0
  1063. package/corpus/templates/slides-2/server/lib/deck-templates/legacy.ts +567 -0
  1064. package/corpus/templates/slides-2/server/lib/deck-templates.ts +60 -0
  1065. package/corpus/templates/slides-2/server/lib/deck-versions.ts +233 -0
  1066. package/corpus/templates/slides-2/server/lib/design-system-workflows.ts +22 -0
  1067. package/corpus/templates/slides-2/server/lib/emails.ts +84 -0
  1068. package/corpus/templates/slides-2/server/lib/env-config.ts +15 -0
  1069. package/corpus/templates/slides-2/server/lib/fetch-remote-image.ts +245 -0
  1070. package/corpus/templates/slides-2/server/lib/generation-completion.ts +278 -0
  1071. package/corpus/templates/slides-2/server/lib/google-docs-access.ts +51 -0
  1072. package/corpus/templates/slides-2/server/lib/google-docs-error.ts +54 -0
  1073. package/corpus/templates/slides-2/server/lib/google-docs-oauth.ts +422 -0
  1074. package/corpus/templates/slides-2/server/lib/google-fonts.ts +509 -0
  1075. package/corpus/templates/slides-2/server/lib/google-oauth-preflight.ts +119 -0
  1076. package/corpus/templates/slides-2/server/lib/google-slides-export-availability.ts +55 -0
  1077. package/corpus/templates/slides-2/server/lib/image-proxy-response.ts +16 -0
  1078. package/corpus/templates/slides-2/server/lib/image-proxy-url.ts +155 -0
  1079. package/corpus/templates/slides-2/server/lib/import-asset-storage.ts +214 -0
  1080. package/corpus/templates/slides-2/server/lib/imported-asset-batch.ts +218 -0
  1081. package/corpus/templates/slides-2/server/lib/legacy-slide-source.ts +692 -0
  1082. package/corpus/templates/slides-2/server/lib/media-search-providers.ts +216 -0
  1083. package/corpus/templates/slides-2/server/lib/native-creative-context.ts +295 -0
  1084. package/corpus/templates/slides-2/server/lib/pdf-parse-setup.ts +115 -0
  1085. package/corpus/templates/slides-2/server/lib/provider-api.ts +57 -0
  1086. package/corpus/templates/slides-2/server/lib/request-wait-until.ts +30 -0
  1087. package/corpus/templates/slides-2/server/lib/shared-deck.ts +29 -0
  1088. package/corpus/templates/slides-2/server/lib/slide-asset-references.ts +309 -0
  1089. package/corpus/templates/slides-2/server/lib/slide-content-patch.ts +1004 -0
  1090. package/corpus/templates/slides-2/server/lib/slide-hygiene.ts +731 -0
  1091. package/corpus/templates/slides-2/server/lib/slide-image-insertion.ts +136 -0
  1092. package/corpus/templates/slides-2/server/lib/slide-reveal-issues.ts +41 -0
  1093. package/corpus/templates/slides-2/server/lib/slide-source-editing/babel-walk.ts +117 -0
  1094. package/corpus/templates/slides-2/server/lib/slide-source-editing/batch-edit.ts +152 -0
  1095. package/corpus/templates/slides-2/server/lib/slide-source-editing/edit-ops.ts +1478 -0
  1096. package/corpus/templates/slides-2/server/lib/slide-source-editing/image-target.ts +128 -0
  1097. package/corpus/templates/slides-2/server/lib/slide-source-editing/text-diff.ts +23 -0
  1098. package/corpus/templates/slides-2/server/lib/slide-source-limits.ts +9 -0
  1099. package/corpus/templates/slides-2/server/lib/slide-source.ts +1786 -0
  1100. package/corpus/templates/slides-2/server/lib/slide-theme-demo-sources.ts +2106 -0
  1101. package/corpus/templates/slides-2/server/lib/slide-themes.ts +2174 -0
  1102. package/corpus/templates/slides-2/server/lib/slide-worker-runtime.ts +1995 -0
  1103. package/corpus/templates/slides-2/server/lib/slides-tracking.ts +73 -0
  1104. package/corpus/templates/slides-2/server/lib/source-import.ts +213 -0
  1105. package/corpus/templates/slides-2/server/lib/svgl.ts +364 -0
  1106. package/corpus/templates/slides-2/server/lib/tenant-files.ts +179 -0
  1107. package/corpus/templates/slides-2/server/lib/upload-storage-status.ts +9 -0
  1108. package/corpus/templates/slides-2/server/lib/uploaded-asset-cleanup-outbox.ts +521 -0
  1109. package/corpus/templates/slides-2/server/lib/uploaded-asset-object-lifecycle.ts +404 -0
  1110. package/corpus/templates/slides-2/server/lib/uploaded-fonts.ts +696 -0
  1111. package/corpus/templates/slides-2/server/lib/uploaded-reference-storage.ts +77 -0
  1112. package/corpus/templates/slides-2/server/lib/validate-slide-animations.ts +341 -0
  1113. package/corpus/templates/slides-2/server/middleware/auth.ts +6 -0
  1114. package/corpus/templates/slides-2/server/plugins/_dev-upload-stub.ts +6 -0
  1115. package/corpus/templates/slides-2/server/plugins/agent-chat.ts +402 -0
  1116. package/corpus/templates/slides-2/server/plugins/auth.ts +31 -0
  1117. package/corpus/templates/slides-2/server/plugins/collab.ts +30 -0
  1118. package/corpus/templates/slides-2/server/plugins/config.ts +6 -0
  1119. package/corpus/templates/slides-2/server/plugins/core-routes.ts +30 -0
  1120. package/corpus/templates/slides-2/server/plugins/creative-context.ts +187 -0
  1121. package/corpus/templates/slides-2/server/plugins/db.ts +462 -0
  1122. package/corpus/templates/slides-2/server/plugins/feature-flags.ts +5 -0
  1123. package/corpus/templates/slides-2/server/plugins/labs.ts +8 -0
  1124. package/corpus/templates/slides-2/server/plugins/orphaned-asset-cleanup.ts +17 -0
  1125. package/corpus/templates/slides-2/server/plugins/otel.ts +6 -0
  1126. package/corpus/templates/slides-2/server/plugins/transactional-emails.ts +5 -0
  1127. package/corpus/templates/slides-2/server/register-secrets.ts +209 -0
  1128. package/corpus/templates/slides-2/server/routes/[...page].get.ts +5 -0
  1129. package/corpus/templates/slides-2/server/routes/[...page].head.ts +1 -0
  1130. package/corpus/templates/slides-2/server/routes/[base]/_agent-native/google-docs/auth-url.get.ts +1 -0
  1131. package/corpus/templates/slides-2/server/routes/[base]/_agent-native/google-docs/callback.get.ts +1 -0
  1132. package/corpus/templates/slides-2/server/routes/_agent-native/google-docs/auth-url.get.ts +1 -0
  1133. package/corpus/templates/slides-2/server/routes/_agent-native/google-docs/callback.get.ts +1 -0
  1134. package/corpus/templates/slides-2/server/routes/api/assets/upload-video.post.ts +1 -0
  1135. package/corpus/templates/slides-2/server/routes/api/assets/upload.post.ts +1 -0
  1136. package/corpus/templates/slides-2/server/routes/api/assets/video-uploads.delete.ts +1 -0
  1137. package/corpus/templates/slides-2/server/routes/api/deck-agent-context.json.get.ts +105 -0
  1138. package/corpus/templates/slides-2/server/routes/api/decks/events.get.ts +1 -0
  1139. package/corpus/templates/slides-2/server/routes/api/demo.get.ts +1 -0
  1140. package/corpus/templates/slides-2/server/routes/api/exports/[filename].get.ts +221 -0
  1141. package/corpus/templates/slides-2/server/routes/api/exports/google-slides.post.ts +240 -0
  1142. package/corpus/templates/slides-2/server/routes/api/exports/html.post.ts +67 -0
  1143. package/corpus/templates/slides-2/server/routes/api/exports/pptx.post.ts +100 -0
  1144. package/corpus/templates/slides-2/server/routes/api/gen-preview/[...].get.ts +24 -0
  1145. package/corpus/templates/slides-2/server/routes/api/generated/[...].get.ts +24 -0
  1146. package/corpus/templates/slides-2/server/routes/api/image-proxy.get.ts +518 -0
  1147. package/corpus/templates/slides-2/server/routes/api/import-assets/[token].get.ts +70 -0
  1148. package/corpus/templates/slides-2/server/routes/api/preview-images.get.ts +20 -0
  1149. package/corpus/templates/slides-2/server/routes/api/share/[token].get.ts +1 -0
  1150. package/corpus/templates/slides-2/server/routes/api/uploads-chunked/[sessionId]/chunk.post.ts +1 -0
  1151. package/corpus/templates/slides-2/server/routes/api/uploads-chunked/[sessionId]/status.get.ts +1 -0
  1152. package/corpus/templates/slides-2/server/routes/api/uploads-chunked/[sessionId].delete.ts +1 -0
  1153. package/corpus/templates/slides-2/server/routes/api/uploads-chunked/start.post.ts +1 -0
  1154. package/corpus/templates/slides-2/server/routes/api/uploads.delete.ts +1 -0
  1155. package/corpus/templates/slides-2/server/routes/api/uploads.post.ts +1 -0
  1156. package/corpus/templates/slides-2/server/workspace-defaults.ts +196 -0
  1157. package/corpus/templates/slides-2/shared/action-ui.ts +147 -0
  1158. package/corpus/templates/slides-2/shared/agent-readable.ts +2 -0
  1159. package/corpus/templates/slides-2/shared/api.ts +406 -0
  1160. package/corpus/templates/slides-2/shared/app-state-tabs.ts +30 -0
  1161. package/corpus/templates/slides-2/shared/app-storage.ts +9 -0
  1162. package/corpus/templates/slides-2/shared/aspect-ratios.ts +49 -0
  1163. package/corpus/templates/slides-2/shared/blank-slide.ts +179 -0
  1164. package/corpus/templates/slides-2/shared/client-compatibility.ts +2 -0
  1165. package/corpus/templates/slides-2/shared/contrast-audit.ts +255 -0
  1166. package/corpus/templates/slides-2/shared/deck-access.ts +26 -0
  1167. package/corpus/templates/slides-2/shared/deck-app-scope.ts +14 -0
  1168. package/corpus/templates/slides-2/shared/deck-content.ts +37 -0
  1169. package/corpus/templates/slides-2/shared/deck-history-control.ts +79 -0
  1170. package/corpus/templates/slides-2/shared/deck-scope.ts +5 -0
  1171. package/corpus/templates/slides-2/shared/deck-title.ts +199 -0
  1172. package/corpus/templates/slides-2/shared/deck-write.ts +61 -0
  1173. package/corpus/templates/slides-2/shared/design-flags.ts +7 -0
  1174. package/corpus/templates/slides-2/shared/design-system-validation.ts +88 -0
  1175. package/corpus/templates/slides-2/shared/editor-control.ts +120 -0
  1176. package/corpus/templates/slides-2/shared/generation-timing.ts +19 -0
  1177. package/corpus/templates/slides-2/shared/google-docs.ts +69 -0
  1178. package/corpus/templates/slides-2/shared/labs.ts +10 -0
  1179. package/corpus/templates/slides-2/shared/overview-navigation.ts +34 -0
  1180. package/corpus/templates/slides-2/shared/ownership.ts +6 -0
  1181. package/corpus/templates/slides-2/shared/pdf-sidecar.ts +130 -0
  1182. package/corpus/templates/slides-2/shared/presenter-control.ts +111 -0
  1183. package/corpus/templates/slides-2/shared/representative-slide.ts +89 -0
  1184. package/corpus/templates/slides-2/shared/slide-background.ts +30 -0
  1185. package/corpus/templates/slides-2/shared/slide-comment-anchor.ts +117 -0
  1186. package/corpus/templates/slides-2/shared/slide-comment-reactions.ts +47 -0
  1187. package/corpus/templates/slides-2/shared/slide-design-tokens.ts +92 -0
  1188. package/corpus/templates/slides-2/shared/slide-fit.ts +78 -0
  1189. package/corpus/templates/slides-2/shared/slide-ids.ts +133 -0
  1190. package/corpus/templates/slides-2/shared/slide-number.ts +124 -0
  1191. package/corpus/templates/slides-2/shared/slide-object-structure.ts +790 -0
  1192. package/corpus/templates/slides-2/shared/slide-text-range-selection.ts +50 -0
  1193. package/corpus/templates/slides-2/shared/slide-transitions.ts +70 -0
  1194. package/corpus/templates/slides-2/shared/slides-2-transition.ts +194 -0
  1195. package/corpus/templates/slides-2/shared/slides-user-prefs.ts +22 -0
  1196. package/corpus/templates/slides-2/shared/source-import-errors.ts +12 -0
  1197. package/corpus/templates/slides-2/shared/source-runtime-export.ts +76 -0
  1198. package/corpus/templates/slides-2/shared/upload-types.ts +41 -0
  1199. package/corpus/templates/slides-2/ssr-entry.ts +11 -0
  1200. package/corpus/templates/slides-2/tsconfig.json +27 -0
  1201. package/corpus/templates/slides-2/vite.config.ts +77 -0
  1202. package/corpus/templates/slides-2/vitest.config.ts +28 -0
  1203. package/corpus/templates/tasks/.agents/skills/actions/references/action-fields.md +1 -1
  1204. package/package.json +1 -1
  1205. package/corpus/templates/design/.agents/skills/shader-fills/SKILL.md +0 -182
  1206. package/corpus/templates/design/actions/apply-shader-fill.ts +0 -450
  1207. package/corpus/templates/design/actions/apply-shader.ts +0 -257
  1208. package/corpus/templates/design/actions/preview-shader-fill.ts +0 -157
  1209. package/corpus/templates/design/app/components/design/inspector/GlslShaderPanel.tsx +0 -1144
  1210. package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +0 -450
  1211. package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +0 -71
  1212. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +0 -555
  1213. package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +0 -105
  1214. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +0 -433
  1215. package/corpus/templates/design/app/components/design/inspector/color-picker-shader-pane.tsx +0 -648
  1216. package/corpus/templates/design/shared/shader-fill.ts +0 -174
  1217. package/corpus/templates/design/shared/shader-presets.ts +0 -1523
@@ -0,0 +1,2174 @@
1
+ export type BuiltInSlideThemeMode = "light" | "dark";
2
+
3
+ export interface BuiltInSlideThemeSummary {
4
+ id: string;
5
+ name: string;
6
+ description: string;
7
+ mode: BuiltInSlideThemeMode;
8
+ preview: {
9
+ background: string;
10
+ text: string;
11
+ accent: string;
12
+ };
13
+ }
14
+
15
+ export interface BuiltInSlideTheme extends BuiltInSlideThemeSummary {
16
+ guide: string;
17
+ }
18
+
19
+ const themes = [
20
+ {
21
+ id: "aero",
22
+ name: "Aero",
23
+ description:
24
+ "Kinetic sports-launch deck \u2014 electric violet, volt accent, italic condensed caps, every edge cut on one 12\u00b0 angle.",
25
+ mode: "dark",
26
+ preview: {
27
+ background: "#4B1DFF", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
28
+ text: "#FFFFFF", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
29
+ accent: "#D8FF2E", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
30
+ },
31
+ guide: [
32
+ "# Aero",
33
+ "",
34
+ "## Palette",
35
+ "",
36
+ "Three base colours carry the deck (violet / volt / ink). Everything else is a supporting tint. Volt is the only highlight \u2014 one volt thing per idea, never a volt paragraph.",
37
+ "",
38
+ "| Role | Value | Notes |",
39
+ "| -------- | ------------------------ | --------------------------------------------------------------------------------------- |",
40
+ '| bg | `#4B1DFF` | electric violet ("UV") \u2014 default page, `design.palette.bg` |', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
41
+ "| text | `#FFFFFF` | primary copy on violet and ink |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
42
+ '| accent | `#D8FF2E` | volt \u2014 hero digits, bands, bib + kicker chips, the "target" in every chart |', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
43
+ "| ink | `#0B0A14` | near-black \u2014 text on volt, third page tone, chip / marker fill |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
44
+ "| deep | `#2A0FA3` | deep violet \u2014 streaks, baseline bars, track and start-line blocks on violet |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
45
+ "| muted | `#D3CAFF` | lavender \u2014 secondary copy, labels, axis ticks on violet (`TONES.uv.dim`) |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
46
+ '| coral | `#FF4A3D` | hot accent \u2014 placings ("1st"), record counts, one chip per page at most |', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
47
+ "| foam | `#BBAEFF` | light violet tint for illustration fills only |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
48
+ "| whiteA | `rgba(255,255,255,a)` | `0.6` dim copy on ink \u00b7 `0.22\u20130.36` streaks + rules \u00b7 `0.26` inactive bars \u00b7 `0.12` chip |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
49
+ "| inkA | `rgba(11,10,20,a)` | on volt pages: `0.66` secondary copy \u00b7 `0.7` captions \u00b7 `0.24` inactive bars + rules |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
50
+ "",
51
+ "### Design tokens + tones",
52
+ "",
53
+ "Declare the `design` const so `bg` / `text` / `accent` / fonts / hero size stay tweakable from the Design panel; the rest are plain constants. Every page picks one of three **tones** \u2014 the `TONES` map tells chrome (footer, kicker) which colours to use on that background.",
54
+ "",
55
+ "```tsx",
56
+ "export const design: DesignSystem = {",
57
+ " palette: { bg: '#4B1DFF', text: '#FFFFFF', accent: '#D8FF2E' },", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
58
+ " fonts: {",
59
+ ' display: \'"Barlow Condensed", "Arial Narrow", system-ui, sans-serif\',',
60
+ " body: '\"Barlow\", system-ui, sans-serif',",
61
+ " },",
62
+ " typeScale: { hero: 620, body: 30 },",
63
+ " radius: 0,",
64
+ "};",
65
+ "",
66
+ "const INK = '#0B0A14';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
67
+ "const CORAL = '#FF4A3D';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
68
+ "const DEEP = '#2A0FA3';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
69
+ "const LAV = '#D3CAFF';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
70
+ "const WHITE_A = (a: number) => `rgba(255,255,255,${a})`;", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
71
+ "const INK_A = (a: number) => `rgba(11,10,20,${a})`;", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
72
+ "",
73
+ "type Tone = 'uv' | 'volt' | 'ink';",
74
+ "",
75
+ "const TONES: Record<Tone, { bg: string; fg: string; dim: string; hi: string; hiFg: string }> = {",
76
+ " uv: { bg: 'var(--slides2-bg)', fg: 'var(--slides2-text)', dim: LAV, hi: 'var(--slides2-accent)', hiFg: INK },",
77
+ " volt: {",
78
+ " bg: 'var(--slides2-accent)',",
79
+ " fg: INK,",
80
+ " dim: 'rgba(11,10,20,0.66)',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
81
+ " hi: INK,",
82
+ " hiFg: 'var(--slides2-accent)',",
83
+ " },",
84
+ " ink: {",
85
+ " bg: INK,",
86
+ " fg: 'var(--slides2-text)',",
87
+ " dim: 'rgba(255,255,255,0.6)',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
88
+ " hi: 'var(--slides2-accent)',",
89
+ " hiFg: INK,",
90
+ " },",
91
+ "};",
92
+ "```",
93
+ "",
94
+ "- `uv` \u2014 default. Violet page, white type, lavender labels, volt highlights.",
95
+ "- `volt` \u2014 inverted: volt page, ink type. Use for lab data, pricing, asks \u2014 the pages that must be read.",
96
+ "- `ink` \u2014 near-black page for results / proof. Coral is most at home here.",
97
+ "",
98
+ "## Typography",
99
+ "",
100
+ '- Display font: `var(--slides2-font-display)` \u2192 `"Barlow Condensed", "Arial Narrow", system-ui, sans-serif` \u2014 **always italic, always uppercase**, weight 900 (800 for secondary numerals), line-height 0.84, letter-spacing -0.012em. Numerals add `tabular-nums` and -0.015em.',
101
+ '- Body font: `var(--slides2-font-body)` \u2192 `"Barlow", system-ui, sans-serif` \u2014 weight 500 for copy; labels are weight 600\u2013700, uppercase, letter-spacing 0.2em.',
102
+ "- Webfont import: `https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,600;1,700;1,800;1,900&family=Barlow:wght@400;500;600;700&display=swap` \u2014 inject once at module top level (snippet under **Foundation** below), per `references/webfonts.md` in `slide-authoring`.",
103
+ "- Type scale (deliberately extreme \u2014 overrides `slide-authoring` defaults):",
104
+ " - Hero title: **620 px** (`var(--slides2-size-hero)`), line-height 0.8, -0.02em, `nowrap` \u2014 one short word + a volt digit (\u2248 6 characters max).",
105
+ " - Section / divider / closer heading: 196\u2013236 px.",
106
+ " - Page heading: 104\u2013150 px (`Title` default 132).",
107
+ " - Hero stat numeral: 280\u2013360 px. Secondary numerals: 84\u2013150 px. Inline / row numerals: 40\u2013104 px.",
108
+ " - Band text and card titles: 40\u201392 px display.",
109
+ " - Body text: **30 px**, line-height 1.4 (secondary copy 22\u201326 px).",
110
+ " - Label: 20 px (17\u201324). Footnote / tiny label: 15\u201316 px.",
111
+ " - Footer: 17 px label, 24 px bib numeral.",
112
+ "",
113
+ "## Layout",
114
+ "",
115
+ "- Canvas: 1920 \u00d7 1080, **absolutely positioned** with the `abs(x, y)` helper \u2014 composition is placed, not flowed.",
116
+ "- Left rail `x = 120`, right edge `x = 1800` (content width 1680). Display type sits 4\u20138 px left of the rail (`x = 112\u2013116`, hero at 96) so the italic overhang lines up optically with labels at 120.",
117
+ "- Vertical rhythm: wordmark / kicker row at y \u2248 92\u2013104 \u00b7 heading at y \u2248 156\u2013168 \u00b7 content down to \u2248 960 \u00b7 footer bib at y = 1004 (32 px tall).",
118
+ "- Full-bleed motifs (streaks, bands, start-line stripe) overrun the canvas (`left: -80`, width 2080) so skewed ends never show; `Stage` clips with `overflow: hidden`.",
119
+ "- Radius is 0 everywhere. No rounded corners, no shadows, no gradients.",
120
+ "",
121
+ "### The 12\u00b0 angle system",
122
+ "",
123
+ "One angle drives every slanted edge in the deck \u2014 chips, bars, bands, streaks, rules, chart columns, even SVG hatching. Never introduce a second angle.",
124
+ "",
125
+ "```tsx",
126
+ "const ANGLE = 12;",
127
+ "const T = Math.tan((ANGLE * Math.PI) / 180);",
128
+ "const SKEW = `skewX(-${ANGLE}deg)`;",
129
+ "",
130
+ "const cut = (h: number) => {",
131
+ " const d = (h * T).toFixed(2);",
132
+ " return `polygon(${d}px 0, 100% 0, calc(100% - ${d}px) 100%, 0 100%)`;",
133
+ "};",
134
+ "",
135
+ "const BAND_RATIO = 12;",
136
+ "const BAND_PCT = ((T / BAND_RATIO) * 100).toFixed(4);",
137
+ "const BAND_CLIP = `polygon(${BAND_PCT}% 0, 100% 0, ${(100 - Number(BAND_PCT)).toFixed(4)}% 100%, 0 100%)`;",
138
+ "```",
139
+ "",
140
+ "- `SKEW` \u2014 for thin things that are *only* slant: streaks, vertical rules, the three-bar mark, spec ticks. Use `transformOrigin: '0 100%'` so the foot stays on its x.",
141
+ "- `cut(h)` \u2014 for filled blocks with upright content inside (chips, bars, ask rows, bib). Pass the element's own pixel height; the clip offset is `h \u00b7 tan 12\u00b0`, so the lean is identical at any height.",
142
+ "- `BAND_CLIP` \u2014 the signature volt band. Its height is always `w / BAND_RATIO`; the clip is percentage-based so the band can scale or morph between pages and keep the angle.",
143
+ "- In SVG charts, offset a bar's top by `h * T` (parallelogram columns), and skew SVG patterns with ``patternTransform={`skewX(-${ANGLE})`}``.",
144
+ "",
145
+ "## Fixed components",
146
+ "",
147
+ "These are paste-ready. Copy them verbatim into a slide that uses this theme. Swap the placeholder brand (`Tempo`) and footer labels for the real ones.",
148
+ "",
149
+ "### Foundation",
150
+ "",
151
+ "Shared type styles, helpers and the module-level webfont + keyframe injection (replace `<slide-id>` with the slide's folder id).",
152
+ "",
153
+ "```tsx",
154
+ "import type { CSSProperties, ReactNode } from 'react';",
155
+ "",
156
+ "const SLIDE_ID = '<slide-id>';",
157
+ "const FONT_HREF =",
158
+ " 'https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,600;1,700;1,800;1,900&family=Barlow:wght@400;500;600;700&display=swap';",
159
+ "const FONT_LINK_ID = `slides2-webfont-${SLIDE_ID}`;",
160
+ "const STYLE_ID = `slides2-styles-${SLIDE_ID}`;",
161
+ "const KEYFRAMES = `",
162
+ "@keyframes ae-run { from { transform: translateX(0) } to { transform: translateX(calc(var(--tile) * -1)) } }",
163
+ "@keyframes ae-in { from { opacity: 0; transform: translateX(-56px) } to { opacity: 1; transform: none } }",
164
+ "@keyframes ae-fade { from { opacity: 0 } to { opacity: 1 } }",
165
+ "@keyframes ae-pace { to { stroke-dashoffset: -1000 } }",
166
+ "`;",
167
+ "",
168
+ "if (typeof document !== 'undefined') {",
169
+ " let link = document.getElementById(FONT_LINK_ID) as HTMLLinkElement | null;",
170
+ " if (!link) {",
171
+ " link = document.createElement('link');",
172
+ " link.id = FONT_LINK_ID;",
173
+ " link.rel = 'stylesheet';",
174
+ " document.head.appendChild(link);",
175
+ " }",
176
+ " if (link.href !== FONT_HREF) link.href = FONT_HREF;",
177
+ "",
178
+ " let style = document.getElementById(STYLE_ID);",
179
+ " if (!style) {",
180
+ " style = document.createElement('style');",
181
+ " style.id = STYLE_ID;",
182
+ " document.head.appendChild(style);",
183
+ " }",
184
+ " if (style.textContent !== KEYFRAMES) style.textContent = KEYFRAMES;",
185
+ "}",
186
+ "",
187
+ "const DISPLAY: CSSProperties = {",
188
+ " fontFamily: 'var(--slides2-font-display)',",
189
+ " fontStyle: 'italic',",
190
+ " fontWeight: 900,",
191
+ " textTransform: 'uppercase',",
192
+ " lineHeight: 0.84,",
193
+ " letterSpacing: '-0.012em',",
194
+ " margin: 0,",
195
+ "};",
196
+ "",
197
+ "const NUM: CSSProperties = {",
198
+ " ...DISPLAY,",
199
+ " fontVariantNumeric: 'tabular-nums',",
200
+ " letterSpacing: '-0.015em',",
201
+ "};",
202
+ "",
203
+ "const LABEL: CSSProperties = {",
204
+ " fontFamily: 'var(--slides2-font-body)',",
205
+ " fontSize: 20,",
206
+ " fontWeight: 600,",
207
+ " letterSpacing: '0.2em',",
208
+ " textTransform: 'uppercase',",
209
+ " lineHeight: 1.2,",
210
+ "};",
211
+ "",
212
+ "const BODY: CSSProperties = {",
213
+ " fontFamily: 'var(--slides2-font-body)',",
214
+ " fontSize: 30,",
215
+ " fontWeight: 500,",
216
+ " lineHeight: 1.4,",
217
+ " margin: 0,",
218
+ "};",
219
+ "",
220
+ "const abs = (left: number, top: number, extra?: CSSProperties): CSSProperties => ({",
221
+ " position: 'absolute',",
222
+ " left,",
223
+ " top,",
224
+ " ...extra,",
225
+ "});",
226
+ "",
227
+ "const pad = (n: number) => String(n).padStart(2, '0');",
228
+ "```",
229
+ "",
230
+ "### Title",
231
+ "",
232
+ "Absolute-placed display heading. `color` inherits from the page tone; pass `style` for entry animation.",
233
+ "",
234
+ "```tsx",
235
+ "const Title = ({",
236
+ " children,",
237
+ " size = 132,",
238
+ " x = 116,",
239
+ " y = 160,",
240
+ " style,",
241
+ "}: {",
242
+ " children: ReactNode;",
243
+ " size?: number;",
244
+ " x?: number;",
245
+ " y?: number;",
246
+ " style?: CSSProperties;",
247
+ "}) => <h2 style={{ ...DISPLAY, ...abs(x, y), fontSize: size, ...style }}>{children}</h2>;",
248
+ "```",
249
+ "",
250
+ "### Footer",
251
+ "",
252
+ "The race bib: page number in a cut volt chip, total beside it, brand + deck title + meta label. Tone-aware via `TONES`. Rendered by `Stage` \u2014 covers, dividers and closers turn it off.",
253
+ "",
254
+ "```tsx",
255
+ "import { useSlidePageNumber } from '@open-slide/core';",
256
+ "",
257
+ "const Footer = ({",
258
+ " tone,",
259
+ " brand = 'Tempo',",
260
+ " title = 'Season plan',",
261
+ " meta = '2027 \u00b7 Confidential',",
262
+ "}: {",
263
+ " tone: Tone;",
264
+ " brand?: string;",
265
+ " title?: string;",
266
+ " meta?: string;",
267
+ "}) => {",
268
+ " const { current, total } = useSlidePageNumber();",
269
+ " const t = TONES[tone];",
270
+ " return (",
271
+ " <div",
272
+ " style={{",
273
+ " ...LABEL,",
274
+ " position: 'absolute',",
275
+ " left: 120,",
276
+ " right: 120,",
277
+ " top: 1004,",
278
+ " height: 32,",
279
+ " display: 'flex',",
280
+ " alignItems: 'center',",
281
+ " gap: 18,",
282
+ " fontSize: 17,",
283
+ " color: t.dim,",
284
+ " zIndex: 5,",
285
+ " }}",
286
+ " >",
287
+ " <span",
288
+ " style={{",
289
+ " ...NUM,",
290
+ " width: 64,",
291
+ " height: 32,",
292
+ " display: 'inline-flex',",
293
+ " alignItems: 'center',",
294
+ " justifyContent: 'center',",
295
+ " background: t.hi,",
296
+ " color: t.hiFg,",
297
+ " clipPath: cut(32),",
298
+ " fontSize: 24,",
299
+ " fontWeight: 800,",
300
+ " lineHeight: 1,",
301
+ " letterSpacing: 0,",
302
+ " }}",
303
+ " >",
304
+ " {pad(current)}",
305
+ " </span>",
306
+ " <span style={{ fontVariantNumeric: 'tabular-nums', marginLeft: -8 }}>/ {pad(total)}</span>",
307
+ " <span style={{ color: t.fg, marginLeft: 14 }}>{brand}</span>",
308
+ " <span>{title}</span>",
309
+ " <span style={{ marginLeft: 'auto' }}>{meta}</span>",
310
+ " </div>",
311
+ " );",
312
+ "};",
313
+ "```",
314
+ "",
315
+ "### Stage",
316
+ "",
317
+ "Every page's root. Sets the tone background + text colour and mounts the footer.",
318
+ "",
319
+ "```tsx",
320
+ "const Stage = ({",
321
+ " tone = 'uv',",
322
+ " footer = true,",
323
+ " children,",
324
+ "}: {",
325
+ " tone?: Tone;",
326
+ " footer?: boolean;",
327
+ " children: ReactNode;",
328
+ "}) => (",
329
+ " <div",
330
+ " style={{",
331
+ " width: '100%',",
332
+ " height: '100%',",
333
+ " position: 'relative',",
334
+ " overflow: 'hidden',",
335
+ " isolation: 'isolate',",
336
+ " background: TONES[tone].bg,",
337
+ " color: TONES[tone].fg,",
338
+ " fontFamily: 'var(--slides2-font-body)',",
339
+ " }}",
340
+ " >",
341
+ " {children}",
342
+ " {footer && <Footer tone={tone} />}",
343
+ " </div>",
344
+ ");",
345
+ "```",
346
+ "",
347
+ "### Eyebrow (Kicker)",
348
+ "",
349
+ "A cut chip with the section tag, followed by the page's subject in label type. Sits top-left at `(120, 104)` on every content page.",
350
+ "",
351
+ "```tsx",
352
+ "const Kicker = ({",
353
+ " tag,",
354
+ " children,",
355
+ " tone = 'uv',",
356
+ " x = 120,",
357
+ " y = 104,",
358
+ "}: {",
359
+ " tag: string;",
360
+ " children: ReactNode;",
361
+ " tone?: Tone;",
362
+ " x?: number;",
363
+ " y?: number;",
364
+ "}) => {",
365
+ " const t = TONES[tone];",
366
+ " return (",
367
+ " <div",
368
+ " style={abs(x, y, { ...LABEL, display: 'flex', alignItems: 'center', gap: 18, color: t.fg })}",
369
+ " >",
370
+ " <span",
371
+ " style={{",
372
+ " ...LABEL,",
373
+ " height: 32,",
374
+ " padding: '0 18px',",
375
+ " display: 'inline-flex',",
376
+ " alignItems: 'center',",
377
+ " background: t.hi,",
378
+ " color: t.hiFg,",
379
+ " clipPath: cut(32),",
380
+ " fontWeight: 700,",
381
+ " fontSize: 17,",
382
+ " }}",
383
+ " >",
384
+ " {tag}",
385
+ " </span>",
386
+ " {children}",
387
+ " </div>",
388
+ " );",
389
+ "};",
390
+ "```",
391
+ "",
392
+ "### Wordmark + Mark",
393
+ "",
394
+ "Three skewed bars stepping down in opacity \u2014 the brand's speed mark. Wordmark at `(120, 92)` on covers and closers; the Mark alone (in ink, `h={64}`) sits inside the volt band.",
395
+ "",
396
+ "```tsx",
397
+ "const Mark = ({ color, h = 34 }: { color: string; h?: number }) => (",
398
+ " <div style={{ display: 'flex', gap: h * 0.16 }}>",
399
+ " <div style={{ width: h * 0.3, height: h, background: color, transform: SKEW }} />",
400
+ " <div style={{ width: h * 0.3, height: h, background: color, transform: SKEW, opacity: 0.7 }} />",
401
+ " <div style={{ width: h * 0.3, height: h, background: color, transform: SKEW, opacity: 0.4 }} />",
402
+ " </div>",
403
+ ");",
404
+ "",
405
+ "const Wordmark = ({",
406
+ " x,",
407
+ " y,",
408
+ " brand = 'Tempo',",
409
+ " color = 'var(--slides2-text)',",
410
+ " mark = 'var(--slides2-accent)',",
411
+ "}: {",
412
+ " x: number;",
413
+ " y: number;",
414
+ " brand?: string;",
415
+ " color?: string;",
416
+ " mark?: string;",
417
+ "}) => (",
418
+ " <div style={abs(x, y, { display: 'flex', alignItems: 'center', gap: 18, zIndex: 4 })}>",
419
+ " <Mark color={mark} />",
420
+ " <span style={{ ...DISPLAY, fontSize: 46, letterSpacing: '0.02em', color, lineHeight: 1 }}>",
421
+ " {brand}",
422
+ " </span>",
423
+ " </div>",
424
+ ");",
425
+ "```",
426
+ "",
427
+ "### Streak",
428
+ "",
429
+ "A skewed, dashed speed line that loops sideways. Stack 8\u201312 on a cover in `deep` (thick, slow) and `WHITE_A(0.22\u20130.36)` (hairline, fast). `live` comes from `useIsActivePage()`.",
430
+ "",
431
+ "```tsx",
432
+ "const Streak = ({",
433
+ " y,",
434
+ " h,",
435
+ " tile,",
436
+ " dash,",
437
+ " color,",
438
+ " dur,",
439
+ " shift = 0,",
440
+ " live,",
441
+ "}: {",
442
+ " y: number;",
443
+ " h: number;",
444
+ " tile: number;",
445
+ " dash: number;",
446
+ " color: string;",
447
+ " dur: number;",
448
+ " shift?: number;",
449
+ " live: boolean;",
450
+ "}) => (",
451
+ " <div",
452
+ " style={{",
453
+ " position: 'absolute',",
454
+ " left: -80,",
455
+ " top: y,",
456
+ " width: 2080,",
457
+ " height: h,",
458
+ " overflow: 'hidden',",
459
+ " transform: SKEW,",
460
+ " }}",
461
+ " >",
462
+ " <div",
463
+ " style={",
464
+ " {",
465
+ " '--tile': `${tile}px`,",
466
+ " width: 2080 + tile,",
467
+ " height: h,",
468
+ " backgroundImage: `linear-gradient(90deg, ${color} 0 ${dash}px, transparent ${dash}px)`,",
469
+ " backgroundSize: `${tile}px ${h}px`,",
470
+ " backgroundRepeat: 'repeat-x',",
471
+ " backgroundPosition: `${shift}px 0`,",
472
+ " animation: live ? `ae-run ${dur}s linear infinite` : undefined,",
473
+ " } as CSSProperties",
474
+ " }",
475
+ " />",
476
+ " </div>",
477
+ ");",
478
+ "```",
479
+ "",
480
+ "### VoltBand",
481
+ "",
482
+ 'The signature skewed band \u2014 the "one line" of the deck. Put band text over it in ink. For a cover-to-page morph, wrap it in `<MorphElement id="volt-band">` (see Motion).',
483
+ "",
484
+ "```tsx",
485
+ "const VoltBand = ({ x, y, w }: { x: number; y: number; w: number }) => (",
486
+ " <div",
487
+ " style={{",
488
+ " position: 'absolute',",
489
+ " left: x,",
490
+ " top: y,",
491
+ " width: w,",
492
+ " height: w / BAND_RATIO,",
493
+ " background: 'var(--slides2-accent)',",
494
+ " clipPath: BAND_CLIP,",
495
+ " }}",
496
+ " />",
497
+ ");",
498
+ "```",
499
+ "",
500
+ "### CutBar, SkewRule, Chip, SpecChip",
501
+ "",
502
+ "Data bars, column dividers, tags and inline spec ticks \u2014 all on the 12\u00b0 angle.",
503
+ "",
504
+ "```tsx",
505
+ "const CutBar = ({",
506
+ " x,",
507
+ " y,",
508
+ " w,",
509
+ " h,",
510
+ " color,",
511
+ "}: {",
512
+ " x: number;",
513
+ " y: number;",
514
+ " w: number;",
515
+ " h: number;",
516
+ " color: string;",
517
+ "}) => (",
518
+ " <div",
519
+ " style={{",
520
+ " position: 'absolute',",
521
+ " left: x,",
522
+ " top: y,",
523
+ " width: w,",
524
+ " height: h,",
525
+ " background: color,",
526
+ " clipPath: cut(h),",
527
+ " }}",
528
+ " />",
529
+ ");",
530
+ "",
531
+ "const SkewRule = ({",
532
+ " x,",
533
+ " y,",
534
+ " h,",
535
+ " w = 6,",
536
+ " color = 'var(--slides2-accent)',",
537
+ "}: {",
538
+ " x: number;",
539
+ " y: number;",
540
+ " h: number;",
541
+ " w?: number;",
542
+ " color?: string;",
543
+ "}) => (",
544
+ " <div",
545
+ " style={abs(x, y, {",
546
+ " width: w,",
547
+ " height: h,",
548
+ " background: color,",
549
+ " transform: SKEW,",
550
+ " transformOrigin: '0 100%',",
551
+ " })}",
552
+ " />",
553
+ ");",
554
+ "",
555
+ "const Chip = ({",
556
+ " children,",
557
+ " bg = CORAL,",
558
+ " fg = INK,",
559
+ " h = 34,",
560
+ "}: {",
561
+ " children: ReactNode;",
562
+ " bg?: string;",
563
+ " fg?: string;",
564
+ " h?: number;",
565
+ "}) => (",
566
+ " <span",
567
+ " style={{",
568
+ " ...LABEL,",
569
+ " fontSize: 18,",
570
+ " fontWeight: 700,",
571
+ " letterSpacing: '0.14em',",
572
+ " height: h,",
573
+ " padding: '0 16px',",
574
+ " display: 'inline-flex',",
575
+ " alignItems: 'center',",
576
+ " background: bg,",
577
+ " color: fg,",
578
+ " clipPath: cut(h),",
579
+ " }}",
580
+ " >",
581
+ " {children}",
582
+ " </span>",
583
+ ");",
584
+ "",
585
+ "const SpecChip = ({ children }: { children: ReactNode }) => (",
586
+ " <span style={{ display: 'inline-flex', alignItems: 'center', gap: 22 }}>",
587
+ " <span style={{ width: 4, height: 22, background: 'var(--slides2-accent)', transform: SKEW }} />",
588
+ " {children}",
589
+ " </span>",
590
+ ");",
591
+ "```",
592
+ "",
593
+ '- `CutBar` \u2014 horizontal data bar; `deep` for baseline, `VoltBand` (or volt `CutBar`) for the target, `INK_A(0.24)` for "category average" on volt pages.',
594
+ "- `SkewRule` \u2014 6 px volt divider between hero stats; 3 px `WHITE_A(0.3)` for split / table columns.",
595
+ '- `Chip` \u2014 coral by default for placings and callouts; `bg={WHITE_A(0.12)} fg="#FFFFFF"` for neutral codes (country, size).', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
596
+ "- `SpecChip` \u2014 the spec row under a cover band: a plain first item, then each following spec led by a skewed volt tick (`4 drops`, `<SpecChip>38 markets</SpecChip>`, \u2026).",
597
+ "",
598
+ "## Motion",
599
+ "",
600
+ "- Philosophy: **rich, but only where it means speed.** Covers, dividers and closers move (looping streaks, a snap-in hero, a pace light running a track); content pages hold still apart from `<Steps>` reveals and one morph. Every move is horizontal and travels left \u2192 right. Gate all animation on `useIsActivePage()` so thumbnails, the overview grid and PDF render the final frame.",
601
+ "- Reusable keyframes (already in the Foundation `KEYFRAMES` string):",
602
+ "",
603
+ "```css",
604
+ "@keyframes ae-run { from { transform: translateX(0) } to { transform: translateX(calc(var(--tile) * -1)) } }",
605
+ "@keyframes ae-in { from { opacity: 0; transform: translateX(-56px) } to { opacity: 1; transform: none } }",
606
+ "@keyframes ae-fade { from { opacity: 0 } to { opacity: 1 } }",
607
+ "@keyframes ae-pace { to { stroke-dashoffset: -1000 } }",
608
+ "```",
609
+ "",
610
+ "- `ae-run` \u2014 `Streak` loops, 1.3\u20134.2 s linear infinite; thinner streaks run faster.",
611
+ "- `ae-in` \u2014 hero and headline entries: `ae-in 0.8s ${SNAP} ${delay}s both`, staggered 0.05 s \u2192 0.18 s.",
612
+ "- `ae-fade` \u2014 content that lands on a bar after a morph: `ae-fade 0.45s ease-out ${MORPH_MS}ms both`.",
613
+ "- `ae-pace` \u2014 a white dash running along an SVG path (`pathLength={1000}`, `strokeDasharray: '22 228'`, 9 s linear infinite).",
614
+ "",
615
+ "Easing + page transitions \u2014 a fast 240 ms nudge in the direction of travel; the outgoing page holds while the new one lands:",
616
+ "",
617
+ "```tsx",
618
+ "import { type SlideTransition } from '@open-slide/core';",
619
+ "",
620
+ "const EASE_OUT = 'cubic-bezier(0, 0, 0.2, 1)';",
621
+ "const EASE_IN = 'cubic-bezier(0.4, 0, 1, 1)';",
622
+ "const SNAP = 'cubic-bezier(0.16, 1, 0.3, 1)';",
623
+ "const HOLD: Keyframe[] = [{ opacity: 1 }, { opacity: 1 }];",
624
+ "const MORPH_MS = 860;",
625
+ "",
626
+ "export const transition: SlideTransition = {",
627
+ " duration: 240,",
628
+ " exit: { duration: 240, easing: EASE_IN, keyframes: HOLD },",
629
+ " enter: {",
630
+ " duration: 240,",
631
+ " easing: EASE_OUT,",
632
+ " keyframes: [",
633
+ " { opacity: 0, transform: 'translateX(calc(var(--slides2-dir, 1) * 10px))' },",
634
+ " { opacity: 1, transform: 'translateX(0)' },",
635
+ " ],",
636
+ " },",
637
+ "};",
638
+ "",
639
+ "const morphTransition: SlideTransition = {",
640
+ " duration: 300,",
641
+ " exit: { duration: 320, easing: EASE_IN, keyframes: HOLD },",
642
+ " enter: { duration: 320, easing: EASE_OUT, keyframes: [{ opacity: 0 }, { opacity: 1 }] },",
643
+ " morph: { duration: MORPH_MS, easing: 'cubic-bezier(0.65, 0, 0.25, 1)' },",
644
+ "};",
645
+ "```",
646
+ "",
647
+ 'The signature move: the cover\'s full-width `VoltBand` morphs into the "target" bar on the next page (wrap both in `<MorphElement id="volt-band">`, set `Cover.transition = morphTransition` and the same on the receiving page).',
648
+ "",
649
+ "## Aesthetic",
650
+ "",
651
+ "Kinetic sports launch \u2014 the visual language of a race-day campaign: electric violet like a stadium at night, a single volt line you can follow across the whole deck, numbers set huge in italic condensed caps the way a bib or a finish clock would set them. Everything leans forward on the same 12\u00b0 angle, so even a static page feels like it's moving left to right. Composition is placed, not flowed: big numerals carry the page and copy stays short. Hold the discipline \u2014 one highlight colour, one angle, one display face. Avoid: rounded corners, drop shadows, gradients, glows, photography that fights the flat colour, upright (non-italic) display type, sentence-case headlines, a second slant angle, and more than one coral element per page.",
652
+ "",
653
+ "## Example usage",
654
+ "",
655
+ "```tsx",
656
+ "const Cover: Page = () => {",
657
+ " const live = useIsActivePage();",
658
+ " const enter = (delay: number): CSSProperties =>",
659
+ " live ? { animation: `ae-in 0.8s ${SNAP} ${delay}s both` } : {};",
660
+ " return (",
661
+ " <Stage footer={false}>",
662
+ " <Streak y={236} h={16} tile={920} dash={560} color={DEEP} dur={3.4} shift={-300} live={live} />",
663
+ " <Streak y={462} h={3} tile={340} dash={120} color={WHITE_A(0.3)} dur={1.5} live={live} />",
664
+ " <Wordmark x={120} y={92} />",
665
+ " <h1",
666
+ " style={{",
667
+ " ...DISPLAY,",
668
+ " ...abs(96, 156),",
669
+ " fontSize: 'var(--slides2-size-hero)',",
670
+ " lineHeight: 0.8,",
671
+ " letterSpacing: '-0.02em',",
672
+ " whiteSpace: 'nowrap',",
673
+ " ...enter(0.05),",
674
+ " }}",
675
+ " >",
676
+ " Run <span style={{ color: 'var(--slides2-accent)' }}>27</span>",
677
+ " </h1>",
678
+ " <VoltBand x={60} y={700} w={1800} />",
679
+ " <div",
680
+ " style={abs(196, 700, {",
681
+ " height: 150,",
682
+ " width: 1528,",
683
+ " display: 'flex',",
684
+ " alignItems: 'center',",
685
+ " justifyContent: 'space-between',",
686
+ " color: INK,",
687
+ " ...enter(0.18),",
688
+ " })}",
689
+ " >",
690
+ " <span style={{ ...DISPLAY, fontSize: 92, lineHeight: 1 }}>Season plan</span>",
691
+ " <Mark color={INK} h={64} />",
692
+ " <span style={{ ...NUM, fontSize: 92, lineHeight: 1 }}>Spring 2027</span>",
693
+ " </div>",
694
+ " </Stage>",
695
+ " );",
696
+ "};",
697
+ "",
698
+ "const Results: Page = () => (",
699
+ ' <Stage tone="volt">',
700
+ ' <Kicker tag="Lab" tone="volt">',
701
+ " Lab results",
702
+ " </Kicker>",
703
+ " <Title size={104}>The lab says faster.</Title>",
704
+ " <div style={abs(120, 320)}>",
705
+ " <div style={{ ...LABEL, fontSize: 18, fontWeight: 700 }}>Running economy</div>",
706
+ " <div style={{ ...NUM, fontSize: 132, marginTop: 10 }}>+4.1%</div>",
707
+ " <p style={{ ...BODY, fontSize: 22, color: INK_A(0.7), marginTop: 6 }}>",
708
+ " Less oxygen at the same pace vs last season.",
709
+ " </p>",
710
+ " </div>",
711
+ ' <CutBar x={760} y={340} w={655} h={44} color="var(--slides2-bg)" />',
712
+ " <CutBar x={760} y={396} w={266} h={44} color={INK} />",
713
+ " <CutBar x={760} y={452} w={380} h={44} color={INK_A(0.24)} />",
714
+ " </Stage>",
715
+ ");",
716
+ "```",
717
+ ].join("\n"),
718
+ },
719
+ {
720
+ id: "fieldwork",
721
+ name: "Fieldwork",
722
+ description:
723
+ "Notion-style operating plan \u2014 warm off-white page, heavy Inter headlines, Newsreader italic quotes, wobbly ink illustrations, pastel tinted cards and coral hand-drawn annotations.",
724
+ mode: "light",
725
+ preview: {
726
+ background: "#FFFEFC", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
727
+ text: "#191919", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
728
+ accent: "#E8553B", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
729
+ },
730
+ guide: [
731
+ "# Fieldwork",
732
+ "",
733
+ "## Palette",
734
+ "",
735
+ "Ink and coral carry the page. The four pastels fill illustrations; their paler tints fill cards. Use coral for one thing per page \u2014 the eyebrow, a circled number, an arrow, a miss.",
736
+ "",
737
+ "| Role | Value | Notes |",
738
+ "| ----------- | ---------------------- | -------------------------------------------------------- |",
739
+ "| bg | `#FFFEFC` | warm off-white page |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
740
+ "| text | `#191919` | ink \u2014 headlines, strokes, primary copy |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
741
+ "| accent | `#E8553B` | coral \u2014 eyebrow, annotations, circled numbers, misses |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
742
+ "| body | `#5F5E5B` | warm grey body copy and subtitles |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
743
+ '| muted | `#9B9A97` | captions, footer, card index, the "from" in from \u2192 to |', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
744
+ "| rule | `rgba(25,25,25,0.12)` | 1.5 px hairlines between rows |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
745
+ "| track | `rgba(25,25,25,0.09)` | progress-bar track |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
746
+ '| neutral | `#E7E5E0` | "previous period" bars in charts |', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
747
+ "| paper | `#FFFFFF` | fill inside ink drawings (phones, pages, faces) |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
748
+ "| yellow | `#F8DA7E` | illustration fill, sparkles, backdrop circles |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
749
+ "| blue | `#8DBDEB` | illustration fill |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
750
+ "| pink | `#F6C3CF` | illustration fill |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
751
+ "| green | `#A6D4B2` | illustration fill |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
752
+ "| highlight | `#FCE38A` | marker highlight behind a phrase (alt: `#FADDE4` pink) |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
753
+ "| tintYellow | `#FBF3DB` | card background |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
754
+ "| tintBlue | `#E7F3F8` | card background |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
755
+ "| tintPink | `#FAF1F5` | card background |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
756
+ "| tintGreen | `#EDF3EC` | card background |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
757
+ "| ok | `#448361` | status text \u2014 on track |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
758
+ "| warn | `#B07A12` | status text \u2014 medium risk |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
759
+ '| note | `#3E7FCF` | secondary annotation stroke / "watch" status |', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
760
+ "",
761
+ "Tweakable tokens for a real slide (headlines read `var(--slides2-font-display)`, hero size reads `var(--slides2-size-hero)`):",
762
+ "",
763
+ "```tsx",
764
+ "export const design: DesignSystem = {",
765
+ " palette: { bg: '#FFFEFC', text: '#191919', accent: '#E8553B' },", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
766
+ " fonts: {",
767
+ ' display: \'"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif\',',
768
+ ' body: \'"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif\',',
769
+ " },",
770
+ " typeScale: { hero: 150, body: 34 },",
771
+ " radius: 24,",
772
+ "};",
773
+ "```",
774
+ "",
775
+ "## Typography",
776
+ "",
777
+ '- Display font: `"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif` \u2014 weight 780, line-height 1.0, letter-spacing `-0.04em` at \u2265 100 px and `-0.03em` below, word-spacing `0.08em`.',
778
+ "- Body font: same Inter stack \u2014 weight 400; 600\u2013720 for labels and inline emphasis. Set `fontVariantNumeric: 'tabular-nums'` on the page root.",
779
+ '- Quote font: `"Newsreader", "Iowan Old Style", Georgia, serif` \u2014 italic 400, only for pull quotes.',
780
+ "- Webfont import: `https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400..800&family=Newsreader:ital,opsz,wght@1,6..72,400&display=swap` \u2014 inject once at module top level with a slide-keyed link id (see `references/webfonts.md` in `slide-authoring`).",
781
+ "- Type scale:",
782
+ " - Hero title: 150 px (cover, three short lines).",
783
+ " - Section / closer heading: 120\u2013130 px, line-height 0.98.",
784
+ " - Page heading: 104 px.",
785
+ " - Card title: 42\u201354 px, display recipe.",
786
+ " - Big stat: 140 px (hero stat), 84 px (inline), 60\u201372 px (table cell), letter-spacing `-0.04em` to `-0.05em`.",
787
+ " - Pull quote: 66 px Newsreader italic, line-height 1.16.",
788
+ " - Body: 34 px on the cover, 28\u201332 px on content pages, line-height 1.45\u20131.5, color `body`.",
789
+ " - Eyebrow: 26 px, weight 650, coral, sentence case.",
790
+ " - Caption / meta: 22\u201326 px, color `muted`.",
791
+ " - Footer: 21 px.",
792
+ "",
793
+ "## Layout",
794
+ "",
795
+ "- Canvas 1920 \u00d7 1080, absolutely positioned on a fixed grid. Left edge `X0 = 120`, content width `W = 1680`.",
796
+ "- Vertical rhythm: eyebrow at `top: 116`, page heading at `top: 160`, a one-line aside right-aligned at `left: 1220\u20131300, top: 196`, main content from `top: 330`, last content ends by ~940, footer at `top: 1000`.",
797
+ "- Cards: radius 24, flat pastel tint, no border, no shadow. Three across: 536 \u00d7 610 at `x = 120 / 692 / 1264`. Full-width rows: 1680 \u00d7 188, stacked 20 px apart.",
798
+ "- Tables and lists: rows separated by 1.5 px `rule` hairlines; header rules in solid 2 px ink.",
799
+ "- Illustrations sit right of the text block (`x \u2248 940\u20131080`) on a pastel backdrop circle, and never overlap type.",
800
+ "- Position helper:",
801
+ "",
802
+ "```tsx",
803
+ "const abs = (left: number, top: number, width?: number, height?: number): CSSProperties => ({",
804
+ " position: 'absolute',",
805
+ " left,",
806
+ " top,",
807
+ " width,",
808
+ " height,",
809
+ "});",
810
+ "```",
811
+ "",
812
+ "## Fixed components",
813
+ "",
814
+ "These are paste-ready. Copy them verbatim into a slide that uses this theme (`import { type CSSProperties, type ReactNode, useId } from 'react';`).",
815
+ "",
816
+ "### Title",
817
+ "",
818
+ "```tsx",
819
+ "const Title = ({ children }: { children: ReactNode }) => (",
820
+ " <h1",
821
+ " style={{",
822
+ " margin: 0,",
823
+ ' fontFamily: \'"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif\',',
824
+ " fontSize: 150,",
825
+ " fontWeight: 780,",
826
+ " lineHeight: 1,",
827
+ " letterSpacing: '-0.04em',",
828
+ " wordSpacing: '0.08em',",
829
+ " color: '#191919',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
830
+ " }}",
831
+ " >",
832
+ " {children}",
833
+ " </h1>",
834
+ ");",
835
+ "```",
836
+ "",
837
+ "### Heading",
838
+ "",
839
+ "Page headings (104), closer headings (130) and card titles (54) share one recipe.",
840
+ "",
841
+ "```tsx",
842
+ "const Heading = ({ children, size = 104 }: { children: ReactNode; size?: number }) => (",
843
+ " <h2",
844
+ " style={{",
845
+ " margin: 0,",
846
+ ' fontFamily: \'"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif\',',
847
+ " fontSize: size,",
848
+ " fontWeight: 780,",
849
+ " lineHeight: 1,",
850
+ " letterSpacing: size >= 100 ? '-0.04em' : '-0.03em',",
851
+ " wordSpacing: '0.08em',",
852
+ " color: '#191919',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
853
+ " }}",
854
+ " >",
855
+ " {children}",
856
+ " </h2>",
857
+ ");",
858
+ "```",
859
+ "",
860
+ "### Footer",
861
+ "",
862
+ "Pin mark + wordmark + label on the left, zero-padded counter on the right. Pass your own `brand` / `label`.",
863
+ "",
864
+ "```tsx",
865
+ "import { useSlidePageNumber } from '@open-slide/core';",
866
+ "",
867
+ "const Mark = ({ size = 24 }: { size?: number }) => (",
868
+ " <svg",
869
+ ' aria-hidden="true"',
870
+ " width={size * 0.8}",
871
+ " height={size}",
872
+ ' viewBox="0 0 20 25"',
873
+ " style={{ display: 'block' }}",
874
+ " >",
875
+ " <path",
876
+ ' d="M10 24C8.5 20 1.5 15 1.5 9.5a8.5 8.5 0 0 1 17 0C18.5 15 11.5 20 10 24Z"',
877
+ ' fill="#191919"', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
878
+ " />",
879
+ ' <circle cx="10" cy="9.5" r="3.4" fill="#FFFEFC" />', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
880
+ " </svg>",
881
+ ");",
882
+ "",
883
+ "const Footer = ({",
884
+ " brand = 'Fieldwork',",
885
+ " label = 'Operating plan',",
886
+ "}: {",
887
+ " brand?: string;",
888
+ " label?: string;",
889
+ "}) => {",
890
+ " const { current, total } = useSlidePageNumber();",
891
+ " const pad2 = (n: number) => String(n).padStart(2, '0');",
892
+ " return (",
893
+ " <div",
894
+ " style={{",
895
+ " position: 'absolute',",
896
+ " left: 120,",
897
+ " right: 120,",
898
+ " top: 1000,",
899
+ " height: 32,",
900
+ " display: 'flex',",
901
+ " alignItems: 'center',",
902
+ " justifyContent: 'space-between',",
903
+ ' fontFamily: \'"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif\',',
904
+ " fontSize: 21,",
905
+ " color: '#9B9A97',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
906
+ " }}",
907
+ " >",
908
+ " <span style={{ display: 'flex', alignItems: 'center', gap: 12 }}>",
909
+ " <Mark size={24} />",
910
+ " <span style={{ color: '#191919', fontWeight: 720, letterSpacing: '-0.02em' }}>{brand}</span>", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
911
+ " <span style={{ marginLeft: 12 }}>{label}</span>",
912
+ " </span>",
913
+ " <span>",
914
+ " {pad2(current)} / {pad2(total)}",
915
+ " </span>",
916
+ " </div>",
917
+ " );",
918
+ "};",
919
+ "```",
920
+ "",
921
+ "### Eyebrow",
922
+ "",
923
+ "Coral, sentence case, no tracking \u2014 it reads like a Notion page breadcrumb, not a label.",
924
+ "",
925
+ "```tsx",
926
+ "const Eyebrow = ({ children }: { children: ReactNode }) => (",
927
+ " <div",
928
+ " style={{",
929
+ ' fontFamily: \'"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif\',',
930
+ " fontSize: 26,",
931
+ " fontWeight: 650,",
932
+ " letterSpacing: '-0.01em',",
933
+ " color: '#E8553B',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
934
+ " }}",
935
+ " >",
936
+ " {children}",
937
+ " </div>",
938
+ ");",
939
+ "```",
940
+ "",
941
+ "### Highlight",
942
+ "",
943
+ "Marker swipe behind one phrase per page. Uneven radii make it look hand-applied.",
944
+ "",
945
+ "```tsx",
946
+ "const Highlight = ({ children, color = '#FCE38A' }: { children: ReactNode; color?: string }) => (", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
947
+ " <span",
948
+ " style={{",
949
+ " background: color,",
950
+ " borderRadius: '6px 12px 8px 14px',",
951
+ " padding: '0 6px',",
952
+ " margin: '0 -2px',",
953
+ " color: '#191919',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
954
+ " WebkitBoxDecorationBreak: 'clone',",
955
+ " boxDecorationBreak: 'clone',",
956
+ " }}",
957
+ " >",
958
+ " {children}",
959
+ " </span>",
960
+ ");",
961
+ "```",
962
+ "",
963
+ "### TintCard",
964
+ "",
965
+ "Flat pastel card. Pick the tint from `tintBlue` / `tintGreen` / `tintYellow` / `tintPink`; rotate through them across a row.",
966
+ "",
967
+ "```tsx",
968
+ "const TintCard = ({",
969
+ " tint = '#E7F3F8',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
970
+ " style,",
971
+ " children,",
972
+ "}: {",
973
+ " tint?: string;",
974
+ " style?: CSSProperties;",
975
+ " children: ReactNode;",
976
+ "}) => (",
977
+ " <div",
978
+ " style={{",
979
+ " position: 'relative',",
980
+ " boxSizing: 'border-box',",
981
+ " borderRadius: 24,",
982
+ " background: tint,",
983
+ " padding: '34px 44px 32px',",
984
+ " ...style,",
985
+ " }}",
986
+ " >",
987
+ " {children}",
988
+ " </div>",
989
+ ");",
990
+ "```",
991
+ "",
992
+ "### Ink, Stroke, CircleDoodle, Sparkle",
993
+ "",
994
+ 'The hand-drawn layer. `Ink` is an SVG with round 3.2 px ink strokes run through a turbulence filter so every line wobbles slightly. Draw illustrations inside it with plain `<path>` / `<rect>` / `<circle>`: ink outline, `#FFFFFF` or a pastel fill, and a pastel backdrop circle with `stroke="none"`. `Stroke` draws itself in when `live` is true \u2014 pass `useIsActivePage()` from the page. `CircleDoodle` loops a key number in coral; `Sparkle` is the four-point star used as a bullet, milestone or garnish.', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
995
+ "",
996
+ "```tsx",
997
+ "const Ink = ({",
998
+ " width,",
999
+ " height,",
1000
+ " viewBox,",
1001
+ " style,",
1002
+ " wobble = 2.2,",
1003
+ " children,",
1004
+ "}: {",
1005
+ " width: number;",
1006
+ " height: number;",
1007
+ " viewBox?: string;",
1008
+ " style?: CSSProperties;",
1009
+ " wobble?: number;",
1010
+ " children: ReactNode;",
1011
+ "}) => {",
1012
+ " const id = `fw${useId().replace(/[^a-zA-Z0-9]/g, '')}`;",
1013
+ " return (",
1014
+ " <svg",
1015
+ ' aria-hidden="true"',
1016
+ " width={width}",
1017
+ " height={height}",
1018
+ " viewBox={viewBox ?? `0 0 ${width} ${height}`}",
1019
+ ' fill="none"',
1020
+ ' stroke="#191919"', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1021
+ " strokeWidth={3.2}",
1022
+ ' strokeLinecap="round"',
1023
+ ' strokeLinejoin="round"',
1024
+ " style={{ display: 'block', overflow: 'visible', ...style }}",
1025
+ " >",
1026
+ " <defs>",
1027
+ ' <filter id={id} x="-10%" y="-10%" width="120%" height="120%">',
1028
+ ' <feTurbulence type="fractalNoise" baseFrequency="0.03" numOctaves={2} seed={4} />',
1029
+ ' <feDisplacementMap in="SourceGraphic" scale={wobble} />',
1030
+ " </filter>",
1031
+ " </defs>",
1032
+ " <g filter={`url(#${id})`}>{children}</g>",
1033
+ " </svg>",
1034
+ " );",
1035
+ "};",
1036
+ "",
1037
+ "const Stroke = ({",
1038
+ " d,",
1039
+ " live,",
1040
+ " delay = 0.3,",
1041
+ " dur = 0.7,",
1042
+ " color = '#191919',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1043
+ " width = 3.2,",
1044
+ "}: {",
1045
+ " d: string;",
1046
+ " live: boolean;",
1047
+ " delay?: number;",
1048
+ " dur?: number;",
1049
+ " color?: string;",
1050
+ " width?: number;",
1051
+ "}) => (",
1052
+ " <path",
1053
+ " d={d}",
1054
+ " pathLength={1}",
1055
+ " strokeDasharray={1}",
1056
+ " stroke={color}",
1057
+ " strokeWidth={width}",
1058
+ ' fill="none"',
1059
+ " style={{",
1060
+ " animation: live ? `fw-draw ${dur}s cubic-bezier(0, 0, 0.2, 1) ${delay}s both` : undefined,",
1061
+ " }}",
1062
+ " />",
1063
+ ");",
1064
+ "",
1065
+ "const loopPath = (w: number, h: number) => {",
1066
+ " const p = (x: number, y: number) => `${((x * w) / 100).toFixed(1)} ${((y * h) / 100).toFixed(1)}`;",
1067
+ " return `M${p(30, 8)}C${p(55, 2)} ${p(90, 8)} ${p(96, 40)}C${p(100, 70)} ${p(72, 94)} ${p(42, 93)}C${p(14, 92)} ${p(2, 74)} ${p(4, 50)}C${p(6, 26)} ${p(26, 10)} ${p(56, 5)}`;",
1068
+ "};",
1069
+ "",
1070
+ "const CircleDoodle = ({",
1071
+ " x,",
1072
+ " y,",
1073
+ " w,",
1074
+ " h,",
1075
+ " live,",
1076
+ " color = '#E8553B',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1077
+ " delay = 0.4,",
1078
+ "}: {",
1079
+ " x: number;",
1080
+ " y: number;",
1081
+ " w: number;",
1082
+ " h: number;",
1083
+ " live: boolean;",
1084
+ " color?: string;",
1085
+ " delay?: number;",
1086
+ "}) => (",
1087
+ " <Ink width={w} height={h} wobble={1.6} style={{ position: 'absolute', left: x, top: y }}>",
1088
+ " <Stroke d={loopPath(w, h)} color={color} width={3.6} live={live} delay={delay} dur={0.8} />",
1089
+ " </Ink>",
1090
+ ");",
1091
+ "",
1092
+ "const Sparkle = ({",
1093
+ " x,",
1094
+ " y,",
1095
+ " s = 1,",
1096
+ " fill = '#F8DA7E',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1097
+ "}: {",
1098
+ " x: number;",
1099
+ " y: number;",
1100
+ " s?: number;",
1101
+ " fill?: string;",
1102
+ "}) => (",
1103
+ " <path",
1104
+ " transform={`translate(${x} ${y}) scale(${s})`}",
1105
+ ' d="M0 -20Q3 -3 20 0Q3 3 0 20Q-3 3 -20 0Q-3 -3 0 -20Z"',
1106
+ " fill={fill}",
1107
+ " strokeWidth={3 / s}",
1108
+ " />",
1109
+ ");",
1110
+ "```",
1111
+ "",
1112
+ "Hand-drawn arrow / underline: an `Ink` box with one or two coral `Stroke`s, e.g. an underline `M6 22C120 10 260 30 400 16S510 12 532 16`, or an arrow whose head is two short strokes appended to the shaft (`\u2026M22 50L44 30M22 50L50 58`).",
1113
+ "",
1114
+ "## Motion",
1115
+ "",
1116
+ "- Philosophy: subtle \u2014 pages ease in with a 5 px lift, then the ink annotations draw themselves and bars grow once the page is active; nothing loops.",
1117
+ "- Keyframes (inject once at module top level with a slide-keyed `<style>` id):",
1118
+ "",
1119
+ "```css",
1120
+ "@keyframes fw-draw { from { stroke-dashoffset: 1 } to { stroke-dashoffset: 0 } }",
1121
+ "@keyframes fw-fade { from { opacity: 0 } to { opacity: 1 } }",
1122
+ "@keyframes fw-rise { from { transform: scaleY(0) } to { transform: scaleY(1) } }",
1123
+ "@keyframes fw-grow { from { transform: scaleX(0) } to { transform: scaleX(1) } }",
1124
+ "```",
1125
+ "",
1126
+ "- Easing: `cubic-bezier(0, 0, 0.2, 1)` out, `cubic-bezier(0.4, 0, 1, 1)` in. Draws run 0.7\u20130.8 s with a 0.3\u20131.0 s delay; bars `fw-rise` / `fw-grow` 0.7 s from `transformOrigin` bottom / left.",
1127
+ "- Gate every on-page animation on `useIsActivePage()` so thumbnails render the finished state.",
1128
+ "- Page transition:",
1129
+ "",
1130
+ "```tsx",
1131
+ "export const transition: SlideTransition = {",
1132
+ " duration: 240,",
1133
+ " exit: {",
1134
+ " duration: 240,",
1135
+ " easing: 'cubic-bezier(0.4, 0, 1, 1)',",
1136
+ " keyframes: [{ opacity: 1 }, { opacity: 1 }],",
1137
+ " },",
1138
+ " enter: {",
1139
+ " duration: 240,",
1140
+ " easing: 'cubic-bezier(0, 0, 0.2, 1)',",
1141
+ " keyframes: [",
1142
+ " { opacity: 0, transform: 'translateY(5px)' },",
1143
+ " { opacity: 1, transform: 'translateY(0)' },",
1144
+ " ],",
1145
+ " },",
1146
+ "};",
1147
+ "```",
1148
+ "",
1149
+ "- For a card that opens into its own page, wrap the tinted card background in `MorphElement` and use `morph: { duration: 760, easing: 'cubic-bezier(0.4, 0, 0.2, 1)' }`; fade the new page's contents in with `fw-fade` after the morph.",
1150
+ "",
1151
+ "## Aesthetic",
1152
+ "",
1153
+ "A company operating plan written in Notion and illustrated by hand: warm paper-white canvas, very heavy tight Inter headlines that read like page titles, calm warm-grey body copy, and generous empty space. Personality comes from the ink layer \u2014 wobbly black-outlined spot illustrations (vans, houses, phones, people, toolboxes) sitting on soft pastel circles, coral circles and arrows scribbled over the numbers that matter, a yellow marker swipe behind one phrase, and the occasional Newsreader italic quote. Every number is real and owned by someone. Avoid: gradients, drop shadows, card borders, dark backgrounds, photography, emoji, uppercase tracked labels, more than one coral mark competing on a page, and illustrations drawn with clean geometric (non-wobbly) strokes.",
1154
+ "",
1155
+ "## Example usage",
1156
+ "",
1157
+ "```tsx",
1158
+ "const root: CSSProperties = {",
1159
+ " position: 'relative',",
1160
+ " width: '100%',",
1161
+ " height: '100%',",
1162
+ " background: '#FFFEFC',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1163
+ " color: '#191919',", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1164
+ ' fontFamily: \'"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif\',',
1165
+ " fontVariantNumeric: 'tabular-nums',",
1166
+ " WebkitFontSmoothing: 'antialiased',",
1167
+ "};",
1168
+ "",
1169
+ "const Cover: Page = () => (",
1170
+ " <div style={root}>",
1171
+ " <div style={{ ...abs(120, 100), display: 'flex', alignItems: 'center', gap: 14 }}>",
1172
+ " <Mark size={32} />",
1173
+ " <span style={{ fontSize: 30, fontWeight: 760, letterSpacing: '-0.03em' }}>Fieldwork</span>",
1174
+ " </div>",
1175
+ " <div style={abs(120, 262)}>",
1176
+ " <Title>",
1177
+ " The annual",
1178
+ " <br />",
1179
+ " operating",
1180
+ " <br />",
1181
+ " plan.",
1182
+ " </Title>",
1183
+ " </div>",
1184
+ " <p style={{ ...abs(120, 772, 760), margin: 0, fontSize: 34, lineHeight: 1.45, color: '#5F5E5B' }}>", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1185
+ " Where we are, where we are going, and <Highlight>who owns each step</Highlight>.",
1186
+ " </p>",
1187
+ " <div style={{ ...abs(120, 906), fontSize: 24, color: '#9B9A97' }}>", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1188
+ " All-hands pre-read \u00b7 Planning team",
1189
+ " </div>",
1190
+ " <Footer />",
1191
+ " </div>",
1192
+ ");",
1193
+ "",
1194
+ "const Summary: Page = () => {",
1195
+ " const live = useIsActivePage();",
1196
+ " return (",
1197
+ " <div style={root}>",
1198
+ " <div style={abs(120, 116)}>",
1199
+ " <Eyebrow>Strategy</Eyebrow>",
1200
+ " </div>",
1201
+ " <div style={abs(120, 160)}>",
1202
+ " <Heading>Three bets this year.</Heading>",
1203
+ " </div>",
1204
+ ' <TintCard tint="#E7F3F8" style={abs(120, 330, 536, 610)}>', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1205
+ " \u2026",
1206
+ " </TintCard>",
1207
+ " <CircleDoodle x={710} y={834} w={300} h={104} live={live} />",
1208
+ " <Footer />",
1209
+ " </div>",
1210
+ " );",
1211
+ "};",
1212
+ "```",
1213
+ ].join("\n"),
1214
+ },
1215
+ {
1216
+ id: "pommi",
1217
+ name: "Pommi",
1218
+ description:
1219
+ "Playful consumer-brand deck \u2014 cream paper, ink outlines, tomato accent, sticker-bright fills, chunky Gabarito and springy motion.",
1220
+ mode: "light",
1221
+ preview: {
1222
+ background: "#FFF3DF", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1223
+ text: "#151313", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1224
+ accent: "#FF5A2C", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1225
+ },
1226
+ guide: [
1227
+ "# Pommi",
1228
+ "",
1229
+ "## Palette",
1230
+ "",
1231
+ "Cream paper and near-black ink do the structural work; tomato is the one accent. Butter, mint, periwinkle and pink are flat fills for cards, stickers, chips and chart marks \u2014 every filled shape gets a 4 px ink outline and a hard offset shadow.",
1232
+ "",
1233
+ "| Role | Value | Notes |",
1234
+ "| --------- | ----------------------- | --------------------------------------------------------------------- |",
1235
+ "| bg | `#FFF3DF` | cream canvas (`design.palette.bg` \u2192 `CREAM`) |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1236
+ "| text | `#151313` | ink: copy, outlines, shadows, pill fills (`design.palette.text` \u2192 `INK`) |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1237
+ '| accent | `#FF5A2C` | tomato: hero stat block, lead sticker, "you" marks (`design.palette.accent` \u2192 `TOMATO`) |', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1238
+ "| butter | `#FFD23F` | default eyebrow fill, highlight sticker, sparkles |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1239
+ '| mint | `#7EDDB0` | positive / "done" fills, secondary sticker |', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1240
+ "| peri | `#98A6FF` | cool fill, cover slab, third series |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1241
+ "| pink | `#FFB0D0` | fourth series, small sparkles |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1242
+ "| paper | `#FFFCF6` | card surface on top of cream |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1243
+ "| white | `#FFFFFF` | chat-bubble style surfaces only |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1244
+ "| muted | `rgba(21, 19, 19, 0.6)` | captions, mono labels, footnotes (\u2248 `#736D65` on cream) |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1245
+ '| faint | `rgba(21, 19, 19, 0.16)`| dashed dividers, grid lines, "inactive" outlines (\u2248 `#DACFBE` on cream) |', // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1246
+ "| heat ramp | `rgba(255, 90, 44, a)` | tomato at 0.1\u20131 alpha for heatmap tiles |", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1247
+ "",
1248
+ "Text on any fill (tomato, butter, mint, peri, pink) is always ink \u2014 never white.",
1249
+ "",
1250
+ "## Typography",
1251
+ "",
1252
+ '- Display font: `"Gabarito", system-ui, sans-serif` \u2014 weight 900 for titles and numbers, 800 for taglines and card labels.',
1253
+ '- Body font: `"Gabarito", system-ui, sans-serif` \u2014 weight 500 for copy, 700\u2013800 for inline emphasis.',
1254
+ '- Label font: `"DM Mono", ui-monospace, monospace` \u2014 weight 500, 17 px, uppercase, `letter-spacing: 0.06em`. Used for eyebrows, captions, axis labels, the footer and page counter.',
1255
+ "- Webfont import: `https://fonts.googleapis.com/css2?family=DM+Mono:wght@500&family=Gabarito:wght@500;700;800;900&display=swap` \u2014 inject once at module top level (snippet in **Motion**), per `references/webfonts.md` in `slide-authoring`.",
1256
+ "- Type scale (overrides `slide-authoring` where noted):",
1257
+ " - Wordmark / hero word: 250\u2013300 px, weight 900, `letter-spacing: -0.055em`, line-height 1 (`typeScale.hero = 300`; above the 140\u2013200 default).",
1258
+ " - Hero number: 180\u2013280 px, weight 900, `letter-spacing: -0.05em`, line-height 0.86, tabular figures.",
1259
+ " - Cover / closer tagline: 64\u201372 px, weight 800, line-height 1.06\u20131.08, `letter-spacing: -0.03em`.",
1260
+ " - Page title: 88 px (80\u201396), weight 900, line-height 1, `letter-spacing: -0.035em`.",
1261
+ " - Card title: 46\u201364 px display weight 900.",
1262
+ " - Stat number: 44\u201376 px display weight 900, `letter-spacing: -0.04em`.",
1263
+ " - Body: 30 px, weight 500, line-height 1.32 (`typeScale.body = 30`; tighter than the 1.5 default \u2014 the type is chunky and copy is short). 28 px inside cards.",
1264
+ " - Inline UI label: 20\u201330 px, weight 700\u2013800.",
1265
+ " - Mono label: 16\u201318 px. Footnote: 18 px, weight 500, line-height 1.4, muted.",
1266
+ "- Gotcha: Gabarito's heavy `\u20ac` has almost no right bearing; under negative tracking wrap it as `<span style={{ marginRight: '0.06em' }}>\u20ac</span>`.",
1267
+ "",
1268
+ "## Layout",
1269
+ "",
1270
+ "- Canvas 1920 \u00d7 1080, `overflow: hidden`. Everything is absolutely placed with the `abs(left, top)` helper \u2014 this is a poster layout, not a flow layout.",
1271
+ "- Side margins: 120 px \u2192 content width 1680 px.",
1272
+ "- Vertical rhythm on content pages: Eyebrow at `y = 96` (46 px tall), Title at `y = 168`, content band roughly `y = 330 \u2192 900`, Footnote at `y \u2248 898\u2013956`, Footer row at `y = 996` (44 px tall).",
1273
+ "- Split pages: left column `x = 120`, 1000 px wide; right column starts at 1160\u20131240 and runs to 1800. A big coloured **slab** (620\u2013640 px wide, 48 px radius, 4 px ink border) often fills the right column and may bleed off the bottom edge.",
1274
+ "- Cover and closer drop the footer and carry a muted mono line at `y = 984` instead.",
1275
+ "- Strokes: 4 px ink for cards, slabs and stickers; 3 px for pills, chips and small tiles; 2.5 px for tiny badges.",
1276
+ "- Shadows are hard offsets with no blur \u2014 `shadow(n)` = `n px n px 0 ink`: 4 on pills, 5\u20136 on stickers and small tiles, 8 on cards, 10 on large cards, 12 on slabs and hero objects.",
1277
+ "- Radii: 999 for pills, 20\u201328 for cards (`design.radius = 28`), 34 for large tilted cards, 48 for slabs.",
1278
+ "- Tilt: stickers \u00b14\u201310\u00b0, cards \u00b11\u20139\u00b0. Content tables and charts stay straight.",
1279
+ "- Dividers: `3px dashed faint` inside cards; `2px dashed faint` for chart grid lines; a 4 px ink baseline under bar charts.",
1280
+ "",
1281
+ "## Fixed components",
1282
+ "",
1283
+ "These are paste-ready. Copy the tokens and helpers first, then the components, then the Motion helpers and style injection.",
1284
+ "",
1285
+ "### Tokens & layout helpers",
1286
+ "",
1287
+ "`CREAM` / `INK` / `TOMATO` read from the per-slide `design` so the Design panel can tweak them.",
1288
+ "",
1289
+ "```tsx",
1290
+ "import {",
1291
+ " type DesignSystem,",
1292
+ " type Page,",
1293
+ " useIsActivePage,",
1294
+ " useSlidePageNumber,",
1295
+ "} from '@open-slide/core';",
1296
+ "import { type CSSProperties, type ReactNode, useEffect, useState } from 'react';",
1297
+ "",
1298
+ "export const design: DesignSystem = {",
1299
+ " palette: { bg: '#FFF3DF', text: '#151313', accent: '#FF5A2C' },", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1300
+ " fonts: {",
1301
+ " display: '\"Gabarito\", system-ui, sans-serif',",
1302
+ " body: '\"Gabarito\", system-ui, sans-serif',",
1303
+ " },",
1304
+ " typeScale: { hero: 300, body: 30 },",
1305
+ " radius: 28,",
1306
+ "};",
1307
+ "",
1308
+ "const CREAM = 'var(--slides2-bg)';",
1309
+ "const INK = 'var(--slides2-text)';",
1310
+ "const TOMATO = 'var(--slides2-accent)';",
1311
+ "const BUTTER = '#FFD23F';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1312
+ "const MINT = '#7EDDB0';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1313
+ "const PERI = '#98A6FF';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1314
+ "const PINK = '#FFB0D0';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1315
+ "const PAPER = '#FFFCF6';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1316
+ "const MUTED = 'rgba(21, 19, 19, 0.6)';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1317
+ "const FAINT = 'rgba(21, 19, 19, 0.16)';", // guard:allow-raw-color — authored slide theme palette or documentation, not app chrome.
1318
+ "",
1319
+ "const BORDER = `4px solid ${INK}`;",
1320
+ "const shadow = (n = 8) => `${n}px ${n}px 0 ${INK}`;",
1321
+ "",
1322
+ "const DISPLAY: CSSProperties = {",
1323
+ " fontFamily: 'var(--slides2-font-display)',",
1324
+ " fontWeight: 900,",
1325
+ " letterSpacing: '-0.035em',",
1326
+ " lineHeight: 1,",
1327
+ " margin: 0,",
1328
+ "};",
1329
+ "",
1330
+ "const MONO: CSSProperties = {",
1331
+ " fontFamily: '\"DM Mono\", ui-monospace, monospace',",
1332
+ " fontWeight: 500,",
1333
+ " fontSize: 17,",
1334
+ " letterSpacing: '0.06em',",
1335
+ " textTransform: 'uppercase',",
1336
+ " lineHeight: 1.2,",
1337
+ "};",
1338
+ "",
1339
+ "const BODY: CSSProperties = {",
1340
+ " fontFamily: 'var(--slides2-font-body)',",
1341
+ " fontWeight: 500,",
1342
+ " fontSize: 'var(--slides2-size-body)',",
1343
+ " lineHeight: 1.32,",
1344
+ " margin: 0,",
1345
+ " textWrap: 'pretty',",
1346
+ "};",
1347
+ "",
1348
+ "const NUM: CSSProperties = { ...DISPLAY, fontVariantNumeric: 'tabular-nums' };",
1349
+ "",
1350
+ "const abs = (left: number, top: number, extra?: CSSProperties): CSSProperties => ({",
1351
+ " position: 'absolute',",
1352
+ " left,",
1353
+ " top,",
1354
+ " ...extra,",
1355
+ "});",
1356
+ "",
1357
+ "const pad = (n: number) => String(n).padStart(2, '0');",
1358
+ "```",
1359
+ "",
1360
+ "### Title",
1361
+ "",
1362
+ "Absolutely placed at the standard title slot. Rises in when the page goes live.",
1363
+ "",
1364
+ "```tsx",
1365
+ "const Title = ({",
1366
+ " children,",
1367
+ " live,",
1368
+ " x = 120,",
1369
+ " y = 168,",
1370
+ " size = 88,",
1371
+ " width = 1680,",
1372
+ " delay = 70,",
1373
+ "}: {",
1374
+ " children: ReactNode;",
1375
+ " live: boolean;",
1376
+ " x?: number;",
1377
+ " y?: number;",
1378
+ " size?: number;",
1379
+ " width?: number;",
1380
+ " delay?: number;",
1381
+ "}) => (",
1382
+ " <h2 style={{ ...DISPLAY, ...abs(x, y), width, fontSize: size, ...rise(live, delay, 40) }}>",
1383
+ " {children}",
1384
+ " </h2>",
1385
+ ");",
1386
+ "```",
1387
+ "",
1388
+ "### Footer",
1389
+ "",
1390
+ "Pull the page number from `useSlidePageNumber()` \u2014 never hardcode `pageNum` / `total` props. Brand mark + wordmark on the left, mono label, a muted note pushed right, and an ink pill counter (`03 / 12`).",
1391
+ "",
1392
+ "```tsx",
1393
+ "const Footer = ({",
1394
+ " brand = 'pommi',",
1395
+ " label = 'Company update \u00b7 2026',",
1396
+ " note = 'Confidential',",
1397
+ "}: {",
1398
+ " brand?: string;",
1399
+ " label?: string;",
1400
+ " note?: string;",
1401
+ "}) => {",
1402
+ " const { current, total } = useSlidePageNumber();",
1403
+ " return (",
1404
+ " <div",
1405
+ " style={abs(120, 996, {",
1406
+ " width: 1680,",
1407
+ " height: 44,",
1408
+ " display: 'flex',",
1409
+ " alignItems: 'center',",
1410
+ " gap: 14,",
1411
+ " zIndex: 8,",
1412
+ " })}",
1413
+ " >",
1414
+ " <Mark size={34} />",
1415
+ " <span style={{ ...DISPLAY, fontSize: 30, letterSpacing: '-0.04em' }}>{brand}</span>",
1416
+ " <span style={{ ...MONO, color: MUTED, marginLeft: 18 }}>{label}</span>",
1417
+ " <span style={{ ...MONO, color: MUTED, marginLeft: 'auto', marginRight: 10 }}>{note}</span>",
1418
+ " <span",
1419
+ " style={{",
1420
+ " ...MONO,",
1421
+ " height: 38,",
1422
+ " padding: '0 16px',",
1423
+ " borderRadius: 999,",
1424
+ " background: INK,",
1425
+ " color: CREAM,",
1426
+ " display: 'inline-flex',",
1427
+ " alignItems: 'center',",
1428
+ " fontVariantNumeric: 'tabular-nums',",
1429
+ " }}",
1430
+ " >",
1431
+ " {pad(current)} / {pad(total)}",
1432
+ " </span>",
1433
+ " </div>",
1434
+ " );",
1435
+ "};",
1436
+ "```",
1437
+ "",
1438
+ "### Eyebrow",
1439
+ "",
1440
+ "A numbered section tag: ink cell with the section number, butter label, hard 4 px shadow. Pass `color={TOMATO}` for the climax section (e.g. the ask).",
1441
+ "",
1442
+ "```tsx",
1443
+ "const Eyebrow = ({",
1444
+ " n,",
1445
+ " children,",
1446
+ " live,",
1447
+ " x = 120,",
1448
+ " y = 96,",
1449
+ " color = BUTTER,",
1450
+ "}: {",
1451
+ " n: string;",
1452
+ " children: ReactNode;",
1453
+ " live: boolean;",
1454
+ " x?: number;",
1455
+ " y?: number;",
1456
+ " color?: string;",
1457
+ "}) => (",
1458
+ " <div",
1459
+ " style={abs(x, y, {",
1460
+ " display: 'flex',",
1461
+ " alignItems: 'stretch',",
1462
+ " height: 46,",
1463
+ " border: `3px solid ${INK}`,",
1464
+ " borderRadius: 999,",
1465
+ " background: color,",
1466
+ " boxShadow: shadow(4),",
1467
+ " overflow: 'hidden',",
1468
+ " ...rise(live, 0, 20),",
1469
+ " })}",
1470
+ " >",
1471
+ " <span",
1472
+ " style={{",
1473
+ " ...MONO,",
1474
+ " fontSize: 18,",
1475
+ " padding: '0 14px 0 16px',",
1476
+ " display: 'flex',",
1477
+ " alignItems: 'center',",
1478
+ " background: INK,",
1479
+ " color: CREAM,",
1480
+ " }}",
1481
+ " >",
1482
+ " {n}",
1483
+ " </span>",
1484
+ " <span",
1485
+ " style={{",
1486
+ " ...MONO,",
1487
+ " fontSize: 18,",
1488
+ " padding: '0 20px 0 16px',",
1489
+ " display: 'flex',",
1490
+ " alignItems: 'center',",
1491
+ " }}",
1492
+ " >",
1493
+ " {children}",
1494
+ " </span>",
1495
+ " </div>",
1496
+ ");",
1497
+ "```",
1498
+ "",
1499
+ "### Stage",
1500
+ "",
1501
+ "The page root. Every page wraps in it; pass `footer={false}` on cover and closer.",
1502
+ "",
1503
+ "```tsx",
1504
+ "const Stage = ({ footer = true, children }: { footer?: boolean; children: ReactNode }) => (",
1505
+ " <div",
1506
+ ' className="pm-root"',
1507
+ " style={{",
1508
+ " width: '100%',",
1509
+ " height: '100%',",
1510
+ " position: 'relative',",
1511
+ " overflow: 'hidden',",
1512
+ " isolation: 'isolate',",
1513
+ " background: CREAM,",
1514
+ " color: INK,",
1515
+ " fontFamily: 'var(--slides2-font-body)',",
1516
+ " }}",
1517
+ " >",
1518
+ " {children}",
1519
+ " {footer && <Footer />}",
1520
+ " </div>",
1521
+ ");",
1522
+ "```",
1523
+ "",
1524
+ "### Mark",
1525
+ "",
1526
+ "The tomato mascot: ink-outlined tomato with a mint leaf and a little door. Used at 34 px in the footer, 50 px on the cover, 400 px bobbing on the closer.",
1527
+ "",
1528
+ "```tsx",
1529
+ "const Mark = ({ size = 56 }: { size?: number }) => (",
1530
+ " <svg",
1531
+ " width={size}",
1532
+ " height={size}",
1533
+ ' viewBox="0 0 64 64"',
1534
+ ' aria-hidden="true"',
1535
+ " style={{ display: 'block', overflow: 'visible' }}",
1536
+ " >",
1537
+ " <path",
1538
+ ' d="M36.5 13.5 C 38.5 6, 46.5 2.5, 55 4.5 C 53 12, 45 16, 36.5 13.5 Z"',
1539
+ " style={{ fill: MINT, stroke: INK, strokeWidth: 3.5, strokeLinejoin: 'round' }}",
1540
+ " />",
1541
+ " <path",
1542
+ ' d="M32 19 C 32 13, 33 9, 36 6"',
1543
+ " style={{ fill: 'none', stroke: INK, strokeWidth: 4, strokeLinecap: 'round' }}",
1544
+ " />",
1545
+ " <path",
1546
+ ' d="M32 19 C 23 13, 6 15, 6 34 C 6 50, 17 60, 25 60 C 28 60, 30 58.5, 32 58.5 C 34 58.5, 36 60, 39 60 C 47 60, 58 50, 58 34 C 58 15, 41 13, 32 19 Z"',
1547
+ " style={{ fill: TOMATO, stroke: INK, strokeWidth: 4, strokeLinejoin: 'round' }}",
1548
+ " />",
1549
+ " <path",
1550
+ ' d="M26.5 58.6 V 47 A 5.5 5.5 0 0 1 37.5 47 V 58.6"',
1551
+ " style={{ fill: CREAM, stroke: INK, strokeWidth: 3.5, strokeLinejoin: 'round' }}",
1552
+ " />",
1553
+ " <path",
1554
+ ' d="M15 30 C 15.5 25.5, 18.5 22.5, 22.5 21.5"',
1555
+ " style={{ fill: 'none', stroke: PAPER, strokeWidth: 3.5, strokeLinecap: 'round' }}",
1556
+ " />",
1557
+ " </svg>",
1558
+ ");",
1559
+ "```",
1560
+ "",
1561
+ "### Sticker",
1562
+ "",
1563
+ "The signature move: a tilted, outlined, hard-shadowed badge that slaps on and then wobbles gently forever. Pass `round={232}` for a circular sticker.",
1564
+ "",
1565
+ "```tsx",
1566
+ "const Sticker = ({",
1567
+ " x,",
1568
+ " y,",
1569
+ " r,",
1570
+ " live,",
1571
+ " delay,",
1572
+ " bg,",
1573
+ " children,",
1574
+ " round,",
1575
+ " pad: padding = '14px 26px',",
1576
+ " z = 6,",
1577
+ "}: {",
1578
+ " x: number;",
1579
+ " y: number;",
1580
+ " r: number;",
1581
+ " live: boolean;",
1582
+ " delay: number;",
1583
+ " bg: string;",
1584
+ " children: ReactNode;",
1585
+ " round?: number;",
1586
+ " pad?: string;",
1587
+ " z?: number;",
1588
+ "}) => (",
1589
+ " <div",
1590
+ " style={",
1591
+ " {",
1592
+ " ...abs(x, y),",
1593
+ " '--r': `${r}deg`,",
1594
+ " transform: `rotate(${r}deg)`,",
1595
+ " zIndex: z,",
1596
+ " ...anim(live, `pm-slap 760ms ${SLAP} ${delay}ms both`),",
1597
+ " } as CSSProperties",
1598
+ " }",
1599
+ " >",
1600
+ " <div",
1601
+ " style={{",
1602
+ " ...anim(live, `pm-wobble 5.2s ease-in-out ${delay + 900}ms infinite`),",
1603
+ " background: bg,",
1604
+ " border: BORDER,",
1605
+ " boxShadow: shadow(6),",
1606
+ " borderRadius: round ? '50%' : 22,",
1607
+ " width: round,",
1608
+ " height: round,",
1609
+ " padding: round ? 0 : padding,",
1610
+ " display: 'flex',",
1611
+ " flexDirection: 'column',",
1612
+ " alignItems: 'center',",
1613
+ " justifyContent: 'center',",
1614
+ " textAlign: 'center',",
1615
+ " }}",
1616
+ " >",
1617
+ " {children}",
1618
+ " </div>",
1619
+ " </div>",
1620
+ ");",
1621
+ "```",
1622
+ "",
1623
+ "### Sparkle",
1624
+ "",
1625
+ "A four-point ink-outlined star that pops in and twinkles. Scatter two or three around stickers and slabs, never more.",
1626
+ "",
1627
+ "```tsx",
1628
+ "const Sparkle = ({",
1629
+ " x,",
1630
+ " y,",
1631
+ " size,",
1632
+ " color = BUTTER,",
1633
+ " live,",
1634
+ " delay,",
1635
+ "}: {",
1636
+ " x: number;",
1637
+ " y: number;",
1638
+ " size: number;",
1639
+ " color?: string;",
1640
+ " live: boolean;",
1641
+ " delay: number;",
1642
+ "}) => (",
1643
+ " <div",
1644
+ " style={{",
1645
+ " ...abs(x, y),",
1646
+ " width: size,",
1647
+ " height: size,",
1648
+ " ...anim(live, `pm-pop 700ms ${BOUNCY} ${delay}ms both`),",
1649
+ " }}",
1650
+ " >",
1651
+ " <svg",
1652
+ " width={size}",
1653
+ " height={size}",
1654
+ ' viewBox="0 0 40 40"',
1655
+ ' aria-hidden="true"',
1656
+ " style={{",
1657
+ " display: 'block',",
1658
+ " overflow: 'visible',",
1659
+ " ...anim(live, `pm-twinkle 2.8s ease-in-out ${delay + 700}ms infinite`),",
1660
+ " }}",
1661
+ " >",
1662
+ " <path",
1663
+ ' d="M20 2 C 22 14, 26 18, 38 20 C 26 22, 22 26, 20 38 C 18 26, 14 22, 2 20 C 14 18, 18 14, 20 2 Z"',
1664
+ " style={{ fill: color, stroke: INK, strokeWidth: 3, strokeLinejoin: 'round' }}",
1665
+ " />",
1666
+ " </svg>",
1667
+ " </div>",
1668
+ ");",
1669
+ "```",
1670
+ "",
1671
+ "### Chip",
1672
+ "",
1673
+ "Paper pill for facts under a tagline (counts, markets, contact details).",
1674
+ "",
1675
+ "```tsx",
1676
+ "const Chip = ({ children }: { children: ReactNode }) => (",
1677
+ " <span",
1678
+ " style={{",
1679
+ " height: 52,",
1680
+ " padding: '0 22px',",
1681
+ " border: `3px solid ${INK}`,",
1682
+ " borderRadius: 999,",
1683
+ " display: 'inline-flex',",
1684
+ " alignItems: 'center',",
1685
+ " fontSize: 24,",
1686
+ " fontWeight: 700,",
1687
+ " background: PAPER,",
1688
+ " }}",
1689
+ " >",
1690
+ " {children}",
1691
+ " </span>",
1692
+ ");",
1693
+ "```",
1694
+ "",
1695
+ "### StatRow",
1696
+ "",
1697
+ 'A paper card with a coloured number block on the left \u2014 the workhorse for "three numbers" pages. Stack at 156 px pitch (`y = 420, 576, 732`).',
1698
+ "",
1699
+ "```tsx",
1700
+ "const StatRow = ({",
1701
+ " x = 120,",
1702
+ " y,",
1703
+ " n,",
1704
+ " color,",
1705
+ " live,",
1706
+ " delay,",
1707
+ " children,",
1708
+ "}: {",
1709
+ " x?: number;",
1710
+ " y: number;",
1711
+ " n: string;",
1712
+ " color: string;",
1713
+ " live: boolean;",
1714
+ " delay: number;",
1715
+ " children: ReactNode;",
1716
+ "}) => (",
1717
+ " <div",
1718
+ " style={abs(x, y, {",
1719
+ " width: 1000,",
1720
+ " height: 132,",
1721
+ " display: 'flex',",
1722
+ " border: BORDER,",
1723
+ " borderRadius: 28,",
1724
+ " background: PAPER,",
1725
+ " boxShadow: shadow(8),",
1726
+ " overflow: 'hidden',",
1727
+ " boxSizing: 'border-box',",
1728
+ " ...anim(live, `pm-in-l 900ms ${SNAPPY} ${delay}ms both`),",
1729
+ " })}",
1730
+ " >",
1731
+ " <div",
1732
+ " style={{",
1733
+ " width: 250,",
1734
+ " flex: 'none',",
1735
+ " background: color,",
1736
+ " borderRight: BORDER,",
1737
+ " display: 'flex',",
1738
+ " alignItems: 'center',",
1739
+ " paddingLeft: 30,",
1740
+ " boxSizing: 'border-box',",
1741
+ " }}",
1742
+ " >",
1743
+ " <span style={{ ...NUM, fontSize: 76, letterSpacing: '-0.045em' }}>{n}</span>",
1744
+ " </div>",
1745
+ " <p style={{ ...BODY, padding: '0 36px', alignSelf: 'center' }}>{children}</p>",
1746
+ " </div>",
1747
+ ");",
1748
+ "```",
1749
+ "",
1750
+ "### TiltCard",
1751
+ "",
1752
+ 'A large coloured card with an ink number badge and a display title, slapped on at an angle. Fan three of them for "how it works" or feature pages.',
1753
+ "",
1754
+ "```tsx",
1755
+ "const TiltCard = ({",
1756
+ " x,",
1757
+ " y,",
1758
+ " r,",
1759
+ " color,",
1760
+ " n,",
1761
+ " title,",
1762
+ " live,",
1763
+ " delay,",
1764
+ " width = 360,",
1765
+ " height = 420,",
1766
+ " children,",
1767
+ "}: {",
1768
+ " x: number;",
1769
+ " y: number;",
1770
+ " r: number;",
1771
+ " color: string;",
1772
+ " n: string;",
1773
+ " title: string;",
1774
+ " live: boolean;",
1775
+ " delay: number;",
1776
+ " width?: number;",
1777
+ " height?: number;",
1778
+ " children: ReactNode;",
1779
+ "}) => (",
1780
+ " <div",
1781
+ " style={",
1782
+ " {",
1783
+ " ...abs(x, y),",
1784
+ " '--r': `${r}deg`,",
1785
+ " transform: `rotate(${r}deg)`,",
1786
+ " width,",
1787
+ " height,",
1788
+ " boxSizing: 'border-box',",
1789
+ " padding: 28,",
1790
+ " background: color,",
1791
+ " border: BORDER,",
1792
+ " borderRadius: 34,",
1793
+ " boxShadow: shadow(10),",
1794
+ " display: 'flex',",
1795
+ " flexDirection: 'column',",
1796
+ " ...anim(live, `pm-slap 760ms ${SLAP} ${delay}ms both`),",
1797
+ " } as CSSProperties",
1798
+ " }",
1799
+ " >",
1800
+ " <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>",
1801
+ " <span",
1802
+ " style={{",
1803
+ " ...MONO,",
1804
+ " fontSize: 18,",
1805
+ " width: 52,",
1806
+ " height: 52,",
1807
+ " flex: 'none',",
1808
+ " borderRadius: '50%',",
1809
+ " background: INK,",
1810
+ " color: CREAM,",
1811
+ " display: 'flex',",
1812
+ " alignItems: 'center',",
1813
+ " justifyContent: 'center',",
1814
+ " }}",
1815
+ " >",
1816
+ " {n}",
1817
+ " </span>",
1818
+ " <span style={{ ...DISPLAY, fontSize: 64 }}>{title}</span>",
1819
+ " </div>",
1820
+ " <p style={{ ...BODY, fontSize: 28, marginTop: 24, lineHeight: 1.3 }}>{children}</p>",
1821
+ " </div>",
1822
+ ");",
1823
+ "```",
1824
+ "",
1825
+ "### DropWord",
1826
+ "",
1827
+ "Hero word where each letter falls in with a gravity bounce and squashes on landing. Use for one short word (no spaces) at 250\u2013300 px.",
1828
+ "",
1829
+ "```tsx",
1830
+ "const DropWord = ({",
1831
+ " text,",
1832
+ " size,",
1833
+ " live,",
1834
+ " delay = 0,",
1835
+ "}: {",
1836
+ " text: string;",
1837
+ " size: number;",
1838
+ " live: boolean;",
1839
+ " delay?: number;",
1840
+ "}) => {",
1841
+ " const letters = Array.from(text, (ch, i) => ({ ch, id: `${i}-${ch}` }));",
1842
+ " return (",
1843
+ " <div",
1844
+ " style={{",
1845
+ " ...DISPLAY,",
1846
+ " fontSize: size,",
1847
+ " letterSpacing: '-0.055em',",
1848
+ " lineHeight: 1,",
1849
+ " display: 'flex',",
1850
+ " whiteSpace: 'nowrap',",
1851
+ " }}",
1852
+ " >",
1853
+ " {letters.map((l, i) => {",
1854
+ " const d = delay + i * 85;",
1855
+ " return (",
1856
+ " <span",
1857
+ " key={l.id}",
1858
+ " style={{",
1859
+ " display: 'inline-block',",
1860
+ " ...(live",
1861
+ " ? ({",
1862
+ " animation: `pm-drop 940ms ${DROP} ${d}ms both`,",
1863
+ " '--pm-from': '-1.6em',",
1864
+ " } as CSSProperties)",
1865
+ " : {}),",
1866
+ " }}",
1867
+ " >",
1868
+ " <span",
1869
+ " style={{",
1870
+ " display: 'inline-block',",
1871
+ " transformOrigin: '50% 88%',",
1872
+ " ...anim(live, `pm-squash 560ms ease-out ${d + Math.round(940 * DROP_LAND)}ms both`),",
1873
+ " }}",
1874
+ " >",
1875
+ " {l.ch}",
1876
+ " </span>",
1877
+ " </span>",
1878
+ " );",
1879
+ " })}",
1880
+ " </div>",
1881
+ " );",
1882
+ "};",
1883
+ "```",
1884
+ "",
1885
+ "### Footnote",
1886
+ "",
1887
+ "```tsx",
1888
+ "const Footnote = ({",
1889
+ " x = 120,",
1890
+ " y,",
1891
+ " width = 1680,",
1892
+ " children,",
1893
+ "}: {",
1894
+ " x?: number;",
1895
+ " y: number;",
1896
+ " width?: number;",
1897
+ " children: ReactNode;",
1898
+ "}) => (",
1899
+ " <p style={{ ...BODY, ...abs(x, y), width, fontSize: 18, lineHeight: 1.4, color: MUTED }}>",
1900
+ " {children}",
1901
+ " </p>",
1902
+ ");",
1903
+ "```",
1904
+ "",
1905
+ "## Motion",
1906
+ "",
1907
+ '- Philosophy: **rich** \u2014 everything has weight: letters drop and squash, stickers slap on and wobble, cards spring in, hero numbers count up and land with a "thunk"; but animation only runs while the page is active (`useLive`), so thumbnails, overview and PDF render the final frame.',
1908
+ "- Easing: physical curves generated into CSS `linear()` \u2014 `BOUNCY` (spring, \u03b6 0.38) for pops and bars, `SNAPPY` (spring, \u03b6 0.62) for rises and slide-ins, `DROP` (gravity with two bounces) for falling objects, `SLAP` cubic-bezier for stickers.",
1909
+ "- Choreography: eyebrow at 0 ms, title ~70 ms, content staggered 120\u2013150 ms apart, stickers and sparkles last (1.2\u20132.5 s). Count-ups ease out quartically over ~1.6 s; fire `pm-thunk` on the number as it lands.",
1910
+ "- Page transition: 240 ms \u2014 the outgoing page holds, the incoming one fades up 8 px.",
1911
+ "- `prefers-reduced-motion` disables all animation under `.pm-root`.",
1912
+ "",
1913
+ "Easing generators and live / count-up helpers:",
1914
+ "",
1915
+ "```tsx",
1916
+ "const springAt = (t: number, zeta: number, omega: number) => {",
1917
+ " if (t >= 1) return 1;",
1918
+ " const wd = omega * Math.sqrt(1 - zeta * zeta);",
1919
+ " const decay = Math.exp(-zeta * omega * t);",
1920
+ " return 1 - decay * (Math.cos(wd * t) + ((zeta * omega) / wd) * Math.sin(wd * t));",
1921
+ "};",
1922
+ "",
1923
+ "// Gravity drop with two shrinking bounces; never passes the floor, unlike a spring.",
1924
+ "const dropAt = (t: number) => {",
1925
+ " const e = 0.3;",
1926
+ " const segs = [1, 2 * e, 2 * e * e];",
1927
+ " const total = segs[0] + segs[1] + segs[2];",
1928
+ " let u = t * total;",
1929
+ " if (u <= 1) return u * u;",
1930
+ " u -= 1;",
1931
+ " for (let k = 1; k < segs.length; k++) {",
1932
+ " if (u <= segs[k]) {",
1933
+ " const x = u / segs[k];",
1934
+ " return 1 - e ** (2 * k) * 4 * x * (1 - x);",
1935
+ " }",
1936
+ " u -= segs[k];",
1937
+ " }",
1938
+ " return 1;",
1939
+ "};",
1940
+ "const DROP_LAND = 1 / (1 + 0.6 + 0.18);",
1941
+ "",
1942
+ "const toLinear = (f: (t: number) => number, n: number) =>",
1943
+ " `linear(${Array.from({ length: n + 1 }, (_, i) => Number(f(i / n).toFixed(4))).join(', ')})`;",
1944
+ "",
1945
+ "const BOUNCY = toLinear((t) => springAt(t, 0.38, 15), 64);",
1946
+ "const SNAPPY = toLinear((t) => springAt(t, 0.62, 10.5), 48);",
1947
+ "const DROP = toLinear(dropAt, 72);",
1948
+ "const SLAP = 'cubic-bezier(0.2, 0.8, 0.3, 1)';",
1949
+ "",
1950
+ "const anim = (live: boolean, value: string): CSSProperties => (live ? { animation: value } : {});",
1951
+ "",
1952
+ "const rise = (live: boolean, delay = 0, dist = 32): CSSProperties =>",
1953
+ " live",
1954
+ " ? ({",
1955
+ " animation: `pm-rise 820ms ${SNAPPY} ${delay}ms both`,",
1956
+ " '--pm-rise': `${dist}px`,",
1957
+ " } as CSSProperties)",
1958
+ " : {};",
1959
+ "",
1960
+ "const useLive = () => {",
1961
+ " const active = useIsActivePage();",
1962
+ " const [reduced] = useState(",
1963
+ " () =>",
1964
+ " typeof window !== 'undefined' &&",
1965
+ " window.matchMedia('(prefers-reduced-motion: reduce)').matches,",
1966
+ " );",
1967
+ " return active && !reduced;",
1968
+ "};",
1969
+ "",
1970
+ "const useCount = (target: number, live: boolean, delay: number, dur = 1700) => {",
1971
+ " const [value, setValue] = useState(live ? 0 : target);",
1972
+ " useEffect(() => {",
1973
+ " if (!live) {",
1974
+ " setValue(target);",
1975
+ " return;",
1976
+ " }",
1977
+ " setValue(0);",
1978
+ " let raf = 0;",
1979
+ " const start = performance.now() + delay;",
1980
+ " const tick = (now: number) => {",
1981
+ " const p = Math.min(1, Math.max(0, (now - start) / dur));",
1982
+ " setValue(target * (1 - (1 - p) ** 4));",
1983
+ " if (p < 1) raf = requestAnimationFrame(tick);",
1984
+ " };",
1985
+ " raf = requestAnimationFrame(tick);",
1986
+ " return () => cancelAnimationFrame(raf);",
1987
+ " }, [live, target, delay, dur]);",
1988
+ " return value;",
1989
+ "};",
1990
+ "```",
1991
+ "",
1992
+ "Webfont + keyframes, injected once at module top level (key the ids to your slide):",
1993
+ "",
1994
+ "```tsx",
1995
+ "const SLIDE_ID = 'your-slide-id';",
1996
+ "const FONT_HREF =",
1997
+ " 'https://fonts.googleapis.com/css2?family=DM+Mono:wght@500&family=Gabarito:wght@500;700;800;900&display=swap';",
1998
+ "const FONT_LINK_ID = `slides2-webfont-${SLIDE_ID}`;",
1999
+ "const STYLE_ID = `slides2-styles-${SLIDE_ID}`;",
2000
+ "",
2001
+ "const CSS = `",
2002
+ "@keyframes pm-rise { from { opacity: 0; transform: translateY(var(--pm-rise, 32px)) } to { opacity: 1; transform: translateY(0) } }",
2003
+ "@keyframes pm-in-l { from { opacity: 0; transform: translateX(-90px) } to { opacity: 1; transform: translateX(0) } }",
2004
+ "@keyframes pm-fade { from { opacity: 0 } to { opacity: 1 } }",
2005
+ "@keyframes pm-drop { from { transform: translateY(var(--pm-from, -320px)) } to { transform: translateY(0) } }",
2006
+ "@keyframes pm-pop { from { opacity: 0; transform: scale(0) } to { opacity: 1; transform: scale(1) } }",
2007
+ "@keyframes pm-pop-b { from { opacity: 0; transform: translateY(20px) scale(0.55) } to { opacity: 1; transform: translateY(0) scale(1) } }",
2008
+ "@keyframes pm-squash { 0% { transform: scale(1, 1) } 26% { transform: scale(1.14, 0.82) } 56% { transform: scale(0.96, 1.05) } 100% { transform: scale(1, 1) } }",
2009
+ "@keyframes pm-slap {",
2010
+ " 0% { opacity: 0; transform: rotate(calc(var(--r) - 24deg)) scale(1.9) }",
2011
+ " 42% { opacity: 1; transform: rotate(calc(var(--r) + 4deg)) scale(0.88, 0.84) }",
2012
+ " 70% { opacity: 1; transform: rotate(calc(var(--r) - 1.5deg)) scale(1.04) }",
2013
+ " 100% { opacity: 1; transform: rotate(var(--r)) scale(1) }",
2014
+ "}",
2015
+ "@keyframes pm-wobble { 0%, 100% { transform: rotate(0deg) } 50% { transform: rotate(2.6deg) } }",
2016
+ "@keyframes pm-bob { 0%, 100% { transform: translateY(0) } 50% { transform: translateY(-12px) } }",
2017
+ "@keyframes pm-twinkle { 0%, 100% { transform: scale(1) rotate(0deg) } 50% { transform: scale(0.7) rotate(25deg) } }",
2018
+ "@keyframes pm-thunk { 0% { transform: scale(1) } 24% { transform: scale(1.07) rotate(-1.4deg) } 58% { transform: scale(0.985) rotate(0.4deg) } 100% { transform: scale(1) } }",
2019
+ "",
2020
+ "@media (prefers-reduced-motion: reduce) {",
2021
+ " .pm-root *, .pm-root *::before, .pm-root *::after { animation: none !important; transition: none !important; }",
2022
+ "}",
2023
+ "`;",
2024
+ "",
2025
+ "if (typeof document !== 'undefined') {",
2026
+ " let link = document.getElementById(FONT_LINK_ID) as HTMLLinkElement | null;",
2027
+ " if (!link) {",
2028
+ " link = document.createElement('link');",
2029
+ " link.id = FONT_LINK_ID;",
2030
+ " link.rel = 'stylesheet';",
2031
+ " document.head.appendChild(link);",
2032
+ " }",
2033
+ " if (link.href !== FONT_HREF) link.href = FONT_HREF;",
2034
+ "",
2035
+ " let style = document.getElementById(STYLE_ID);",
2036
+ " if (!style) {",
2037
+ " style = document.createElement('style');",
2038
+ " style.id = STYLE_ID;",
2039
+ " document.head.appendChild(style);",
2040
+ " }",
2041
+ " if (style.textContent !== CSS) style.textContent = CSS;",
2042
+ "}",
2043
+ "```",
2044
+ "",
2045
+ "Optional page transition:",
2046
+ "",
2047
+ "```tsx",
2048
+ "import type { SlideTransition } from '@open-slide/core';",
2049
+ "",
2050
+ "export const transition: SlideTransition = {",
2051
+ " duration: 240,",
2052
+ " exit: {",
2053
+ " duration: 240,",
2054
+ " easing: 'cubic-bezier(0.4, 0, 1, 1)',",
2055
+ " keyframes: [{ opacity: 1 }, { opacity: 1 }],",
2056
+ " },",
2057
+ " enter: {",
2058
+ " duration: 240,",
2059
+ " easing: 'cubic-bezier(0, 0, 0.2, 1)',",
2060
+ " keyframes: [",
2061
+ " { opacity: 0, transform: 'translateY(8px)' },",
2062
+ " { opacity: 1, transform: 'translateY(0)' },",
2063
+ " ],",
2064
+ " },",
2065
+ "};",
2066
+ "```",
2067
+ "",
2068
+ "## Aesthetic",
2069
+ "",
2070
+ "A consumer app's pitch deck that feels like a sticker sheet: warm cream paper, thick ink outlines on every shape, flat candy fills (tomato, butter, mint, periwinkle, pink) and hard, blur-free offset shadows that make cards look die-cut and stacked. Type is huge, heavy and tightly tracked; uppercase DM Mono keeps the labels honest. Layouts are poster-like \u2014 big absolute-positioned blocks, a coloured slab on the right, a few tilted stickers and sparkles breaking the grid \u2014 and motion is springy and physical, as if everything was dropped onto the page. Avoid: gradients, soft or blurred shadows, glassmorphism, thin hairline borders, white text on fills, photography, dark mode, and more than one tomato hero per page. If it could be a die-cut sticker on a laptop lid, it is on theme.",
2071
+ "",
2072
+ "## Example usage",
2073
+ "",
2074
+ "```tsx",
2075
+ "const Content: Page = () => {",
2076
+ " const live = useLive();",
2077
+ " const count = useCount(412, live, 600, 1600);",
2078
+ " return (",
2079
+ " <Stage>",
2080
+ ' <Eyebrow n="01" live={live}>',
2081
+ " Highlights",
2082
+ " </Eyebrow>",
2083
+ " <Title live={live} size={96} width={1100}>",
2084
+ " This quarter,",
2085
+ " <br />",
2086
+ " in three numbers.",
2087
+ " </Title>",
2088
+ ' <StatRow y={420} n="3.4\u00d7" color={TOMATO} live={live} delay={260}>',
2089
+ " more weekly active users than at the same point last year",
2090
+ " </StatRow>",
2091
+ ' <StatRow y={576} n="61%" color={BUTTER} live={live} delay={380}>',
2092
+ " of new sign-ups arrived through a friend's invite link",
2093
+ " </StatRow>",
2094
+ ' <StatRow y={732} n="4 s" color={PERI} live={live} delay={500}>',
2095
+ " median time to finish the core action, down from eleven",
2096
+ " </StatRow>",
2097
+ " <Footnote y={898} width={1000}>",
2098
+ " Illustrative figures for the theme preview. Swap in your own numbers and sources.",
2099
+ " </Footnote>",
2100
+ "",
2101
+ " <div",
2102
+ " style={abs(1220, 330, {",
2103
+ " width: 580,",
2104
+ " height: 520,",
2105
+ " boxSizing: 'border-box',",
2106
+ " padding: '40px 44px',",
2107
+ " background: PAPER,",
2108
+ " border: BORDER,",
2109
+ " borderRadius: 34,",
2110
+ " boxShadow: shadow(10),",
2111
+ " display: 'flex',",
2112
+ " flexDirection: 'column',",
2113
+ " ...rise(live, 160, 60),",
2114
+ " })}",
2115
+ " >",
2116
+ " <span style={{ ...MONO, color: MUTED }}>Monthly active homes</span>",
2117
+ " <span",
2118
+ " style={{",
2119
+ " ...NUM,",
2120
+ " fontSize: 200,",
2121
+ " lineHeight: 0.86,",
2122
+ " letterSpacing: '-0.05em',",
2123
+ " marginTop: 24,",
2124
+ " transformOrigin: '0% 80%',",
2125
+ " ...anim(live, 'pm-thunk 620ms ease-out 2200ms both'),",
2126
+ " }}",
2127
+ " >",
2128
+ " {Math.round(count)}k",
2129
+ " </span>",
2130
+ " <p style={{ ...BODY, fontWeight: 700, marginTop: 26 }}>",
2131
+ " households open the app at least once a month.",
2132
+ " </p>",
2133
+ " <div",
2134
+ " style={{",
2135
+ " marginTop: 'auto',",
2136
+ " paddingTop: 22,",
2137
+ " borderTop: `3px dashed ${FAINT}`,",
2138
+ " display: 'flex',",
2139
+ " alignItems: 'baseline',",
2140
+ " gap: 14,",
2141
+ " }}",
2142
+ " >",
2143
+ " <span style={{ ...NUM, fontSize: 44, letterSpacing: '-0.03em' }}>+3.1\u00d7</span>",
2144
+ " <span style={{ ...MONO, fontSize: 16, color: MUTED }}>Year on year</span>",
2145
+ " </div>",
2146
+ " </div>",
2147
+ ' <Sticker x={1600} y={286} r={6} live={live} delay={2300} bg={MINT} pad="10px 20px">',
2148
+ " <span style={{ fontSize: 24, fontWeight: 800 }}>64% organic</span>",
2149
+ " </Sticker>",
2150
+ " <Sparkle x={1180} y={296} size={40} live={live} delay={2450} />",
2151
+ " </Stage>",
2152
+ " );",
2153
+ "};",
2154
+ "```",
2155
+ ].join("\n"),
2156
+ },
2157
+ ] satisfies readonly BuiltInSlideTheme[];
2158
+
2159
+ export function listBuiltInSlideThemeSummaries(): BuiltInSlideThemeSummary[] {
2160
+ return themes.map(({ id, name, description, mode, preview }) => ({
2161
+ id,
2162
+ name,
2163
+ description,
2164
+ mode,
2165
+ preview,
2166
+ }));
2167
+ }
2168
+
2169
+ export function getBuiltInSlideTheme(
2170
+ id: string,
2171
+ ): BuiltInSlideTheme | undefined {
2172
+ const theme = themes.find((candidate) => candidate.id === id);
2173
+ return theme ? structuredClone(theme) : undefined;
2174
+ }