@ryanyahya/opendoc 0.4.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 (789) hide show
  1. package/.agents/skills/opendoc-apply-comments/SKILL.md +30 -0
  2. package/.agents/skills/opendoc-apply-comments/agents/openai.yaml +4 -0
  3. package/.agents/skills/opendoc-create/SKILL.md +63 -0
  4. package/.agents/skills/opendoc-create/agents/openai.yaml +6 -0
  5. package/.agents/skills/opendoc-create-template/SKILL.md +50 -0
  6. package/.agents/skills/opendoc-create-template/agents/openai.yaml +4 -0
  7. package/.agents/skills/opendoc-create-template/references/structured-reports.md +11 -0
  8. package/.agents/skills/opendoc-create-theme/SKILL.md +40 -0
  9. package/.agents/skills/opendoc-create-theme/agents/openai.yaml +4 -0
  10. package/.agents/skills/opendoc-current-document/SKILL.md +32 -0
  11. package/.agents/skills/opendoc-current-document/agents/openai.yaml +4 -0
  12. package/.agents/skills/opendoc-current-document/references/context-fields.md +20 -0
  13. package/.agents/skills/opendoc-review-document/SKILL.md +60 -0
  14. package/.agents/skills/opendoc-review-document/agents/openai.yaml +4 -0
  15. package/AGENTS.md +69 -0
  16. package/CONTRIBUTING.md +38 -0
  17. package/LICENSE +21 -0
  18. package/README.md +179 -0
  19. package/SECURITY.md +9 -0
  20. package/THIRD_PARTY.md +49 -0
  21. package/VALIDATION.md +99 -0
  22. package/bin/opendoc.mjs +6 -0
  23. package/dist/assets/Markdown-sNZyjJi7.js +29 -0
  24. package/dist/assets/OpenDocSerif-Regular-D3OXs9A9.ttf +0 -0
  25. package/dist/assets/OpenDocSerif-Semibold-CjL9oDRo.ttf +0 -0
  26. package/dist/assets/geist-latin-ext-wght-italic-XgKbg5n7.woff2 +0 -0
  27. package/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  28. package/dist/assets/geist-latin-wght-italic-dTnRTFFJ.woff2 +0 -0
  29. package/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  30. package/dist/assets/index-DdrZ6ozO.css +1 -0
  31. package/dist/assets/index-DgNBz7mL.js +39 -0
  32. package/dist/assets/pdf-B7Emtyld.js +54 -0
  33. package/dist/assets/pdf.worker.min-Dswkl-cV.mjs +29 -0
  34. package/dist/assets/wordmark-DsqLlZpb.png +0 -0
  35. package/dist/index.html +17 -0
  36. package/docs/APPEARANCE.md +21 -0
  37. package/docs/ASSETS.md +176 -0
  38. package/docs/AUTHORING.md +178 -0
  39. package/docs/HEADLESS.md +120 -0
  40. package/docs/MEDIA.md +112 -0
  41. package/docs/PROJECTS.md +55 -0
  42. package/docs/PROSE.md +15 -0
  43. package/docs/SELECTION.md +59 -0
  44. package/docs/TEMPLATES.md +55 -0
  45. package/docs/THEMES.md +106 -0
  46. package/node_modules/@formepdf/core/LICENSE +21 -0
  47. package/node_modules/@formepdf/core/README.md +53 -0
  48. package/node_modules/@formepdf/core/dist/attachments.d.ts +55 -0
  49. package/node_modules/@formepdf/core/dist/attachments.js +59 -0
  50. package/node_modules/@formepdf/core/dist/extract.d.ts +8 -0
  51. package/node_modules/@formepdf/core/dist/extract.js +56 -0
  52. package/node_modules/@formepdf/core/dist/index.d.ts +311 -0
  53. package/node_modules/@formepdf/core/dist/index.js +167 -0
  54. package/node_modules/@formepdf/core/dist/layout.d.ts +132 -0
  55. package/node_modules/@formepdf/core/dist/layout.js +240 -0
  56. package/node_modules/@formepdf/core/dist/shared/browserHelpers.d.ts +19 -0
  57. package/node_modules/@formepdf/core/dist/shared/browserHelpers.js +128 -0
  58. package/node_modules/@formepdf/core/package.json +35 -0
  59. package/node_modules/@formepdf/core/pkg-node/LICENSE +21 -0
  60. package/node_modules/@formepdf/core/pkg-node/README.md +84 -0
  61. package/node_modules/@formepdf/core/pkg-node/forme.d.ts +39 -0
  62. package/node_modules/@formepdf/core/pkg-node/forme.js +394 -0
  63. package/node_modules/@formepdf/core/pkg-node/forme_bg.wasm +0 -0
  64. package/node_modules/@formepdf/core/pkg-node/forme_bg.wasm.d.ts +21 -0
  65. package/node_modules/@formepdf/core/pkg-node/package.json +25 -0
  66. package/node_modules/@formepdf/react/README.md +70 -0
  67. package/node_modules/@formepdf/react/dist/charts.d.ts +72 -0
  68. package/node_modules/@formepdf/react/dist/charts.js +338 -0
  69. package/node_modules/@formepdf/react/dist/components.d.ts +533 -0
  70. package/node_modules/@formepdf/react/dist/components.js +608 -0
  71. package/node_modules/@formepdf/react/dist/expr.d.ts +20 -0
  72. package/node_modules/@formepdf/react/dist/expr.js +39 -0
  73. package/node_modules/@formepdf/react/dist/font.d.ts +2 -0
  74. package/node_modules/@formepdf/react/dist/font.js +1 -0
  75. package/node_modules/@formepdf/react/dist/index.d.ts +11 -0
  76. package/node_modules/@formepdf/react/dist/index.js +15 -0
  77. package/node_modules/@formepdf/react/dist/render.d.ts +12 -0
  78. package/node_modules/@formepdf/react/dist/render.js +15 -0
  79. package/node_modules/@formepdf/react/dist/serialize.d.ts +12 -0
  80. package/node_modules/@formepdf/react/dist/serialize.js +1470 -0
  81. package/node_modules/@formepdf/react/dist/stylesheet.d.ts +4 -0
  82. package/node_modules/@formepdf/react/dist/stylesheet.js +5 -0
  83. package/node_modules/@formepdf/react/dist/template-proxy.d.ts +38 -0
  84. package/node_modules/@formepdf/react/dist/template-proxy.js +100 -0
  85. package/node_modules/@formepdf/react/dist/types.d.ts +287 -0
  86. package/node_modules/@formepdf/react/dist/types.js +1 -0
  87. package/node_modules/@formepdf/react/package.json +41 -0
  88. package/node_modules/@formepdf/shared/README.md +7 -0
  89. package/node_modules/@formepdf/shared/dist/canvas.d.ts +6 -0
  90. package/node_modules/@formepdf/shared/dist/canvas.js +43 -0
  91. package/node_modules/@formepdf/shared/dist/charts.d.ts +100 -0
  92. package/node_modules/@formepdf/shared/dist/charts.js +98 -0
  93. package/node_modules/@formepdf/shared/dist/encode.d.ts +27 -0
  94. package/node_modules/@formepdf/shared/dist/encode.js +93 -0
  95. package/node_modules/@formepdf/shared/dist/font.d.ts +13 -0
  96. package/node_modules/@formepdf/shared/dist/font.js +52 -0
  97. package/node_modules/@formepdf/shared/dist/index.d.ts +10 -0
  98. package/node_modules/@formepdf/shared/dist/index.js +15 -0
  99. package/node_modules/@formepdf/shared/dist/parser.d.ts +30 -0
  100. package/node_modules/@formepdf/shared/dist/parser.js +756 -0
  101. package/node_modules/@formepdf/shared/dist/semantics.d.ts +15 -0
  102. package/node_modules/@formepdf/shared/dist/semantics.js +44 -0
  103. package/node_modules/@formepdf/shared/dist/style.d.ts +7 -0
  104. package/node_modules/@formepdf/shared/dist/style.js +1024 -0
  105. package/node_modules/@formepdf/shared/dist/types.d.ts +743 -0
  106. package/node_modules/@formepdf/shared/dist/types.js +2 -0
  107. package/node_modules/@formepdf/shared/package.json +35 -0
  108. package/node_modules/@types/node/LICENSE +21 -0
  109. package/node_modules/@types/node/README.md +15 -0
  110. package/node_modules/@types/node/assert/strict.d.ts +111 -0
  111. package/node_modules/@types/node/assert.d.ts +1078 -0
  112. package/node_modules/@types/node/async_hooks.d.ts +603 -0
  113. package/node_modules/@types/node/buffer.buffer.d.ts +472 -0
  114. package/node_modules/@types/node/buffer.d.ts +1934 -0
  115. package/node_modules/@types/node/child_process.d.ts +1476 -0
  116. package/node_modules/@types/node/cluster.d.ts +578 -0
  117. package/node_modules/@types/node/compatibility/disposable.d.ts +14 -0
  118. package/node_modules/@types/node/compatibility/index.d.ts +9 -0
  119. package/node_modules/@types/node/compatibility/indexable.d.ts +20 -0
  120. package/node_modules/@types/node/compatibility/iterators.d.ts +20 -0
  121. package/node_modules/@types/node/console.d.ts +452 -0
  122. package/node_modules/@types/node/constants.d.ts +21 -0
  123. package/node_modules/@types/node/crypto.d.ts +4545 -0
  124. package/node_modules/@types/node/dgram.d.ts +600 -0
  125. package/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
  126. package/node_modules/@types/node/dns/promises.d.ts +503 -0
  127. package/node_modules/@types/node/dns.d.ts +923 -0
  128. package/node_modules/@types/node/domain.d.ts +170 -0
  129. package/node_modules/@types/node/events.d.ts +976 -0
  130. package/node_modules/@types/node/fs/promises.d.ts +1306 -0
  131. package/node_modules/@types/node/fs.d.ts +4463 -0
  132. package/node_modules/@types/node/globals.d.ts +172 -0
  133. package/node_modules/@types/node/globals.typedarray.d.ts +38 -0
  134. package/node_modules/@types/node/http.d.ts +2097 -0
  135. package/node_modules/@types/node/http2.d.ts +2843 -0
  136. package/node_modules/@types/node/https.d.ts +579 -0
  137. package/node_modules/@types/node/index.d.ts +98 -0
  138. package/node_modules/@types/node/inspector.d.ts +253 -0
  139. package/node_modules/@types/node/inspector.generated.d.ts +4052 -0
  140. package/node_modules/@types/node/module.d.ts +891 -0
  141. package/node_modules/@types/node/net.d.ts +1076 -0
  142. package/node_modules/@types/node/os.d.ts +506 -0
  143. package/node_modules/@types/node/package.json +145 -0
  144. package/node_modules/@types/node/path.d.ts +200 -0
  145. package/node_modules/@types/node/perf_hooks.d.ts +968 -0
  146. package/node_modules/@types/node/process.d.ts +2084 -0
  147. package/node_modules/@types/node/punycode.d.ts +117 -0
  148. package/node_modules/@types/node/querystring.d.ts +152 -0
  149. package/node_modules/@types/node/readline/promises.d.ts +161 -0
  150. package/node_modules/@types/node/readline.d.ts +594 -0
  151. package/node_modules/@types/node/repl.d.ts +428 -0
  152. package/node_modules/@types/node/sea.d.ts +162 -0
  153. package/node_modules/@types/node/sqlite.d.ts +722 -0
  154. package/node_modules/@types/node/stream/consumers.d.ts +38 -0
  155. package/node_modules/@types/node/stream/promises.d.ts +90 -0
  156. package/node_modules/@types/node/stream/web.d.ts +573 -0
  157. package/node_modules/@types/node/stream.d.ts +1694 -0
  158. package/node_modules/@types/node/string_decoder.d.ts +67 -0
  159. package/node_modules/@types/node/test.d.ts +2265 -0
  160. package/node_modules/@types/node/timers/promises.d.ts +108 -0
  161. package/node_modules/@types/node/timers.d.ts +287 -0
  162. package/node_modules/@types/node/tls.d.ts +1319 -0
  163. package/node_modules/@types/node/trace_events.d.ts +197 -0
  164. package/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +468 -0
  165. package/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +34 -0
  166. package/node_modules/@types/node/ts5.6/index.d.ts +98 -0
  167. package/node_modules/@types/node/tty.d.ts +208 -0
  168. package/node_modules/@types/node/url.d.ts +984 -0
  169. package/node_modules/@types/node/util.d.ts +2606 -0
  170. package/node_modules/@types/node/v8.d.ts +920 -0
  171. package/node_modules/@types/node/vm.d.ts +1053 -0
  172. package/node_modules/@types/node/wasi.d.ts +181 -0
  173. package/node_modules/@types/node/web-globals/abortcontroller.d.ts +34 -0
  174. package/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
  175. package/node_modules/@types/node/web-globals/events.d.ts +97 -0
  176. package/node_modules/@types/node/web-globals/fetch.d.ts +55 -0
  177. package/node_modules/@types/node/web-globals/navigator.d.ts +22 -0
  178. package/node_modules/@types/node/web-globals/storage.d.ts +24 -0
  179. package/node_modules/@types/node/web-globals/streams.d.ts +22 -0
  180. package/node_modules/@types/node/worker_threads.d.ts +819 -0
  181. package/node_modules/@types/node/zlib.d.ts +747 -0
  182. package/node_modules/@types/react/LICENSE +21 -0
  183. package/node_modules/@types/react/README.md +15 -0
  184. package/node_modules/@types/react/canary.d.ts +129 -0
  185. package/node_modules/@types/react/compiler-runtime.d.ts +4 -0
  186. package/node_modules/@types/react/experimental.d.ts +184 -0
  187. package/node_modules/@types/react/global.d.ts +166 -0
  188. package/node_modules/@types/react/index.d.ts +4378 -0
  189. package/node_modules/@types/react/jsx-dev-runtime.d.ts +33 -0
  190. package/node_modules/@types/react/jsx-runtime.d.ts +24 -0
  191. package/node_modules/@types/react/package.json +210 -0
  192. package/node_modules/@types/react/ts5.0/canary.d.ts +129 -0
  193. package/node_modules/@types/react/ts5.0/experimental.d.ts +184 -0
  194. package/node_modules/@types/react/ts5.0/global.d.ts +166 -0
  195. package/node_modules/@types/react/ts5.0/index.d.ts +4365 -0
  196. package/node_modules/@types/react/ts5.0/jsx-dev-runtime.d.ts +33 -0
  197. package/node_modules/@types/react/ts5.0/jsx-runtime.d.ts +24 -0
  198. package/node_modules/csstype/LICENSE +19 -0
  199. package/node_modules/csstype/README.md +291 -0
  200. package/node_modules/csstype/index.d.ts +22569 -0
  201. package/node_modules/csstype/index.js.flow +6863 -0
  202. package/node_modules/csstype/package.json +70 -0
  203. package/node_modules/entities/LICENSE +11 -0
  204. package/node_modules/entities/decode.d.ts +1 -0
  205. package/node_modules/entities/decode.js +3 -0
  206. package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts +19 -0
  207. package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts.map +1 -0
  208. package/node_modules/entities/dist/commonjs/decode-codepoint.js +77 -0
  209. package/node_modules/entities/dist/commonjs/decode-codepoint.js.map +1 -0
  210. package/node_modules/entities/dist/commonjs/decode.d.ts +209 -0
  211. package/node_modules/entities/dist/commonjs/decode.d.ts.map +1 -0
  212. package/node_modules/entities/dist/commonjs/decode.js +511 -0
  213. package/node_modules/entities/dist/commonjs/decode.js.map +1 -0
  214. package/node_modules/entities/dist/commonjs/encode.d.ts +22 -0
  215. package/node_modules/entities/dist/commonjs/encode.d.ts.map +1 -0
  216. package/node_modules/entities/dist/commonjs/encode.js +73 -0
  217. package/node_modules/entities/dist/commonjs/encode.js.map +1 -0
  218. package/node_modules/entities/dist/commonjs/escape.d.ts +43 -0
  219. package/node_modules/entities/dist/commonjs/escape.d.ts.map +1 -0
  220. package/node_modules/entities/dist/commonjs/escape.js +121 -0
  221. package/node_modules/entities/dist/commonjs/escape.js.map +1 -0
  222. package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts +2 -0
  223. package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts.map +1 -0
  224. package/node_modules/entities/dist/commonjs/generated/decode-data-html.js +10 -0
  225. package/node_modules/entities/dist/commonjs/generated/decode-data-html.js.map +1 -0
  226. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts +2 -0
  227. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts.map +1 -0
  228. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js +10 -0
  229. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js.map +1 -0
  230. package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts +8 -0
  231. package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts.map +1 -0
  232. package/node_modules/entities/dist/commonjs/generated/encode-html.js +13 -0
  233. package/node_modules/entities/dist/commonjs/generated/encode-html.js.map +1 -0
  234. package/node_modules/entities/dist/commonjs/index.d.ts +96 -0
  235. package/node_modules/entities/dist/commonjs/index.d.ts.map +1 -0
  236. package/node_modules/entities/dist/commonjs/index.js +131 -0
  237. package/node_modules/entities/dist/commonjs/index.js.map +1 -0
  238. package/node_modules/entities/dist/commonjs/package.json +3 -0
  239. package/node_modules/entities/dist/esm/decode-codepoint.d.ts +19 -0
  240. package/node_modules/entities/dist/esm/decode-codepoint.d.ts.map +1 -0
  241. package/node_modules/entities/dist/esm/decode-codepoint.js +72 -0
  242. package/node_modules/entities/dist/esm/decode-codepoint.js.map +1 -0
  243. package/node_modules/entities/dist/esm/decode.d.ts +209 -0
  244. package/node_modules/entities/dist/esm/decode.d.ts.map +1 -0
  245. package/node_modules/entities/dist/esm/decode.js +497 -0
  246. package/node_modules/entities/dist/esm/decode.js.map +1 -0
  247. package/node_modules/entities/dist/esm/encode.d.ts +22 -0
  248. package/node_modules/entities/dist/esm/encode.d.ts.map +1 -0
  249. package/node_modules/entities/dist/esm/encode.js +69 -0
  250. package/node_modules/entities/dist/esm/encode.js.map +1 -0
  251. package/node_modules/entities/dist/esm/escape.d.ts +43 -0
  252. package/node_modules/entities/dist/esm/escape.d.ts.map +1 -0
  253. package/node_modules/entities/dist/esm/escape.js +117 -0
  254. package/node_modules/entities/dist/esm/escape.js.map +1 -0
  255. package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts +2 -0
  256. package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts.map +1 -0
  257. package/node_modules/entities/dist/esm/generated/decode-data-html.js +7 -0
  258. package/node_modules/entities/dist/esm/generated/decode-data-html.js.map +1 -0
  259. package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts +2 -0
  260. package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts.map +1 -0
  261. package/node_modules/entities/dist/esm/generated/decode-data-xml.js +7 -0
  262. package/node_modules/entities/dist/esm/generated/decode-data-xml.js.map +1 -0
  263. package/node_modules/entities/dist/esm/generated/encode-html.d.ts +8 -0
  264. package/node_modules/entities/dist/esm/generated/encode-html.d.ts.map +1 -0
  265. package/node_modules/entities/dist/esm/generated/encode-html.js +10 -0
  266. package/node_modules/entities/dist/esm/generated/encode-html.js.map +1 -0
  267. package/node_modules/entities/dist/esm/index.d.ts +96 -0
  268. package/node_modules/entities/dist/esm/index.d.ts.map +1 -0
  269. package/node_modules/entities/dist/esm/index.js +107 -0
  270. package/node_modules/entities/dist/esm/index.js.map +1 -0
  271. package/node_modules/entities/dist/esm/package.json +3 -0
  272. package/node_modules/entities/escape.d.ts +1 -0
  273. package/node_modules/entities/escape.js +3 -0
  274. package/node_modules/entities/package.json +118 -0
  275. package/node_modules/entities/readme.md +122 -0
  276. package/node_modules/entities/src/decode-codepoint.ts +81 -0
  277. package/node_modules/entities/src/decode.spec.ts +320 -0
  278. package/node_modules/entities/src/decode.ts +620 -0
  279. package/node_modules/entities/src/encode.spec.ts +78 -0
  280. package/node_modules/entities/src/encode.ts +77 -0
  281. package/node_modules/entities/src/escape.spec.ts +14 -0
  282. package/node_modules/entities/src/escape.ts +148 -0
  283. package/node_modules/entities/src/generated/.eslintrc.json +10 -0
  284. package/node_modules/entities/src/generated/decode-data-html.ts +8 -0
  285. package/node_modules/entities/src/generated/decode-data-xml.ts +8 -0
  286. package/node_modules/entities/src/generated/encode-html.ts +17 -0
  287. package/node_modules/entities/src/index.spec.ts +125 -0
  288. package/node_modules/entities/src/index.ts +188 -0
  289. package/node_modules/parse5/LICENSE +19 -0
  290. package/node_modules/parse5/README.md +38 -0
  291. package/node_modules/parse5/dist/cjs/common/doctype.d.ts +4 -0
  292. package/node_modules/parse5/dist/cjs/common/doctype.js +118 -0
  293. package/node_modules/parse5/dist/cjs/common/error-codes.d.ts +67 -0
  294. package/node_modules/parse5/dist/cjs/common/error-codes.js +66 -0
  295. package/node_modules/parse5/dist/cjs/common/foreign-content.d.ts +9 -0
  296. package/node_modules/parse5/dist/cjs/common/foreign-content.js +237 -0
  297. package/node_modules/parse5/dist/cjs/common/html.d.ts +289 -0
  298. package/node_modules/parse5/dist/cjs/common/html.js +528 -0
  299. package/node_modules/parse5/dist/cjs/common/token.d.ts +84 -0
  300. package/node_modules/parse5/dist/cjs/common/token.js +24 -0
  301. package/node_modules/parse5/dist/cjs/common/unicode.d.ts +42 -0
  302. package/node_modules/parse5/dist/cjs/common/unicode.js +70 -0
  303. package/node_modules/parse5/dist/cjs/index.d.ts +71 -0
  304. package/node_modules/parse5/dist/cjs/index.js +54 -0
  305. package/node_modules/parse5/dist/cjs/package.json +1 -0
  306. package/node_modules/parse5/dist/cjs/parser/formatting-element-list.d.ts +36 -0
  307. package/node_modules/parse5/dist/cjs/parser/formatting-element-list.js +114 -0
  308. package/node_modules/parse5/dist/cjs/parser/index.d.ts +221 -0
  309. package/node_modules/parse5/dist/cjs/parser/index.js +3240 -0
  310. package/node_modules/parse5/dist/cjs/parser/open-element-stack.d.ts +53 -0
  311. package/node_modules/parse5/dist/cjs/parser/open-element-stack.js +328 -0
  312. package/node_modules/parse5/dist/cjs/serializer/index.d.ts +60 -0
  313. package/node_modules/parse5/dist/cjs/serializer/index.js +172 -0
  314. package/node_modules/parse5/dist/cjs/tokenizer/index.d.ts +247 -0
  315. package/node_modules/parse5/dist/cjs/tokenizer/index.js +2714 -0
  316. package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.d.ts +36 -0
  317. package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.js +200 -0
  318. package/node_modules/parse5/dist/cjs/tree-adapters/default.d.ts +84 -0
  319. package/node_modules/parse5/dist/cjs/tree-adapters/default.js +176 -0
  320. package/node_modules/parse5/dist/cjs/tree-adapters/interface.d.ts +255 -0
  321. package/node_modules/parse5/dist/cjs/tree-adapters/interface.js +2 -0
  322. package/node_modules/parse5/dist/common/doctype.d.ts +4 -0
  323. package/node_modules/parse5/dist/common/doctype.js +114 -0
  324. package/node_modules/parse5/dist/common/error-codes.d.ts +67 -0
  325. package/node_modules/parse5/dist/common/error-codes.js +63 -0
  326. package/node_modules/parse5/dist/common/foreign-content.d.ts +9 -0
  327. package/node_modules/parse5/dist/common/foreign-content.js +228 -0
  328. package/node_modules/parse5/dist/common/html.d.ts +289 -0
  329. package/node_modules/parse5/dist/common/html.js +523 -0
  330. package/node_modules/parse5/dist/common/token.d.ts +84 -0
  331. package/node_modules/parse5/dist/common/token.js +20 -0
  332. package/node_modules/parse5/dist/common/unicode.d.ts +42 -0
  333. package/node_modules/parse5/dist/common/unicode.js +62 -0
  334. package/node_modules/parse5/dist/index.d.ts +71 -0
  335. package/node_modules/parse5/dist/index.js +42 -0
  336. package/node_modules/parse5/dist/parser/formatting-element-list.d.ts +36 -0
  337. package/node_modules/parse5/dist/parser/formatting-element-list.js +110 -0
  338. package/node_modules/parse5/dist/parser/index.d.ts +221 -0
  339. package/node_modules/parse5/dist/parser/index.js +3245 -0
  340. package/node_modules/parse5/dist/parser/open-element-stack.d.ts +53 -0
  341. package/node_modules/parse5/dist/parser/open-element-stack.js +324 -0
  342. package/node_modules/parse5/dist/serializer/index.d.ts +60 -0
  343. package/node_modules/parse5/dist/serializer/index.js +168 -0
  344. package/node_modules/parse5/dist/tokenizer/index.d.ts +247 -0
  345. package/node_modules/parse5/dist/tokenizer/index.js +2710 -0
  346. package/node_modules/parse5/dist/tokenizer/preprocessor.d.ts +36 -0
  347. package/node_modules/parse5/dist/tokenizer/preprocessor.js +196 -0
  348. package/node_modules/parse5/dist/tree-adapters/default.d.ts +84 -0
  349. package/node_modules/parse5/dist/tree-adapters/default.js +173 -0
  350. package/node_modules/parse5/dist/tree-adapters/interface.d.ts +255 -0
  351. package/node_modules/parse5/dist/tree-adapters/interface.js +1 -0
  352. package/node_modules/parse5/package.json +50 -0
  353. package/node_modules/undici-types/LICENSE +21 -0
  354. package/node_modules/undici-types/README.md +6 -0
  355. package/node_modules/undici-types/agent.d.ts +31 -0
  356. package/node_modules/undici-types/api.d.ts +43 -0
  357. package/node_modules/undici-types/balanced-pool.d.ts +29 -0
  358. package/node_modules/undici-types/cache.d.ts +36 -0
  359. package/node_modules/undici-types/client.d.ts +108 -0
  360. package/node_modules/undici-types/connector.d.ts +34 -0
  361. package/node_modules/undici-types/content-type.d.ts +21 -0
  362. package/node_modules/undici-types/cookies.d.ts +28 -0
  363. package/node_modules/undici-types/diagnostics-channel.d.ts +66 -0
  364. package/node_modules/undici-types/dispatcher.d.ts +256 -0
  365. package/node_modules/undici-types/env-http-proxy-agent.d.ts +21 -0
  366. package/node_modules/undici-types/errors.d.ts +149 -0
  367. package/node_modules/undici-types/eventsource.d.ts +61 -0
  368. package/node_modules/undici-types/fetch.d.ts +209 -0
  369. package/node_modules/undici-types/file.d.ts +39 -0
  370. package/node_modules/undici-types/filereader.d.ts +54 -0
  371. package/node_modules/undici-types/formdata.d.ts +108 -0
  372. package/node_modules/undici-types/global-dispatcher.d.ts +9 -0
  373. package/node_modules/undici-types/global-origin.d.ts +7 -0
  374. package/node_modules/undici-types/handlers.d.ts +15 -0
  375. package/node_modules/undici-types/header.d.ts +4 -0
  376. package/node_modules/undici-types/index.d.ts +71 -0
  377. package/node_modules/undici-types/interceptors.d.ts +17 -0
  378. package/node_modules/undici-types/mock-agent.d.ts +50 -0
  379. package/node_modules/undici-types/mock-client.d.ts +25 -0
  380. package/node_modules/undici-types/mock-errors.d.ts +12 -0
  381. package/node_modules/undici-types/mock-interceptor.d.ts +93 -0
  382. package/node_modules/undici-types/mock-pool.d.ts +25 -0
  383. package/node_modules/undici-types/package.json +55 -0
  384. package/node_modules/undici-types/patch.d.ts +33 -0
  385. package/node_modules/undici-types/pool-stats.d.ts +19 -0
  386. package/node_modules/undici-types/pool.d.ts +39 -0
  387. package/node_modules/undici-types/proxy-agent.d.ts +28 -0
  388. package/node_modules/undici-types/readable.d.ts +65 -0
  389. package/node_modules/undici-types/retry-agent.d.ts +8 -0
  390. package/node_modules/undici-types/retry-handler.d.ts +116 -0
  391. package/node_modules/undici-types/util.d.ts +18 -0
  392. package/node_modules/undici-types/webidl.d.ts +228 -0
  393. package/node_modules/undici-types/websocket.d.ts +150 -0
  394. package/package.json +80 -0
  395. package/scripts/rebuild-forme.mjs +61 -0
  396. package/src/app/AppearanceControl.tsx +44 -0
  397. package/src/app/AssetThemeDefaults.tsx +87 -0
  398. package/src/app/AssetsBrowser.tsx +273 -0
  399. package/src/app/CommentDock.tsx +108 -0
  400. package/src/app/CreateDocumentDialog.tsx +51 -0
  401. package/src/app/DocumentActions.tsx +69 -0
  402. package/src/app/DocumentCard.tsx +50 -0
  403. package/src/app/DocumentViewControl.tsx +31 -0
  404. package/src/app/DocumentsBrowser.tsx +70 -0
  405. package/src/app/ExportHistoryDialog.tsx +86 -0
  406. package/src/app/ExportMenu.tsx +127 -0
  407. package/src/app/GuideDialog.tsx +80 -0
  408. package/src/app/InspectionLayer.tsx +77 -0
  409. package/src/app/LogoUploadDialog.tsx +92 -0
  410. package/src/app/Markdown.tsx +34 -0
  411. package/src/app/MaterialsBrowser.tsx +149 -0
  412. package/src/app/PageNumberInput.tsx +56 -0
  413. package/src/app/Pdf.tsx +561 -0
  414. package/src/app/ProjectDialogs.tsx +100 -0
  415. package/src/app/Reader.tsx +769 -0
  416. package/src/app/SearchField.tsx +13 -0
  417. package/src/app/Sidebar.tsx +86 -0
  418. package/src/app/SkillIndex.tsx +30 -0
  419. package/src/app/TemplatesBrowser.tsx +149 -0
  420. package/src/app/ThemesBrowser.tsx +159 -0
  421. package/src/app/api.ts +47 -0
  422. package/src/app/appearance.ts +35 -0
  423. package/src/app/assets.css +139 -0
  424. package/src/app/catalogPreview.ts +20 -0
  425. package/src/app/colors.css +167 -0
  426. package/src/app/comment-dock.css +53 -0
  427. package/src/app/commentDrafts.ts +67 -0
  428. package/src/app/componentCorrection.ts +17 -0
  429. package/src/app/edit-workbench.css +87 -0
  430. package/src/app/editSession.ts +238 -0
  431. package/src/app/editorRecovery.ts +25 -0
  432. package/src/app/export-history.css +31 -0
  433. package/src/app/export.css +17 -0
  434. package/src/app/guideLinks.ts +21 -0
  435. package/src/app/guides.css +40 -0
  436. package/src/app/main.tsx +221 -0
  437. package/src/app/materials.css +53 -0
  438. package/src/app/pdfLoading.ts +12 -0
  439. package/src/app/pdfSelection.ts +112 -0
  440. package/src/app/projects.css +63 -0
  441. package/src/app/reader-toolbar.css +65 -0
  442. package/src/app/selection.css +150 -0
  443. package/src/app/sidebar.css +60 -0
  444. package/src/app/skills.css +7 -0
  445. package/src/app/style.css +1061 -0
  446. package/src/app/templates.css +49 -0
  447. package/src/app/themes.css +80 -0
  448. package/src/app/ui/Icon.tsx +92 -0
  449. package/src/app/ui/README.md +27 -0
  450. package/src/app/ui/fonts.css +36 -0
  451. package/src/app/ui/index.tsx +223 -0
  452. package/src/app/ui/ui.css +388 -0
  453. package/src/app/useReaderPreview.ts +19 -0
  454. package/src/app/useTextEditing.ts +155 -0
  455. package/src/assets/adapter.ts +122 -0
  456. package/src/assets/files.ts +378 -0
  457. package/src/assets/import-worker.ts +294 -0
  458. package/src/assets/imports.ts +124 -0
  459. package/src/assets/index.ts +60 -0
  460. package/src/assets/store.ts +798 -0
  461. package/src/assets/usage.ts +118 -0
  462. package/src/cli/check.ts +25 -0
  463. package/src/cli/init.ts +119 -0
  464. package/src/cli/lock.ts +34 -0
  465. package/src/cli/main.ts +118 -0
  466. package/src/cli/process.ts +19 -0
  467. package/src/cli/start.ts +96 -0
  468. package/src/cli/update.ts +348 -0
  469. package/src/cli/workspace.ts +94 -0
  470. package/src/document/index.tsx +641 -0
  471. package/src/document/page.tsx +53 -0
  472. package/src/document/text-targets.tsx +162 -0
  473. package/src/media/files.ts +124 -0
  474. package/src/media/render.ts +63 -0
  475. package/src/rendering/resolve-sources.ts +84 -0
  476. package/src/runtime/jsx-dev-runtime.ts +2 -0
  477. package/src/runtime/jsx-runtime.ts +2 -0
  478. package/src/runtime/paths.ts +12 -0
  479. package/src/server/assets-cli.ts +162 -0
  480. package/src/server/assets-http.ts +100 -0
  481. package/src/server/client.ts +50 -0
  482. package/src/server/clipboard.ts +22 -0
  483. package/src/server/comments-cli.ts +64 -0
  484. package/src/server/comments.ts +130 -0
  485. package/src/server/create-cli.ts +33 -0
  486. package/src/server/create.ts +228 -0
  487. package/src/server/dependencies.ts +91 -0
  488. package/src/server/documents.ts +143 -0
  489. package/src/server/edits.ts +249 -0
  490. package/src/server/export-batch.ts +105 -0
  491. package/src/server/export-errors.ts +2 -0
  492. package/src/server/export-file.ts +57 -0
  493. package/src/server/export-inputs.ts +66 -0
  494. package/src/server/export-preview.ts +69 -0
  495. package/src/server/export.ts +32 -0
  496. package/src/server/exports.ts +283 -0
  497. package/src/server/files.ts +21 -0
  498. package/src/server/guides.ts +71 -0
  499. package/src/server/index.ts +432 -0
  500. package/src/server/materials.ts +39 -0
  501. package/src/server/media-cli.ts +73 -0
  502. package/src/server/media-mutations.ts +168 -0
  503. package/src/server/pptx.ts +160 -0
  504. package/src/server/preflight.ts +129 -0
  505. package/src/server/projects-cli.ts +29 -0
  506. package/src/server/projects.ts +187 -0
  507. package/src/server/render-error.ts +9 -0
  508. package/src/server/render-source.ts +24 -0
  509. package/src/server/render.ts +48 -0
  510. package/src/server/review-cli.ts +40 -0
  511. package/src/server/review.ts +161 -0
  512. package/src/server/selection.ts +23 -0
  513. package/src/server/source-overrides.ts +97 -0
  514. package/src/server/templates-cli.ts +51 -0
  515. package/src/server/templates.ts +186 -0
  516. package/src/server/text-layout.ts +41 -0
  517. package/src/server/text-source.ts +307 -0
  518. package/src/server/themes-cli.ts +59 -0
  519. package/src/server/themes.ts +215 -0
  520. package/src/server/ttf2eot.d.ts +3 -0
  521. package/src/server/worker.ts +166 -0
  522. package/src/server/workspace.ts +242 -0
  523. package/src/shared/anchors.ts +69 -0
  524. package/src/shared/assets.ts +154 -0
  525. package/src/shared/export.ts +34 -0
  526. package/src/shared/media.ts +33 -0
  527. package/src/shared/projects.ts +19 -0
  528. package/src/shared/selection.ts +94 -0
  529. package/src/shared/skill-index.ts +14 -0
  530. package/src/shared/starters.ts +19 -0
  531. package/src/shared/templates.ts +18 -0
  532. package/src/shared/themes.ts +24 -0
  533. package/src/shared/types.ts +39 -0
  534. package/src/template/index.ts +27 -0
  535. package/src/themes/index.ts +3 -0
  536. package/src/themes/neutral.ts +20 -0
  537. package/src/themes/types.ts +110 -0
  538. package/starter/assets/brand/wordmark.png +0 -0
  539. package/starter/assets/fonts/InterUI-LICENSE.txt +93 -0
  540. package/starter/assets/fonts/InterUI-Medium.ttf +0 -0
  541. package/starter/assets/fonts/InterUI-Regular.ttf +0 -0
  542. package/starter/assets/fonts/InterUI-source.json +19 -0
  543. package/starter/assets/fonts/OpenDocMono-Regular.ttf +0 -0
  544. package/starter/assets/fonts/OpenDocSans-Italic.ttf +0 -0
  545. package/starter/assets/fonts/OpenDocSans-Regular.ttf +0 -0
  546. package/starter/assets/fonts/OpenDocSans-Semibold.ttf +0 -0
  547. package/starter/assets/fonts/OpenDocSans-SemiboldItalic.ttf +0 -0
  548. package/starter/assets/fonts/OpenDocSerif-Italic.ttf +0 -0
  549. package/starter/assets/fonts/OpenDocSerif-Regular.ttf +0 -0
  550. package/starter/assets/fonts/OpenDocSerif-Semibold.ttf +0 -0
  551. package/starter/assets/fonts/OpenDocSerif-SemiboldItalic.ttf +0 -0
  552. package/starter/assets/fonts/SourceCode-LICENSE.md +93 -0
  553. package/starter/assets/fonts/SourceSans-LICENSE.md +93 -0
  554. package/starter/assets/fonts/SourceSerif-LICENSE.md +93 -0
  555. package/starter/assets/fonts/geist/OFL.txt +93 -0
  556. package/starter/assets/fonts/geist/asset.json +7 -0
  557. package/starter/assets/fonts/geist/files/1a9874b3be0fc168692a3d2327bccb4d28835653d3b91537a755296a467a83e3.ttf +0 -0
  558. package/starter/assets/fonts/geist/files/a8eefb873ba9c9020665f8a98302697ce1f3b79ab2deef6ee508c0ca6a82e876.ttf +0 -0
  559. package/starter/assets/fonts/geist/files/ccce59465ae5c61930ada5453834f60500fbd95084d85db63e0e65fad0125455.ttf +0 -0
  560. package/starter/assets/fonts/geist/files/f5e95110d70593672515080bee9148463ada0a7f77b89ed65a3d43cb2b0ff83a.pdf +0 -0
  561. package/starter/assets/fonts/geist/revisions/9a2bc12fb2f23cb27bc227087e63e1407bb804ee0586480bd6b7966ec69fb474.json +60 -0
  562. package/starter/assets/fonts/inter/OFL.txt +93 -0
  563. package/starter/assets/fonts/inter/asset.json +7 -0
  564. package/starter/assets/fonts/inter/files/1b08e7fc267a5c7e1d614100f604b83e7e8a0be241f0f288faa2b3ac93a683ba.ttf +0 -0
  565. package/starter/assets/fonts/inter/files/5b6f0c6f26e5c554a64cdcc3a9b5d802b7f9aec6206f1dbcfcdcad7b5860a2a9.ttf +0 -0
  566. package/starter/assets/fonts/inter/files/957db8560d510a198a7d0333fae7b6b444b00c20801581126273978d778eb3c3.pdf +0 -0
  567. package/starter/assets/fonts/inter/files/b37284b5701b6b168dfc770aa1a4ac492106422fd3ba76bc7641e37434e8019c.ttf +0 -0
  568. package/starter/assets/fonts/inter/files/c1811d32ac0f6eed1bbf57529f2ecdfc6c717d48a969dd864942436315a1b198.ttf +0 -0
  569. package/starter/assets/fonts/inter/files/e7a1aaf7eda9f2fad4131725fa556265ec75ca7b2d756260173a040363e8d4f7.ttf +0 -0
  570. package/starter/assets/fonts/inter/files/ef8f755d933b9310804cc9152f1f18cb2ac460d6b05054ec913d889c9f11f79e.ttf +0 -0
  571. package/starter/assets/fonts/inter/revisions/600391517c413963b71e278a57c26c40366c81fa3939a6b9755f446206766d12.json +99 -0
  572. package/starter/assets/fonts/inter/source.json +57 -0
  573. package/starter/assets/fonts/lato/OFL.txt +93 -0
  574. package/starter/assets/fonts/lato/asset.json +7 -0
  575. package/starter/assets/fonts/lato/files/4a6b566dbb28adb473a8789ce5169306f42f0c8a070ac92bae93636f36348b0d.pdf +0 -0
  576. package/starter/assets/fonts/lato/files/5adeb6b334d8fb99ef053bc052b952773d544315e0e1d668a12c0ce8bd51375c.ttf +0 -0
  577. package/starter/assets/fonts/lato/files/62c1b7f0d2e74b45960154c3520efc337b553db0961bfdc950d5618334596cc8.ttf +0 -0
  578. package/starter/assets/fonts/lato/files/71b8b7decbe75a881ed267be539d402bd1e9420b799658aada4e0d1bd5af803c.ttf +0 -0
  579. package/starter/assets/fonts/lato/files/8a0aace75d33794eece4b28187bfc1df0bbd2888b5d8a56e01788c8d65d16be1.ttf +0 -0
  580. package/starter/assets/fonts/lato/files/d636e4683231f931eda222d588e944d082bfd3bdba02f928bee461c0f185b251.ttf +0 -0
  581. package/starter/assets/fonts/lato/files/e399c44efe1387100531d26c7e4800c5d12251b890d6654a3098c7c679cb1786.ttf +0 -0
  582. package/starter/assets/fonts/lato/revisions/49ccb93400a9d466fab7d9843b1ecf8916ec6d47a475dd79a597a22eb39616bc.json +99 -0
  583. package/starter/assets/fonts/lato/source.json +57 -0
  584. package/starter/assets/fonts/merriweather/OFL.txt +93 -0
  585. package/starter/assets/fonts/merriweather/asset.json +7 -0
  586. package/starter/assets/fonts/merriweather/files/1c54f91b910454251c4c2b7bd4e472e1abf265fba7ca3c0ef2eee2f41324099e.ttf +0 -0
  587. package/starter/assets/fonts/merriweather/files/8bde8da2bb7f0265e27ba0481f70bb48d0f98a976c145f2f239c648ddd6532e0.pdf +0 -0
  588. package/starter/assets/fonts/merriweather/files/90b7db4460fcd1a5ca49575c2668a793f3cd6447664d312a068d690e1c01e6bc.ttf +0 -0
  589. package/starter/assets/fonts/merriweather/files/afff81272b7653417bb6f8bef57add055b1f9fda36f27eba5f32b40752bd08da.ttf +0 -0
  590. package/starter/assets/fonts/merriweather/files/e029d3b71e5bae3877c73f4f2b15af28db16593d49b0aed2a328d37ff7075846.ttf +0 -0
  591. package/starter/assets/fonts/merriweather/files/e9864a6790bf712a04e20f3662b206a1535186ed3e877fd859dd5fb9682335df.ttf +0 -0
  592. package/starter/assets/fonts/merriweather/files/fa71baebdd20a7d0de2e5e445a5922530fe9e1d740efbe791f113b682d3cb093.ttf +0 -0
  593. package/starter/assets/fonts/merriweather/revisions/1888e390b3e4f38a3d7cd2dc1bb805aeb6ce13f986a97656f0265fd436bc91d2.json +99 -0
  594. package/starter/assets/fonts/merriweather/source.json +57 -0
  595. package/starter/assets/fonts/open-sans/OFL.txt +92 -0
  596. package/starter/assets/fonts/open-sans/asset.json +7 -0
  597. package/starter/assets/fonts/open-sans/files/1bc0594a83762b2c25d38915a34464b7fec6088298ca22d151757bf98d6700ec.ttf +0 -0
  598. package/starter/assets/fonts/open-sans/files/47ed1cfaa7ffca04a04ab850b2938fd52c09d1b44cfa3e2980878e166b0cbd87.ttf +0 -0
  599. package/starter/assets/fonts/open-sans/files/574939af301f07df8e21cfff279465c5981dd9d9cf62086f7515897df951c6f5.pdf +0 -0
  600. package/starter/assets/fonts/open-sans/files/6d3884d0d57c1b67e9c50c54eca7b69c535c114e76bd7a9cfda0258588185553.ttf +0 -0
  601. package/starter/assets/fonts/open-sans/files/733eb93b167e6d45de09aa768f6c0355647c2c26f5416dbc7407a08ed41e81c6.ttf +0 -0
  602. package/starter/assets/fonts/open-sans/files/75367e6da7d914eaed87883ba51b2a2b5816b5cdbb39f96ec5c81a5b032bfd5a.ttf +0 -0
  603. package/starter/assets/fonts/open-sans/files/ff4fdc11204e0edd14e9a0bb6c374b847a9093b0ec2c16702e03afca79ac4ef7.ttf +0 -0
  604. package/starter/assets/fonts/open-sans/revisions/bbbe3a4915b9bccbc883c0decb4097511c43b6bd09ae22a1516aff128c219bc5.json +99 -0
  605. package/starter/assets/fonts/open-sans/source.json +57 -0
  606. package/starter/assets/fonts/roboto/OFL.txt +93 -0
  607. package/starter/assets/fonts/roboto/asset.json +7 -0
  608. package/starter/assets/fonts/roboto/files/22d45d989248a624252b8382067ac56550212fa675dcdbaf12f03d297dd87a58.pdf +0 -0
  609. package/starter/assets/fonts/roboto/files/35757eaa996b3359022f47f164a67ee9eac04971af24c5b8fbd4b89e844ff190.ttf +0 -0
  610. package/starter/assets/fonts/roboto/files/4d3035883c531846bd1ce2dc89f36d932e72dc114f56062c7e3a9cdd74f3d3ea.ttf +0 -0
  611. package/starter/assets/fonts/roboto/files/be7639306a4fc4a02ce2ae2ff59eb1335e4db4a7379dd0a384ed7cc053817789.ttf +0 -0
  612. package/starter/assets/fonts/roboto/files/d2920cbb1b60a3fd11fbf22049286e43a6baf522d37fdf1e7c89562319bcfea5.ttf +0 -0
  613. package/starter/assets/fonts/roboto/files/dece7c71bbe61710787f0839c722c65e87355dd2eb4a823e6b5488121ff81e4b.ttf +0 -0
  614. package/starter/assets/fonts/roboto/files/f478ba88b0292e685e487901dfbb1401457d32d6ebee4030cdfd5698235bffa8.ttf +0 -0
  615. package/starter/assets/fonts/roboto/revisions/bda5e2d84c17313373dd2dbf3e64fe0dd450c7e1b59e6929e69557e122fe976e.json +99 -0
  616. package/starter/assets/fonts/roboto/source.json +57 -0
  617. package/starter/assets/logos/opendoc/asset.json +6 -0
  618. package/starter/assets/logos/opendoc/files/831d5ccd9eb6709cc8439ea257c03d81452e81a28a3d1eedbd6a3b7daff687b6.png +0 -0
  619. package/starter/assets/logos/opendoc/revisions/834dde8926ddb81de687254195a168bb13bfb77803307f1257de1f2228be63b2.json +33 -0
  620. package/starter/assets/ui-fonts/geist/OFL.txt +93 -0
  621. package/starter/assets/ui-fonts/geist/geist-latin-ext-wght-italic.woff2 +0 -0
  622. package/starter/assets/ui-fonts/geist/geist-latin-ext-wght-normal.woff2 +0 -0
  623. package/starter/assets/ui-fonts/geist/geist-latin-wght-italic.woff2 +0 -0
  624. package/starter/assets/ui-fonts/geist/geist-latin-wght-normal.woff2 +0 -0
  625. package/starter/assets/ui-fonts/geist/source.json +26 -0
  626. package/starter/documents/welcome/assets.json +7 -0
  627. package/starter/documents/welcome/index.tsx +160 -0
  628. package/starter/documents/welcome/media/.gitkeep +0 -0
  629. package/starter/documents/welcome/media/paper-architecture/image.png +0 -0
  630. package/starter/documents/welcome/media/paper-architecture/meta.json +9 -0
  631. package/starter/documents/welcome/media/paper-architecture/prompt.txt +1 -0
  632. package/starter/documents/welcome/media/studio-rhythm/chart.svg +2343 -0
  633. package/starter/documents/welcome/media/studio-rhythm/data.json +234 -0
  634. package/starter/documents/welcome/media/studio-rhythm/generation.json +9 -0
  635. package/starter/documents/welcome/media/studio-rhythm/image.png +0 -0
  636. package/starter/documents/welcome/media/studio-rhythm/meta.json +11 -0
  637. package/starter/documents/welcome/media/studio-rhythm/recipe.py +79 -0
  638. package/starter/documents/welcome/theme.tsx +5 -0
  639. package/starter/documents/welcome-presentation/assets.json +7 -0
  640. package/starter/documents/welcome-presentation/index.tsx +166 -0
  641. package/starter/documents/welcome-presentation/media/.gitkeep +0 -0
  642. package/starter/documents/welcome-presentation/media/paper-architecture/image.png +0 -0
  643. package/starter/documents/welcome-presentation/media/paper-architecture/meta.json +9 -0
  644. package/starter/documents/welcome-presentation/media/paper-architecture/prompt.txt +1 -0
  645. package/starter/documents/welcome-presentation/media/studio-rhythm/chart.svg +1336 -0
  646. package/starter/documents/welcome-presentation/media/studio-rhythm/data.json +234 -0
  647. package/starter/documents/welcome-presentation/media/studio-rhythm/generation.json +9 -0
  648. package/starter/documents/welcome-presentation/media/studio-rhythm/image.png +0 -0
  649. package/starter/documents/welcome-presentation/media/studio-rhythm/meta.json +13 -0
  650. package/starter/documents/welcome-presentation/media/studio-rhythm/recipe.py +49 -0
  651. package/starter/documents/welcome-presentation/theme.tsx +5 -0
  652. package/starter/projects.json +17 -0
  653. package/starter/templates/AGENTS.md +9 -0
  654. package/starter/templates/_shared/BusinessLogo.tsx +14 -0
  655. package/starter/templates/_shared/Pricing.tsx +40 -0
  656. package/starter/templates/_shared/commerce.ts +93 -0
  657. package/starter/templates/brand-guidelines/AGENTS.md +32 -0
  658. package/starter/templates/brand-guidelines/index.tsx +62 -0
  659. package/starter/templates/brand-guidelines/preview.tsx +181 -0
  660. package/starter/templates/brand-guidelines/starter.tsx +179 -0
  661. package/starter/templates/brand-guidelines/template.json +15 -0
  662. package/starter/templates/business-proposal/AGENTS.md +13 -0
  663. package/starter/templates/business-proposal/README.md +36 -0
  664. package/starter/templates/business-proposal/data.json +37 -0
  665. package/starter/templates/business-proposal/examples/long.json +142 -0
  666. package/starter/templates/business-proposal/examples/sparse.json +17 -0
  667. package/starter/templates/business-proposal/examples/typical.json +37 -0
  668. package/starter/templates/business-proposal/index.tsx +59 -0
  669. package/starter/templates/business-proposal/preview.tsx +47 -0
  670. package/starter/templates/business-proposal/schema.ts +14 -0
  671. package/starter/templates/business-proposal/starter.tsx +18 -0
  672. package/starter/templates/business-proposal/template.json +11 -0
  673. package/starter/templates/company-profile/AGENTS.md +48 -0
  674. package/starter/templates/company-profile/index.tsx +69 -0
  675. package/starter/templates/company-profile/preview.tsx +185 -0
  676. package/starter/templates/company-profile/starter.tsx +186 -0
  677. package/starter/templates/company-profile/template.json +15 -0
  678. package/starter/templates/consulting-report/AGENTS.md +11 -0
  679. package/starter/templates/consulting-report/README.md +13 -0
  680. package/starter/templates/consulting-report/RESEARCH.md +10 -0
  681. package/starter/templates/consulting-report/index.tsx +44 -0
  682. package/starter/templates/consulting-report/preview.tsx +39 -0
  683. package/starter/templates/consulting-report/starter.tsx +15 -0
  684. package/starter/templates/consulting-report/template.json +11 -0
  685. package/starter/templates/editorial-essay/AGENTS.md +11 -0
  686. package/starter/templates/editorial-essay/README.md +11 -0
  687. package/starter/templates/editorial-essay/index.tsx +30 -0
  688. package/starter/templates/editorial-essay/preview.tsx +26 -0
  689. package/starter/templates/editorial-essay/starter.tsx +15 -0
  690. package/starter/templates/editorial-essay/template.json +11 -0
  691. package/starter/templates/executive-brief/AGENTS.md +9 -0
  692. package/starter/templates/executive-brief/README.md +11 -0
  693. package/starter/templates/executive-brief/index.tsx +33 -0
  694. package/starter/templates/executive-brief/preview.tsx +37 -0
  695. package/starter/templates/executive-brief/starter.tsx +11 -0
  696. package/starter/templates/executive-brief/template.json +11 -0
  697. package/starter/templates/image-story/AGENTS.md +37 -0
  698. package/starter/templates/image-story/index.tsx +106 -0
  699. package/starter/templates/image-story/preview.tsx +33 -0
  700. package/starter/templates/image-story/starter.tsx +24 -0
  701. package/starter/templates/image-story/template.json +13 -0
  702. package/starter/templates/invoice/AGENTS.md +13 -0
  703. package/starter/templates/invoice/README.md +40 -0
  704. package/starter/templates/invoice/data.json +61 -0
  705. package/starter/templates/invoice/examples/long.json +241 -0
  706. package/starter/templates/invoice/examples/sparse.json +33 -0
  707. package/starter/templates/invoice/examples/typical.json +61 -0
  708. package/starter/templates/invoice/index.tsx +57 -0
  709. package/starter/templates/invoice/preview.tsx +12 -0
  710. package/starter/templates/invoice/schema.ts +45 -0
  711. package/starter/templates/invoice/starter.tsx +12 -0
  712. package/starter/templates/invoice/template.json +11 -0
  713. package/starter/templates/literary-text/AGENTS.md +9 -0
  714. package/starter/templates/literary-text/README.md +11 -0
  715. package/starter/templates/literary-text/index.tsx +31 -0
  716. package/starter/templates/literary-text/preview.tsx +20 -0
  717. package/starter/templates/literary-text/starter.tsx +11 -0
  718. package/starter/templates/literary-text/template.json +11 -0
  719. package/starter/templates/magazine-feature/AGENTS.md +11 -0
  720. package/starter/templates/magazine-feature/README.md +13 -0
  721. package/starter/templates/magazine-feature/index.tsx +41 -0
  722. package/starter/templates/magazine-feature/preview.tsx +34 -0
  723. package/starter/templates/magazine-feature/starter.tsx +15 -0
  724. package/starter/templates/magazine-feature/template.json +11 -0
  725. package/starter/templates/monthly-report/AGENTS.md +11 -0
  726. package/starter/templates/monthly-report/README.md +24 -0
  727. package/starter/templates/monthly-report/data.json +131 -0
  728. package/starter/templates/monthly-report/examples/long.json +519 -0
  729. package/starter/templates/monthly-report/examples/sparse.json +20 -0
  730. package/starter/templates/monthly-report/examples/typical.json +37 -0
  731. package/starter/templates/monthly-report/index.tsx +92 -0
  732. package/starter/templates/monthly-report/preview.tsx +14 -0
  733. package/starter/templates/monthly-report/schema.ts +127 -0
  734. package/starter/templates/monthly-report/starter.tsx +13 -0
  735. package/starter/templates/monthly-report/template.json +11 -0
  736. package/starter/templates/pitch-deck/AGENTS.md +32 -0
  737. package/starter/templates/pitch-deck/index.tsx +46 -0
  738. package/starter/templates/pitch-deck/preview.tsx +142 -0
  739. package/starter/templates/pitch-deck/starter.tsx +140 -0
  740. package/starter/templates/pitch-deck/template.json +15 -0
  741. package/starter/templates/proposal-deck/AGENTS.md +25 -0
  742. package/starter/templates/proposal-deck/index.tsx +52 -0
  743. package/starter/templates/proposal-deck/preview.tsx +172 -0
  744. package/starter/templates/proposal-deck/starter.tsx +168 -0
  745. package/starter/templates/proposal-deck/template.json +7 -0
  746. package/starter/templates/quotation/AGENTS.md +13 -0
  747. package/starter/templates/quotation/README.md +42 -0
  748. package/starter/templates/quotation/data.json +64 -0
  749. package/starter/templates/quotation/examples/long.json +272 -0
  750. package/starter/templates/quotation/examples/sparse.json +31 -0
  751. package/starter/templates/quotation/examples/typical.json +64 -0
  752. package/starter/templates/quotation/index.tsx +51 -0
  753. package/starter/templates/quotation/preview.tsx +12 -0
  754. package/starter/templates/quotation/schema.ts +27 -0
  755. package/starter/templates/quotation/starter.tsx +12 -0
  756. package/starter/templates/quotation/template.json +11 -0
  757. package/starter/templates/scientific-paper/AGENTS.md +11 -0
  758. package/starter/templates/scientific-paper/README.md +13 -0
  759. package/starter/templates/scientific-paper/index.tsx +47 -0
  760. package/starter/templates/scientific-paper/preview.tsx +43 -0
  761. package/starter/templates/scientific-paper/starter.tsx +15 -0
  762. package/starter/templates/scientific-paper/template.json +11 -0
  763. package/starter/themes/Specimen.tsx +54 -0
  764. package/starter/themes/civic-spectrum/components.tsx +92 -0
  765. package/starter/themes/civic-spectrum/design.md +70 -0
  766. package/starter/themes/civic-spectrum/index.ts +57 -0
  767. package/starter/themes/civic-spectrum/preview.tsx +66 -0
  768. package/starter/themes/field-manual/components.tsx +106 -0
  769. package/starter/themes/field-manual/design.md +72 -0
  770. package/starter/themes/field-manual/index.ts +57 -0
  771. package/starter/themes/field-manual/preview.tsx +82 -0
  772. package/starter/themes/index.ts +3 -0
  773. package/starter/themes/mckinsey-consulting/components.tsx +69 -0
  774. package/starter/themes/mckinsey-consulting/design.md +68 -0
  775. package/starter/themes/mckinsey-consulting/index.ts +60 -0
  776. package/starter/themes/mckinsey-consulting/preview.tsx +53 -0
  777. package/starter/themes/neutral/design.md +35 -0
  778. package/starter/themes/neutral/index.ts +21 -0
  779. package/starter/themes/neutral/preview.tsx +4 -0
  780. package/starter/themes/opendoc-neutral/components.tsx +77 -0
  781. package/starter/themes/opendoc-neutral/design.md +70 -0
  782. package/starter/themes/opendoc-neutral/index.ts +54 -0
  783. package/starter/themes/opendoc-neutral/preview.tsx +43 -0
  784. package/starter/themes/types.ts +3 -0
  785. package/tsconfig.workspace.json +24 -0
  786. package/vendor/formepdf/LICENSE +21 -0
  787. package/vendor/formepdf/README.md +97 -0
  788. package/vendor/formepdf/font-subset.patch +228 -0
  789. package/vendor/formepdf/text-writer.patch +507 -0
@@ -0,0 +1,60 @@
1
+ import type { DocTheme } from 'opendoc/themes';
2
+
3
+ export const colors = {
4
+ white: '#FFFFFF', ink: '#051C2C', focus: '#2251FF', muted: '#4D4D4D', rule: '#D0D0D0',
5
+ soft: '#F0F0F0', pale: '#AAE6F0', cyan: '#00A9F4', blue1: '#034B6F', blue2: '#027AB1',
6
+ blue3: '#39BDF3', blue4: '#71D2F1', positive: '#3C96B4', caution: '#FAA082', negative: '#E5546C',
7
+ };
8
+
9
+ export const theme: DocTheme = {
10
+ id: 'mckinsey-consulting', name: 'McKinsey Consulting',
11
+ description: 'An independent consulting system: answer-first headlines, rigorous exhibits, deep blue structure and electric blue focus.',
12
+ body: 'OpenDoc Sans', heading: 'OpenDoc Sans', ink: colors.ink, muted: colors.muted,
13
+ accent: colors.focus, paper: colors.white, line: colors.rule,
14
+ fontSize: 10.5, lineHeight: 1.42, margin: 48, paragraphGap: 10,
15
+ pageSize: 'A4', runningHeader: true, runningFooter: true, footerLabel: 'Analysis / Working paper',
16
+ useFor: ['Executive decisions', 'Analytical reports', 'Business cases'],
17
+ principles: ['State the answer before the evidence.', 'Make the comparison explicit.', 'Let one datum carry the color.'],
18
+ palette: [
19
+ { name: 'Deep blue', value: colors.ink, role: 'Structure, text and inverse covers' },
20
+ { name: 'Electric blue', value: colors.focus, role: 'One focal datum or conclusion' },
21
+ { name: 'White', value: colors.white, role: 'Exhibit canvas and inverse text' },
22
+ { name: 'Gray', value: colors.muted, role: 'Annotations and source notes' },
23
+ { name: 'Rule', value: colors.rule, role: 'Hairlines and chart axes' },
24
+ { name: 'Soft', value: colors.soft, role: 'Context bands' },
25
+ { name: 'Pale blue', value: colors.pale, role: 'Implication fields and selected rows' },
26
+ { name: 'Cyan', value: colors.cyan, role: 'Secondary emphasis' },
27
+ { name: 'Series 1', value: colors.blue1, role: 'Ordered dark series' },
28
+ { name: 'Series 2', value: colors.blue2, role: 'Ordered mid-dark series' },
29
+ { name: 'Series 3', value: colors.blue3, role: 'Ordered mid-light series' },
30
+ { name: 'Series 4', value: colors.blue4, role: 'Ordered light series' },
31
+ { name: 'Positive', value: colors.positive, role: 'Favorable movement' },
32
+ { name: 'Caution', value: colors.caution, role: 'Watch items' },
33
+ { name: 'Negative', value: colors.negative, role: 'Adverse exceptions' },
34
+ ],
35
+ geometry: [
36
+ 'Square rectangles; no rounded analytical containers.',
37
+ 'A4, 48 pt margins, 12-column construction with 12 pt gutters.',
38
+ 'A 4 pt spacing unit; 0.5 pt rules and directly labeled bars.',
39
+ 'Claim → metric frame → evidence → implication → source.',
40
+ ],
41
+ design: {
42
+ typography: {
43
+ h1: { fontSize: 31, lineHeight: 1.1, letterSpacing: -0.6, marginBottom: 16 },
44
+ h2: { fontSize: 19, lineHeight: 1.15, marginTop: 24, marginBottom: 10 },
45
+ h3: { fontSize: 12, marginTop: 16, marginBottom: 8 },
46
+ label: { fontSize: 8, fontWeight: 600, letterSpacing: 1.1 },
47
+ lead: { fontSize: 12, lineHeight: 1.4, color: colors.muted },
48
+ small: { fontSize: 8, lineHeight: 1.35 },
49
+ caption: { fontSize: 8.5, lineHeight: 1.35 },
50
+ },
51
+ page: { margin: { top: 48, bottom: 52, left: 48, right: 48 }, style: { backgroundColor: colors.white } },
52
+ title: { block: { borderBottomWidth: 0, paddingBottom: 0, marginBottom: 24 }, eyebrow: { marginBottom: 12 } },
53
+ cover: { page: { backgroundColor: colors.ink }, block: { borderTopWidth: 0, marginTop: 92 }, title: { fontSize: 58, lineHeight: 1.04, color: colors.white }, subtitle: { color: colors.pale }, eyebrow: { color: colors.pale }, byline: { color: colors.pale }, footer: { color: colors.pale } },
54
+ furniture: { header: { letterSpacing: 0.7, paddingBottom: 16 }, text: { fontSize: 7.5 }, footer: { borderTopWidth: 0.5, paddingTop: 8 }, pageNumber: 'total' },
55
+ table: { header: { backgroundColor: colors.ink }, headerText: { color: colors.white, fontSize: 8.5, fontWeight: 600 }, cell: { padding: 8 }, text: { fontSize: 9 }, alternate: colors.soft },
56
+ figure: { block: { marginTop: 12, marginBottom: 20 } },
57
+ callout: { block: { backgroundColor: colors.pale, borderLeftWidth: 0, padding: 16, marginBottom: 16 }, title: { color: colors.ink, fontWeight: 600, fontSize: 10 }, text: { fontSize: 10.5, color: colors.ink } },
58
+ list: { gap: 8, item: { marginBottom: 8 } },
59
+ },
60
+ };
@@ -0,0 +1,53 @@
1
+ import { Document, Pages, Heading, Paragraph, DataTable, Text, View } from 'opendoc';
2
+ import { theme, colors as c } from './index';
3
+ import { ConsultingCover, ExhibitTitle, RankedBars, Implication, SourceNote } from './components';
4
+
5
+ export const meta = { title: 'McKinsey Consulting — Make the answer visible', description: theme.description, theme: theme.id };
6
+
7
+ export default function Preview() {
8
+ return <Document title={meta.title} theme={theme}>
9
+ <ConsultingCover id="consulting-identity" title={'Make the\nanswer visible.'} subtitle="A disciplined system for conclusions, comparisons and decisions." />
10
+ <Pages title="McKinsey Consulting / The system" footer="Design grammar / Independent adaptation">
11
+ <ExhibitTitle id="consulting-system" number="01" topic="Visual grammar" metric="A4 portrait / all dimensions in points / embedded local typography">Structure stays quiet. The answer carries the color.</ExhibitTitle>
12
+ <View style={{ flexDirection: 'row', gap: 20 }}>
13
+ <View style={{ width: 198 }}>
14
+ <Heading id="consulting-palette-title" level={3} style={{ marginTop: 0 }}>A semantic palette</Heading>
15
+ {theme.palette!.map(color => <View key={color.name} style={{ flexDirection: 'row', gap: 8, alignItems: 'center', marginBottom: 6 }}>
16
+ <View style={{ width: 22, height: 22, backgroundColor: color.value, borderWidth: color.value === c.white ? 0.5 : 0, borderColor: c.rule }} />
17
+ <View><Text style={{ fontSize: 8.5, fontWeight: 600 }}>{color.name}</Text><Text style={{ fontSize: 7.5, fontFamily: 'OpenDoc Mono', color: c.muted }}>{color.value}</Text></View>
18
+ </View>)}
19
+ </View>
20
+ <View style={{ flex: 1 }}>
21
+ <Text style={{ fontSize: 48, fontWeight: 600, lineHeight: 1.05, letterSpacing: -1, marginBottom: 8 }}>Aa 82%</Text>
22
+ <Paragraph id="consulting-type" style={{ fontSize: 9 }}>OpenDoc Sans is the embedded substitute. The original McKinsey Sans is proprietary; no brand font or logo is redistributed.</Paragraph>
23
+ <DataTable id="consulting-type-scale" columns={[{ label: 'Role', width: 1.7 }, { label: 'pt / leading', width: 1 }]} rows={[
24
+ ['Cover', '62 / 1.01'], ['Conclusion', '31 / 1.10'], ['Section', '19 / 1.15'], ['Body', '10.5 / 1.42'], ['Source', '8 / 1.35'],
25
+ ]} />
26
+ <Heading id="consulting-geometry-title" level={3}>Geometry is analytical</Heading>
27
+ <View style={{ flexDirection: 'row', gap: 8, alignItems: 'flex-end', marginBottom: 12 }}>
28
+ <View style={{ width: 40, height: 40, backgroundColor: c.ink }} /><View style={{ width: 64, height: 24, backgroundColor: c.focus }} /><View style={{ width: 84, height: 8, backgroundColor: c.pale }} />
29
+ </View>
30
+ <Paragraph id="consulting-geometry" style={{ fontSize: 9 }}>Square corners. A 4 pt spacing unit. A 12-column construction with 12 pt gutters inside 48 pt page margins. Fine 0.5 pt rules separate comparisons.</Paragraph>
31
+ <Paragraph id="consulting-composition" style={{ fontSize: 9 }}>Give the evidence most of the page. Use one assertive title, define the metric, directly label the marks, then state the implication and source.</Paragraph>
32
+ </View>
33
+ </View>
34
+ <SourceNote id="consulting-basis">An independent OpenDoc interpretation of analytical publication conventions, without affiliation. Detailed palette roles and component guidance are in this theme’s design guide.</SourceNote>
35
+ </Pages>
36
+ <Pages title="McKinsey Consulting / Applied exhibit" footer="Illustrative analysis / No empirical claim">
37
+ <ExhibitTitle id="consulting-applied" number="02" topic="Value pool" metric="Share of identified opportunity by lever, % of total / illustrative scenario">Three levers account for 82% of the opportunity.</ExhibitTitle>
38
+ <RankedBars id="consulting-bars" max={40} rows={[
39
+ { label: 'Simplify intake', detail: 'Reduce repeated entry', value: 32 },
40
+ { label: 'Balance capacity', detail: 'Match effort to demand', value: 28 },
41
+ { label: 'Shorten handoffs', detail: 'Clarify the next owner', value: 22 },
42
+ { label: 'Improve routing', detail: 'Reduce avoidable loops', value: 11 },
43
+ { label: 'Other changes', detail: 'Remaining opportunity', value: 7 },
44
+ ]} />
45
+ <View wrap={false} style={{ flexDirection: 'row', gap: 16, alignItems: 'center', marginTop: 4, marginBottom: 12 }}>
46
+ <Text style={{ width: 124, fontSize: 48, fontWeight: 600, color: c.focus, lineHeight: 1 }}>82%</Text>
47
+ <Text style={{ flex: 1, fontSize: 12, lineHeight: 1.35 }}>The first three levers contain most of the modeled value. Start there, then test whether the assumptions hold.</Text>
48
+ </View>
49
+ <Implication id="consulting-next">Prioritize validation of the three largest levers before funding a wider transformation. An attractive estimate becomes a decision only after its assumptions survive scrutiny.</Implication>
50
+ <SourceNote id="consulting-source">Source: synthetic example created to demonstrate this theme. Values total 100%; the first three sum to 82%. Bars share a zero baseline and a 40% maximum. These figures describe no organization.</SourceNote>
51
+ </Pages>
52
+ </Document>;
53
+ }
@@ -0,0 +1,35 @@
1
+ # Neutral
2
+
3
+ Neutral is OpenDoc’s plain proofing system: dark type, white paper, and quiet gray structure. It is useful for working documents, correspondence, and evaluating a template’s proportions before choosing a more expressive theme. Its character comes from clarity and restraint. It should look finished enough to share, with no brand identity imposed on the material.
4
+
5
+ ## Composition and rhythm
6
+
7
+ Use a dependable left edge and a comfortable reading column. The opening gives the title priority, followed by a short subtitle or byline when useful. Body sections retain a visible hierarchy without turning each heading into an event. Keep the document’s main reading path obvious; a second column is appropriate only when the chosen template or content needs it.
8
+
9
+ Maintain regular paragraph spacing and enough separation before a new section. Use headings to mark changes in thought and lists for genuinely parallel material. A heading belongs with its opening passage. Let longer prose and tables flow naturally instead of shrinking them to preserve a page count.
10
+
11
+ ## Type and emphasis
12
+
13
+ The sans-serif family carries both display and reading text. Weight and scale establish hierarchy; grayscale distinguishes secondary notes. Use bold for a short emphasis and italic for a change of voice. Keep labels readable and avoid using uppercase for ordinary sentences. The executable definition in `index.ts` owns all sizes, spacing, and style values. The default A4 page uses 54 pt margins, 11 pt body type, 1.5 leading, and 12 pt paragraph gaps. Standard headings are 30, 21, and 14 pt with 1.2 leading and weight 600; title blocks start at 32 pt. Captions are 9 pt and small notes 8.5 pt. A template may supply different starting proportions; document styles can adapt them.
14
+
15
+ ## Palette
16
+
17
+ Ink `#242424` carries main text; muted `#666666` carries annotations; accent `#424242` carries labels and table headers; surface `#ffffff` keeps panels and page fields white; rule `#d6d6d6` defines quiet boundaries. Use weights 400 and 600 from the bundled OpenDoc Sans family. OpenDoc Mono remains the code family.
18
+
19
+ ## Supporting material
20
+
21
+ Tables should remain easy to scan, with consistent column alignment and numbers aligned for comparison. Captions state what is shown; source notes remain close enough to read as part of the exhibit. Grayscale row treatments and rules organize information without making a dense cage.
22
+
23
+ Charts use direct labels and a clear comparison basis. Use darker marks for a focal value and lighter marks for context. Distinguish multiple series through labels or shape when color adds no necessary information. Preserve evidence-critical colors in supplied media; neutral page furniture does not require recoloring a real chart.
24
+
25
+ Images follow the reading column or the template’s deliberate wider field. Keep the original aspect ratio, a useful crop, and a nearby caption. Callouts provide one restrained interruption, not a container around every paragraph.
26
+
27
+ ## Branding and density
28
+
29
+ Neutral has no built-in logo, decorative motif, or institutional voice. Use the actual document’s author, title, and footer information. Add a supplied mark only when required by the brief and leave enough space around it.
30
+
31
+ The system should handle both a short note and a long report. For dense content, simplify the presentation or use the appropriate template rather than reducing all type. Avoid ornamental icons, shadows, decorative rules, invented brand marks, and arbitrary accent colors.
32
+
33
+ ## Basis and review
34
+
35
+ This is an original OpenDoc proofing theme, not an extracted external brand. `preview.tsx` uses the shared specimen and the same executable theme as authored documents. Review line lengths, restrained contrast, table alignment, and running matter in the exported PDF. The specimen’s comparison values are illustrative only.
@@ -0,0 +1,21 @@
1
+ import type { DocTheme } from 'opendoc/themes';
2
+
3
+ /** The plain proofing system shared by the template catalog. */
4
+ export const neutral: DocTheme = {
5
+ id: 'neutral', name: 'Neutral', description: 'A plain, adaptable proofing system with black type, gray details, and an open white page.',
6
+ body: 'OpenDoc Sans', heading: 'OpenDoc Sans', ink: '#242424', muted: '#666666',
7
+ accent: '#424242', paper: '#ffffff', line: '#d6d6d6',
8
+ fontSize: 11, lineHeight: 1.5, margin: 54, paragraphGap: 12,
9
+ pageSize: 'A4', runningHeader: false, runningFooter: true, footerLabel: '',
10
+ useFor: ['Layout proofs', 'Everyday documents', 'A starting point for a custom system'],
11
+ principles: ['Let content and structure lead.', 'Keep the page quiet.', 'Make every level easy to recognize.'],
12
+ palette: [
13
+ { name: 'Ink', value: '#242424', role: 'Main text and headings' },
14
+ { name: 'Muted', value: '#666666', role: 'Secondary text and annotations' },
15
+ { name: 'Accent', value: '#424242', role: 'Labels, table headers, and selected emphasis' },
16
+ { name: 'Surface', value: '#ffffff', role: 'Covers, callouts, code panels, and alternate table rows' },
17
+ { name: 'Rule', value: '#d6d6d6', role: 'Quiet structure and table boundaries' },
18
+ ],
19
+ geometry: ['A4 portrait; 54 pt default margins.', '11 pt body, 1.5 line height, 12 pt paragraph spacing.', 'Square corners, a clear left edge, and naturally flowing pages.'],
20
+ };
21
+ export const theme = neutral;
@@ -0,0 +1,4 @@
1
+ import { ThemeSpecimen } from '../Specimen';
2
+ import { theme } from './index';
3
+ export const meta = { title: `${theme.name} design specimen`, description: theme.description, theme: theme.id };
4
+ export default function Preview() { return <ThemeSpecimen theme={theme} />; }
@@ -0,0 +1,77 @@
1
+ import type { ReactNode } from 'react';
2
+ import { Fixed, View, Text, type Style } from '@formepdf/react';
3
+ import { Block, Heading, Page, Paragraph, TextSlot, documentFont } from 'opendoc';
4
+ import { colors, metrics } from './index';
5
+
6
+ export type Surface = 'paper' | 'white' | 'dark';
7
+ export const surfaceColors = (surface: Surface) => surface === 'dark'
8
+ ? { background: colors.night, ink: colors.inverse, muted: colors.inverseMuted, rule: colors.inverseRule }
9
+ : { background: surface === 'white' ? colors.white : colors.paper, ink: colors.ink, muted: colors.muted, rule: colors.rule };
10
+
11
+ /** A flowing surface; running furniture repeats if the content needs another page. */
12
+ export function NeutralPages({ title, label = 'OpenDoc Neutral', surface = 'paper', children, header = true }: {
13
+ title: string; label?: string; surface?: Surface; children: ReactNode; header?: boolean;
14
+ }) {
15
+ const c = surfaceColors(surface);
16
+ return <Page size="A4" margin={{ top: metrics.margin, right: metrics.margin, bottom: metrics.bottom, left: metrics.margin }} style={{ backgroundColor: c.background, color: c.ink }}>
17
+ {header && <Fixed position="header"><View style={{ flexDirection: 'row', justifyContent: 'space-between', paddingBottom: 18 }}>
18
+ <Text style={{ fontFamily: 'OpenDoc Mono', fontSize: 7, color: c.muted }}>{label}</Text>
19
+ <Text style={{ fontFamily: 'OpenDoc Mono', fontSize: 7, color: c.muted }}>{title}</Text>
20
+ </View></Fixed>}
21
+ <Fixed position="footer"><View style={{ flexDirection: 'row', justifyContent: 'space-between', borderTopWidth: metrics.rule, borderColor: c.rule, paddingTop: 10 }}>
22
+ <Text style={{ fontFamily: 'OpenDoc Mono', fontSize: 7, color: c.muted }}>{label}</Text>
23
+ <Text style={{ fontFamily: 'OpenDoc Mono', fontSize: 7, color: c.muted }}>{'{{pageNumber}}'}</Text>
24
+ </View></Fixed>
25
+ {children}
26
+ </Page>;
27
+ }
28
+
29
+ export function NeutralOpening({ id, eyebrow, title, subtitle, surface = 'paper', display = false }: {
30
+ id: string; eyebrow: string; title: string; subtitle?: string; surface?: Surface; display?: boolean;
31
+ }) {
32
+ const c = surfaceColors(surface);
33
+ return <Block id={id} style={{ marginBottom: 24 }}>
34
+ <Paragraph id={`${id}-eyebrow`} role="label" style={{ color: surface === 'dark' ? colors.inverseMuted : colors.blue, marginBottom: 18 }}><TextSlot slot="eyebrow" from="eyebrow">{eyebrow}</TextSlot></Paragraph>
35
+ <Heading id={`${id}-title`} level={1} style={{ color: c.ink, fontFamily: documentFont('heading'), ...(display ? { fontSize: 62, lineHeight: 1.03, letterSpacing: -2.1 } : {}), marginBottom: subtitle ? 16 : 0 }}><TextSlot slot="title" from="title">{title}</TextSlot></Heading>
36
+ {subtitle && <Paragraph id={`${id}-subtitle`} role="lead" style={{ color: c.muted, marginBottom: 0 }}><TextSlot slot="subtitle" from="subtitle">{subtitle}</TextSlot></Paragraph>}
37
+ </Block>;
38
+ }
39
+
40
+ /** Independent bounded columns, deliberately not advertised as sequential text flow. */
41
+ export function NeutralColumns({ left, right, ratio = 'equal', style }: { left: ReactNode; right: ReactNode; ratio?: 'equal' | 'narrow-left'; style?: Style }) {
42
+ return <View style={{ flexDirection: 'row', gap: metrics.gutter, alignItems: 'flex-start', ...style }}>
43
+ <View style={{ flex: 1, minWidth: 0 }}>{left}</View>
44
+ <View style={{ flex: ratio === 'equal' ? 1 : 2, minWidth: 0 }}>{right}</View>
45
+ </View>;
46
+ }
47
+
48
+ export function NeutralQuote({ id, children, attribution, surface = 'paper' }: { id: string; children: ReactNode; attribution: string; surface?: Surface }) {
49
+ const c = surfaceColors(surface);
50
+ return <Block id={id} style={{ borderTopWidth: 2, borderColor: surface === 'dark' ? colors.inverse : colors.blue, paddingTop: 18, marginTop: 18, marginBottom: 24 }}>
51
+ <Paragraph id={`${id}-text`} style={{ fontFamily: 'OpenDoc Serif', fontStyle: 'italic', fontSize: 28, lineHeight: 1.2, color: c.ink, marginBottom: 16 }}>{children}</Paragraph>
52
+ <Paragraph id={`${id}-attribution`} role="label" style={{ color: c.muted, marginBottom: 0 }}><TextSlot slot="attribution" from="attribution">{attribution}</TextSlot></Paragraph>
53
+ </Block>;
54
+ }
55
+
56
+ /** Native vector-like page shapes, used sparingly as the theme's opening motif. */
57
+ export function PaperStudy({ id, surface = 'paper' }: { id: string; surface?: Surface }) {
58
+ const dark = surface === 'dark';
59
+ return <Block id={id} style={{ height: 186, flexDirection: 'row', gap: 16, alignItems: 'flex-end' }}>
60
+ <View style={{ flex: 1, height: 114, padding: 18, backgroundColor: dark ? colors.inverseRule : colors.stone }}>
61
+ <View style={{ width: 20, height: 3, backgroundColor: dark ? colors.inverseMuted : colors.muted, marginBottom: 36 }} />
62
+ <View style={{ height: 1, backgroundColor: dark ? colors.inverseMuted : colors.muted, marginBottom: 8 }} />
63
+ <View style={{ height: 1, width: '62%', backgroundColor: dark ? colors.inverseMuted : colors.muted }} />
64
+ </View>
65
+ <View style={{ flex: 1, height: 150, padding: 18, backgroundColor: dark ? colors.inverse : colors.ink }}>
66
+ <View style={{ width: 20, height: 3, backgroundColor: colors.blue, marginBottom: 32 }} />
67
+ <View style={{ height: 32, width: 32, borderWidth: 1, borderColor: dark ? colors.ink : colors.inverse, marginBottom: 18 }} />
68
+ <View style={{ height: 1, backgroundColor: dark ? colors.ink : colors.inverse }} />
69
+ </View>
70
+ <View style={{ flex: 1, height: 186, padding: 18, backgroundColor: colors.blue }}>
71
+ <View style={{ width: 20, height: 3, backgroundColor: colors.white, marginBottom: 38 }} />
72
+ <View style={{ height: 54, width: 54, borderWidth: 1, borderColor: colors.white, marginBottom: 25 }} />
73
+ <View style={{ height: 1, backgroundColor: colors.white, marginBottom: 8 }} />
74
+ <View style={{ height: 1, width: '62%', backgroundColor: colors.white }} />
75
+ </View>
76
+ </Block>;
77
+ }
@@ -0,0 +1,70 @@
1
+ # OpenDoc Neutral
2
+
3
+ The OpenDoc house style makes room for writing, evidence, and imagery. Warm paper and charcoal establish its character; scale, a flexible grid, fine rules, and one blue signal give it visual taste. It is a reusable everyday system, with expressive openings and dark surfaces available when the content benefits.
4
+
5
+ ## Palette
6
+
7
+ | Role | Hex | Use |
8
+ | --- | --- | --- |
9
+ | Paper | #FCFBF8 | Ordinary reading pages |
10
+ | White | #FFFFFF | Charts and analytical tables |
11
+ | Ink / Night | #171A1D | Primary text; dark page surface |
12
+ | Muted | #62686D | Secondary copy |
13
+ | Blue | #3758F9 | Labels, citations, a chart focus, or one composition |
14
+ | Wash | #ECEEF9 | Occasional callout |
15
+ | Stone | #EAE7DF | Code panels and neutral diagrams |
16
+ | Rule | #D7D7D2 | Light-surface dividers |
17
+ | Inverse | #F7F6F2 | Primary text on charcoal |
18
+ | Inverse muted | #B6BABE | Secondary text on charcoal |
19
+ | Inverse rule | #41464B | Dark-surface dividers |
20
+
21
+ Use genuine white and charcoal page backgrounds, independent of the app's appearance. Keep charts on white. Use blue for a clear point of emphasis; ordinary pages should not become collections of colored boxes.
22
+
23
+ ## Type and rhythm
24
+
25
+ The bundled OpenDoc Sans carries headings and body text. OpenDoc Serif italic supplies a deliberate editorial quotation or reflective passage; OpenDoc Mono identifies labels, page furniture, and code. All are embedded local faces. Saved body/heading bindings can replace semantic families; the intentional serif and monospace voices remain distinct.
26
+
27
+ | Role | Size / weight | Line height | Tracking |
28
+ | --- | --- | --- | --- |
29
+ | Display opening | 62 pt / 600 | 1.03 | -2.1 pt |
30
+ | Page opening | 34 pt / 600 | 1.08 | -1.1 pt |
31
+ | Section heading | 20 pt / 600 | 1.18 | -0.35 pt |
32
+ | Small heading | 12 pt / 600 | 1.25 | Normal |
33
+ | Body | 10.5 pt / 400 | 1.48 | Normal |
34
+ | Lead | 13 pt / 400 | 1.45 | Normal |
35
+ | Editorial quote | 28 pt / 400 italic | 1.2 | Normal |
36
+ | Label | 7.5 pt / 400 mono | Inherited | 0.7 pt |
37
+ | Caption / small | 8.5 / 8 pt | 1.4 | Normal |
38
+ | Table body / header | 9 / 8 pt | 1.35 / inherited | Normal |
39
+ | Code | 8 pt / 400 mono | 1.5 | Normal |
40
+ | Running furniture | 7 pt / 400 mono | Inherited | Normal |
41
+
42
+ Body paragraphs have 10 pt after-space. Ordinary h2 headings have 20 pt before and 10 pt after; h3 headings have 14 pt before and 8 pt after. Large openings use an 18 pt label gap, a 16 pt title-to-subtitle gap, and 24 pt below the composition. Use 6 pt as the spacing unit for custom arrangements; these optical type spacings are intentional exceptions.
43
+
44
+ ## Grid and surfaces
45
+
46
+ A4 portrait has 48 pt top and side margins, 56 pt bottom, and a 499.28 pt content width. A 24 pt gutter gives two 237.64 pt columns, or a 158.43 / 316.85 pt asymmetric split. Use a 0.6 pt rule and square corners. Running labels sit above the reading field; a fine rule and actual folio close each page.
47
+
48
+ Use `NeutralPages` for flowing reading, white evidence, or charcoal pages. Its header/footer repeat on continuation pages. Ordinary prose must be allowed to flow. Use `NeutralColumns` for independent bounded material, not sequential story text. An opening may have a large deliberate gap; a long report should not be manually paginated paragraph by paragraph.
49
+
50
+ ## Reusable compositions
51
+
52
+ See [components.tsx](components.tsx) for the executable implementations.
53
+
54
+ - `NeutralPages`: title, optional label, surface (`paper`, `white`, `dark`), optional header, and children. On dark surfaces, explicitly give standard headings, paragraphs, and captions the corresponding inverse color; their semantic theme colors otherwise remain dark ink.
55
+ - `NeutralOpening`: stable id, eyebrow, title, optional subtitle, surface, and optional display scale. Keeps the same title/subtitle identities when its text changes.
56
+ - `NeutralColumns`: left and right content, equal or narrow-left ratio, optional native style. Give each column its own reading path.
57
+ - `NeutralQuote`: stable id, authored quote, attribution, and surface. Uses a 2 pt leading rule and a real serif italic face. Attribute original house copy honestly.
58
+ - `PaperStudy`: stable id and surface. Three native page-like planes (114, 150, and 186 pt high, with 16 pt gaps) express the move from working material to a finished page. Use only as an opening or closing visual, not as repeated filler.
59
+
60
+ ## Evidence, imagery, and identity
61
+
62
+ Tables have charcoal column headers, white labels, 8 pt cell padding, restrained alternating rows (#F1F1EE), and 0.5 pt bottom rules. Keep numeric columns right aligned. Captions and source notes stay close to figures. Use managed chart images, retain prepared data and recipes, and repeat the key values in selectable text or a native table. Clearly label synthetic demonstrations.
63
+
64
+ Images keep their aspect ratio. Favor a substantial image and an explanatory caption over a collage of tiny decorations. A dark gallery page can let a photograph carry the composition. Generated artwork must be labeled as such and retain its prompt/provenance; it is not documentary evidence.
65
+
66
+ The shared OpenDoc logo is the existing wordmark, imported from `assets/brand/wordmark.png`. Its dark variation belongs on light surfaces. Preserve the original proportions and transparency. Place it explicitly through a saved `Logo` binding; no mark is inserted automatically. The theme's specimen stays self-contained and does not rely on a document's private media.
67
+
68
+ ## Basis
69
+
70
+ Original house system created for the user's OpenDoc Neutral brief: tasteful neutral styling, a welcome document that demonstrates varied layouts, detailed data graphics, generated imagery, identity, and light/dark pages. The existing OpenDoc wordmark and bundled local font families are retained. The composition and palette are original design interpretations, not an adaptation of an external brand. The independent specimen and the welcome document are the review surfaces.
@@ -0,0 +1,54 @@
1
+ import type { DocTheme } from 'opendoc/themes';
2
+
3
+ export const colors = {
4
+ paper: '#FCFBF8', white: '#FFFFFF', ink: '#171A1D', muted: '#62686D',
5
+ blue: '#3758F9', wash: '#ECEEF9', rule: '#D7D7D2', stone: '#EAE7DF',
6
+ night: '#171A1D', inverse: '#F7F6F2', inverseMuted: '#B6BABE', inverseRule: '#41464B',
7
+ };
8
+ export const metrics = { margin: 48, bottom: 56, gutter: 24, rule: 0.6, unit: 6, measure: 499.28 };
9
+
10
+ export const theme: DocTheme = {
11
+ id: 'opendoc-neutral', name: 'OpenDoc Neutral',
12
+ description: 'The OpenDoc house style: warm paper, charcoal, a precise blue signal, generous typography, and a flexible editorial grid.',
13
+ body: 'OpenDoc Sans', heading: 'OpenDoc Sans',
14
+ ink: colors.ink, muted: colors.muted, accent: colors.blue, paper: colors.paper, line: colors.rule,
15
+ fontSize: 10.5, lineHeight: 1.48, margin: metrics.margin, paragraphGap: 10,
16
+ pageSize: 'A4', runningHeader: true, runningFooter: true, footerLabel: 'OpenDoc',
17
+ useFor: ['Everyday documents with a considered identity', 'Editorial guides and visual reports', 'Proposals, evidence, and working papers'],
18
+ principles: ['Use scale and whitespace before adding decoration.', 'Give the reader one clear point of entry.', 'Use blue to identify what matters.', 'Let long content flow; compose short material deliberately.'],
19
+ palette: [
20
+ { name: 'Paper', value: colors.paper, role: 'Warm reading pages' },
21
+ { name: 'White', value: colors.white, role: 'Analytical pages and image fields' },
22
+ { name: 'Ink', value: colors.ink, role: 'Primary text and dark page surface' },
23
+ { name: 'Muted', value: colors.muted, role: 'Secondary explanations and captions' },
24
+ { name: 'Blue', value: colors.blue, role: 'A single emphasis, citation, or chart focus' },
25
+ { name: 'Wash', value: colors.wash, role: 'Occasional supporting panel' },
26
+ { name: 'Stone', value: colors.stone, role: 'Neutral structure and diagram fields' },
27
+ { name: 'Rule', value: colors.rule, role: 'Fine dividers and table boundaries' },
28
+ { name: 'Inverse', value: colors.inverse, role: 'Text on charcoal pages' },
29
+ { name: 'Inverse muted', value: colors.inverseMuted, role: 'Captions and secondary text on charcoal' },
30
+ { name: 'Inverse rule', value: colors.inverseRule, role: 'Dividers on charcoal' },
31
+ ],
32
+ geometry: ['A4 portrait; 48 pt top/side and 56 pt bottom margins.', 'A 499 pt content field: equal columns or a 1:2 split, with 24 pt gutters.', 'A 6 pt spacing unit; 0.6 pt rules; square corners.', '10.5 pt reading type at 1.48 leading; 34 pt openings and 62 pt display type.', 'Warm reading pages, white analytical pages, and charcoal image or closing pages.'],
33
+ design: {
34
+ page: { margin: { top: 48, right: 48, bottom: 56, left: 48 }, style: { backgroundColor: colors.paper } },
35
+ typography: {
36
+ h1: { fontSize: 34, fontWeight: 600, lineHeight: 1.08, letterSpacing: -1.1, marginTop: 0, marginBottom: 18 },
37
+ h2: { fontSize: 20, fontWeight: 600, lineHeight: 1.18, letterSpacing: -0.35, marginTop: 20, marginBottom: 10 },
38
+ h3: { fontSize: 12, fontWeight: 600, lineHeight: 1.25, marginTop: 14, marginBottom: 8 },
39
+ label: { fontFamily: 'OpenDoc Mono', fontSize: 7.5, letterSpacing: 0.7, color: colors.blue },
40
+ lead: { fontSize: 13, lineHeight: 1.45, color: colors.muted },
41
+ small: { fontFamily: 'OpenDoc Sans', fontSize: 8, lineHeight: 1.4, color: colors.muted },
42
+ caption: { fontFamily: 'OpenDoc Sans', fontSize: 8.5, lineHeight: 1.4, color: colors.muted },
43
+ code: { fontFamily: 'OpenDoc Mono', fontSize: 8, lineHeight: 1.5, color: colors.ink },
44
+ },
45
+ title: { block: { paddingBottom: 24, borderBottomWidth: 0, marginBottom: 18 }, heading: { fontSize: 34 }, eyebrow: { marginBottom: 16 }, subtitle: { fontSize: 13 }, uppercaseEyebrow: false },
46
+ cover: { title: { fontSize: 62, lineHeight: 1.03, letterSpacing: -2.1 }, subtitle: { fontSize: 16 }, page: { backgroundColor: colors.paper } },
47
+ furniture: { text: { fontFamily: 'OpenDoc Mono', fontSize: 7, color: colors.muted }, header: { paddingBottom: 18 }, footer: { borderTopWidth: 0.6, paddingTop: 10 }, pageNumber: 'page', uppercaseHeader: false },
48
+ table: { block: { marginTop: 10, marginBottom: 18 }, header: { backgroundColor: colors.ink }, headerText: { fontSize: 8, fontWeight: 600, color: colors.white }, cell: { padding: 8, borderBottomWidth: 0.5 }, text: { fontSize: 9, lineHeight: 1.35 }, alternate: '#F1F1EE' },
49
+ figure: { block: { marginTop: 10, marginBottom: 16 } },
50
+ callout: { block: { backgroundColor: colors.wash, borderLeftWidth: 2, borderColor: colors.blue, padding: 16 }, title: { fontSize: 8, color: colors.blue }, text: { fontSize: 10, lineHeight: 1.45 } },
51
+ code: { block: { marginTop: 8, marginBottom: 16 }, panel: { backgroundColor: colors.stone, padding: 16 } },
52
+ list: { gap: 8, markerWidth: 16, item: { fontSize: 10.5, lineHeight: 1.45 } },
53
+ },
54
+ };
@@ -0,0 +1,43 @@
1
+ import { Document, Paragraph, Heading, DataTable, Strong, View } from 'opendoc';
2
+ import { theme, colors } from './index';
3
+ import { NeutralPages, NeutralOpening, NeutralColumns, NeutralQuote, PaperStudy } from './components';
4
+
5
+ export const meta = { title: 'OpenDoc Neutral', description: 'A three-page house-style specimen: typographic identity, a working report, and a charcoal closing.', theme: theme.id };
6
+ export default function Specimen() {
7
+ return <Document title={meta.title} theme={theme}>
8
+ <NeutralPages title="The house style" header={false}>
9
+ <Paragraph id="specimen-wordmark" style={{ fontSize: 18, fontWeight: 600, letterSpacing: -0.5, marginBottom: 72 }}>OpenDoc</Paragraph>
10
+ <NeutralOpening id="specimen-opening" eyebrow="A HOUSE STYLE / 01" title={'Clarity has\ncharacter.'} subtitle="OpenDoc Neutral brings a considered visual language to everyday work." display />
11
+ <Paragraph id="specimen-intent" style={{ width: 365, marginTop: 8, marginBottom: 42 }}>Warm paper. Confident typography. A precise blue signal. A flexible grid that gives words, images, and evidence room to do their work.</Paragraph>
12
+ <PaperStudy id="specimen-paper-study" />
13
+ <Paragraph id="specimen-caption" role="small" style={{ marginTop: 18 }}>One visual language, from a short working note to a substantial publication.</Paragraph>
14
+ </NeutralPages>
15
+ <NeutralPages title="Applied / a working report" surface="white">
16
+ <NeutralOpening id="specimen-report" eyebrow="A WORKING REPORT / 02" title="Make the decision easy to find." subtitle="A fictional studio review shows the system at reading scale." />
17
+ <NeutralColumns left={<>
18
+ <Heading id="specimen-principle" level={2} style={{ marginTop: 0 }}>Start with the reader</Heading>
19
+ <Paragraph id="specimen-reading">A useful report gives the reader a clear reason to continue. Put the decision near the beginning, develop the evidence, and keep qualifications close to the claim they affect.</Paragraph>
20
+ <Paragraph id="specimen-long-reading">This column is ordinary selectable text. It can be revised without redrawing the page, and longer sections can continue naturally. The grid supplies structure while the content determines how much space is needed.</Paragraph>
21
+ </>} right={<>
22
+ <Heading id="specimen-evidence" level={2} style={{ marginTop: 0 }}>Keep the basis visible</Heading>
23
+ <Paragraph id="specimen-evidence-copy">Every number below is <Strong>illustrative</Strong>. A restrained header, aligned values, and a nearby source note make the comparison easy to inspect.</Paragraph>
24
+ <Paragraph id="specimen-review-copy">Use fine rules instead of a dense cage. Keep labels short and units explicit. Preserve the data and record identities when an agent prepares the next edition.</Paragraph>
25
+ </>} />
26
+ <DataTable id="specimen-table" caption="Illustrative studio allocation" columns={[{ label: 'Workstream', width: 2 }, { label: 'Hours', align: 'right' }, { label: 'Share', align: 'right' }]} rows={[["Research", 24, '20%'], ["Drafting", 48, '40%'], ["Design", 30, '25%'], ["Review", 18, '15%']]} rowIds={['research', 'drafting', 'design', 'review']} sourceNote="Synthetic specimen values, totaling 120 hours. No work was measured." />
27
+ <NeutralQuote id="specimen-quote" attribution="OpenDoc / house principle">Give the page a clear purpose, then give it room.</NeutralQuote>
28
+ </NeutralPages>
29
+ <NeutralPages title="A change of pace" surface="dark">
30
+ <NeutralOpening id="specimen-dark" eyebrow="THE INVERSE SURFACE / 03" title={'Quiet pages.\nStrong ideas.'} subtitle="Charcoal creates a deliberate pause for an opening, a large image, or a final thought." surface="dark" display />
31
+ <NeutralQuote id="specimen-dark-quote" attribution="Original OpenDoc house copy" surface="dark">The craft is in what the reader can see, understand, and use.</NeutralQuote>
32
+ <View style={{ marginTop: 32 }}><NeutralColumns left={<>
33
+ <Paragraph id="specimen-dark-grid" role="label" style={{ color: colors.inverseMuted }}>GRID</Paragraph>
34
+ <Paragraph id="specimen-dark-grid-copy" style={{ color: colors.inverse }}>A4 portrait. 48 pt side margins. 24 pt gutters. Equal columns or a one-to-two split.</Paragraph>
35
+ </>} right={<>
36
+ <Paragraph id="specimen-dark-type" role="label" style={{ color: colors.inverseMuted }}>VOICE</Paragraph>
37
+ <Paragraph id="specimen-dark-type-copy" style={{ color: colors.inverse }}>Sans for clarity, serif italic for reflection, monospace for labels. Real local faces, embedded in the PDF.</Paragraph>
38
+ </>} /></View>
39
+ <View style={{ marginTop: 36, flexDirection: 'row', gap: 12 }}>{[colors.paper, colors.stone, colors.muted, colors.blue].map(color => <View key={color} style={{ height: 42, flex: 1, backgroundColor: color }} />)}</View>
40
+ <Paragraph id="specimen-dark-end" role="small" style={{ marginTop: 18, color: colors.inverseMuted }}>The guide and reusable source components live with the theme. The finished welcome document shows the same system with real media and shared assets.</Paragraph>
41
+ </NeutralPages>
42
+ </Document>;
43
+ }
@@ -0,0 +1,3 @@
1
+ // Compatibility entry for existing workspace themes. New themes can import from opendoc/themes.
2
+ export { themeType, themePage, validateTheme } from 'opendoc/themes';
3
+ export type { DocTheme, ThemeDesign, ThemeFont, ThemeTypeRole } from 'opendoc/themes';
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "jsx": "react-jsx",
8
+ "jsxImportSource": "opendoc",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "resolveJsonModule": true,
12
+ "skipLibCheck": true,
13
+ "noEmit": true,
14
+ "allowImportingTsExtensions": true,
15
+ "baseUrl": ".",
16
+ "typeRoots": ["./node_modules/@types"],
17
+ "types": ["node"],
18
+ "paths": {
19
+ "react": ["./node_modules/@types/react/index.d.ts"],
20
+ "react/*": ["./node_modules/@types/react/*"],
21
+ "@formepdf/react": ["./node_modules/@formepdf/react/dist/index.d.ts"]
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Daniel Molitor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,97 @@
1
+ # Forme text writer and font subset repair
2
+
3
+ OpenDoc uses `@formepdf/core` **0.20.1-opendoc.3**, based on upstream
4
+ [`v0.20.1`, commit `0d706f839617b775e90edcc93d6001a8b0145a78`](https://github.com/formepdf/forme/tree/0d706f839617b775e90edcc93d6001a8b0145a78).
5
+ The published JavaScript interface is unchanged. `text-writer.patch` repairs the
6
+ Rust PDF writer, while `font-subset.patch` repairs embedded TrueType metadata.
7
+ The source repository's archive contains rebuilt bundler, web, and Node WASM
8
+ engines. The workspace override pins this repaired engine for contributors.
9
+
10
+ Both installable editions, `opendoc` and `opendoc-headless`, bundle this repaired
11
+ core with Forme's React serializer and shared JavaScript definitions.
12
+ `pnpm package:pack` materializes ordinary npm trees in temporary staging
13
+ directories. Both editions render in Node, so distribution retains the repaired
14
+ `pkg-node` engine byte for byte and omits the unused browser and worker WASM
15
+ targets. The staged core manifest exposes only its Node entry and layout helpers;
16
+ it does not advertise the removed targets. The duplicate source archive remains
17
+ in this repository and is excluded from both runtime packages. Consumers need no
18
+ override, local archive path, Rust tools, or build hook. Native dependencies such
19
+ as `esbuild`, canvas, and resvg stay unbundled so npm installs the binaries
20
+ appropriate to the consumer's operating system and architecture.
21
+
22
+ OpenDoc already supplies its own TSX bundling and source-location capture. The
23
+ only remaining `@formepdf/renderer` operation was asset source resolution.
24
+ `src/rendering/resolve-sources.ts` retains the 0.20.1 package's `dist/resolve.js`
25
+ implementation, with only TypeScript annotations and formatting changes. This
26
+ avoids importing the unrelated HTML compiler. Its copyright is Daniel Molitor,
27
+ 2026, and the MIT license in this directory covers the retained resolver as well
28
+ as the engine. Future upgrades should compare that small module with the
29
+ upstream resolver explicitly.
30
+
31
+ The `opendoc.3` build also remaps local source, home, Cargo, and toolchain paths
32
+ to anonymous `/build/` paths using Rust's
33
+ [`--remap-path-prefix`](https://doc.rust-lang.org/rustc/remap-source-paths.html).
34
+ This removes builder-specific paths from embedded panic diagnostics without
35
+ changing the renderer API. The rebuild script checks every generated WASM engine
36
+ for the original local paths before packaging it.
37
+
38
+ ## Repair
39
+
40
+ - Allocate PDF character codes by glyph **and source text**, with an explicit
41
+ CIDToGIDMap. A shaped `fi` and literal `fi` can use the same glyph without losing
42
+ their distinct source text.
43
+ - Write full UTF-16BE sequences in ToUnicode, including ligatures and surrogate
44
+ pairs. Keep the original GSUB, GPOS, and kerning tables in every imported font.
45
+ - Position custom-font glyphs using their shaped x/y coordinates, including
46
+ kerning, mark offsets, letter spacing, and cumulative justified spaces. Use the
47
+ same positioning for watermarks. Preserve fractional font sizes and widths.
48
+ - Reset word spacing at style boundaries to avoid leaking custom-font text state.
49
+ - Record actual TrueType table lengths while keeping table starts aligned to
50
+ four bytes. In particular, a short `loca` contains exactly `numGlyphs + 1`
51
+ entries; alignment padding is outside its recorded length.
52
+ - Preserve the original `maxp` profile except for `numGlyphs`. The retained
53
+ outlines, glyph instructions, and copied `fpgm`, `prep`, and `cvt ` tables still
54
+ need the original interpreter resource limits.
55
+ - Keep the `head` directory checksum calculated with zero `checkSumAdjustment`.
56
+ Write the adjustment only into the table, so the whole font sums to `0xB1B0AFBA`.
57
+
58
+ These metadata repairs follow the OpenType [font file and checksum
59
+ rules](https://learn.microsoft.com/en-us/typography/opentype/spec/otff) and
60
+ [`maxp` profile](https://learn.microsoft.com/en-us/typography/opentype/spec/maxp).
61
+
62
+ This is a source-level engine fix. It does not alter font files, disable shaping,
63
+ normalize away missing spaces, or relax compatibility checks. Existing renamed
64
+ OpenDoc font derivatives remain unchanged for document continuity.
65
+
66
+ ## Rebuild
67
+
68
+ In a source checkout, `pnpm install --frozen-lockfile` uses the checked-in archive
69
+ and needs no Rust tools. To rebuild from that checkout, install Rust **1.98.1**, its `wasm32-unknown-unknown` target,
70
+ and **wasm-pack 0.15.0**, then run:
71
+
72
+ ```sh
73
+ node scripts/rebuild-forme.mjs
74
+ ```
75
+
76
+ The script verifies the upstream commit and original npm tarball SHA-512, applies
77
+ both readable patches, runs the engine's library tests, builds all three WASM entry
78
+ points with the upstream lockfile, and packages the existing published JS with
79
+ those engines. Build files stay in a fresh operating-system temporary directory;
80
+ an optional first argument chooses a new directory that must not already exist.
81
+ The printed directory is retained for inspecting build results. Set
82
+ `RUSTUP_TOOLCHAIN=stable` only if that
83
+ installed toolchain is exactly 1.98.1.
84
+
85
+ After deliberately replacing the archive, refresh the pnpm lockfile and run
86
+ `pnpm check`, `pnpm test`, and `pnpm build`. Review the PDF specimens for all five
87
+ Google Fonts families and verify their original file hashes. See
88
+ `tests/font-renderer.test.ts` for PDF extraction and geometry regressions and
89
+ `tests/font-subset.test.ts` for lengths, checksums, and hinting metadata read from
90
+ the actual embedded font streams. The subset patch also contains Rust regressions
91
+ for alignment, checksums, and profile preservation using the upstream font fixture.
92
+
93
+ ## Upstream replacement
94
+
95
+ When an upstream version includes equivalent fixes, remove the local override
96
+ and archive only after these regressions and existing document checks pass.
97
+ The patch and engine remain under Forme's MIT license, retained in `LICENSE`.