@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.
- package/.agents/skills/opendoc-apply-comments/SKILL.md +30 -0
- package/.agents/skills/opendoc-apply-comments/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-create/SKILL.md +63 -0
- package/.agents/skills/opendoc-create/agents/openai.yaml +6 -0
- package/.agents/skills/opendoc-create-template/SKILL.md +50 -0
- package/.agents/skills/opendoc-create-template/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-create-template/references/structured-reports.md +11 -0
- package/.agents/skills/opendoc-create-theme/SKILL.md +40 -0
- package/.agents/skills/opendoc-create-theme/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-current-document/SKILL.md +32 -0
- package/.agents/skills/opendoc-current-document/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-current-document/references/context-fields.md +20 -0
- package/.agents/skills/opendoc-review-document/SKILL.md +60 -0
- package/.agents/skills/opendoc-review-document/agents/openai.yaml +4 -0
- package/AGENTS.md +69 -0
- package/CONTRIBUTING.md +38 -0
- package/LICENSE +21 -0
- package/README.md +179 -0
- package/SECURITY.md +9 -0
- package/THIRD_PARTY.md +49 -0
- package/VALIDATION.md +99 -0
- package/bin/opendoc.mjs +6 -0
- package/dist/assets/Markdown-sNZyjJi7.js +29 -0
- package/dist/assets/OpenDocSerif-Regular-D3OXs9A9.ttf +0 -0
- package/dist/assets/OpenDocSerif-Semibold-CjL9oDRo.ttf +0 -0
- package/dist/assets/geist-latin-ext-wght-italic-XgKbg5n7.woff2 +0 -0
- package/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/assets/geist-latin-wght-italic-dTnRTFFJ.woff2 +0 -0
- package/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/assets/index-DdrZ6ozO.css +1 -0
- package/dist/assets/index-DgNBz7mL.js +39 -0
- package/dist/assets/pdf-B7Emtyld.js +54 -0
- package/dist/assets/pdf.worker.min-Dswkl-cV.mjs +29 -0
- package/dist/assets/wordmark-DsqLlZpb.png +0 -0
- package/dist/index.html +17 -0
- package/docs/APPEARANCE.md +21 -0
- package/docs/ASSETS.md +176 -0
- package/docs/AUTHORING.md +178 -0
- package/docs/HEADLESS.md +120 -0
- package/docs/MEDIA.md +112 -0
- package/docs/PROJECTS.md +55 -0
- package/docs/PROSE.md +15 -0
- package/docs/SELECTION.md +59 -0
- package/docs/TEMPLATES.md +55 -0
- package/docs/THEMES.md +106 -0
- package/node_modules/@formepdf/core/LICENSE +21 -0
- package/node_modules/@formepdf/core/README.md +53 -0
- package/node_modules/@formepdf/core/dist/attachments.d.ts +55 -0
- package/node_modules/@formepdf/core/dist/attachments.js +59 -0
- package/node_modules/@formepdf/core/dist/extract.d.ts +8 -0
- package/node_modules/@formepdf/core/dist/extract.js +56 -0
- package/node_modules/@formepdf/core/dist/index.d.ts +311 -0
- package/node_modules/@formepdf/core/dist/index.js +167 -0
- package/node_modules/@formepdf/core/dist/layout.d.ts +132 -0
- package/node_modules/@formepdf/core/dist/layout.js +240 -0
- package/node_modules/@formepdf/core/dist/shared/browserHelpers.d.ts +19 -0
- package/node_modules/@formepdf/core/dist/shared/browserHelpers.js +128 -0
- package/node_modules/@formepdf/core/package.json +35 -0
- package/node_modules/@formepdf/core/pkg-node/LICENSE +21 -0
- package/node_modules/@formepdf/core/pkg-node/README.md +84 -0
- package/node_modules/@formepdf/core/pkg-node/forme.d.ts +39 -0
- package/node_modules/@formepdf/core/pkg-node/forme.js +394 -0
- package/node_modules/@formepdf/core/pkg-node/forme_bg.wasm +0 -0
- package/node_modules/@formepdf/core/pkg-node/forme_bg.wasm.d.ts +21 -0
- package/node_modules/@formepdf/core/pkg-node/package.json +25 -0
- package/node_modules/@formepdf/react/README.md +70 -0
- package/node_modules/@formepdf/react/dist/charts.d.ts +72 -0
- package/node_modules/@formepdf/react/dist/charts.js +338 -0
- package/node_modules/@formepdf/react/dist/components.d.ts +533 -0
- package/node_modules/@formepdf/react/dist/components.js +608 -0
- package/node_modules/@formepdf/react/dist/expr.d.ts +20 -0
- package/node_modules/@formepdf/react/dist/expr.js +39 -0
- package/node_modules/@formepdf/react/dist/font.d.ts +2 -0
- package/node_modules/@formepdf/react/dist/font.js +1 -0
- package/node_modules/@formepdf/react/dist/index.d.ts +11 -0
- package/node_modules/@formepdf/react/dist/index.js +15 -0
- package/node_modules/@formepdf/react/dist/render.d.ts +12 -0
- package/node_modules/@formepdf/react/dist/render.js +15 -0
- package/node_modules/@formepdf/react/dist/serialize.d.ts +12 -0
- package/node_modules/@formepdf/react/dist/serialize.js +1470 -0
- package/node_modules/@formepdf/react/dist/stylesheet.d.ts +4 -0
- package/node_modules/@formepdf/react/dist/stylesheet.js +5 -0
- package/node_modules/@formepdf/react/dist/template-proxy.d.ts +38 -0
- package/node_modules/@formepdf/react/dist/template-proxy.js +100 -0
- package/node_modules/@formepdf/react/dist/types.d.ts +287 -0
- package/node_modules/@formepdf/react/dist/types.js +1 -0
- package/node_modules/@formepdf/react/package.json +41 -0
- package/node_modules/@formepdf/shared/README.md +7 -0
- package/node_modules/@formepdf/shared/dist/canvas.d.ts +6 -0
- package/node_modules/@formepdf/shared/dist/canvas.js +43 -0
- package/node_modules/@formepdf/shared/dist/charts.d.ts +100 -0
- package/node_modules/@formepdf/shared/dist/charts.js +98 -0
- package/node_modules/@formepdf/shared/dist/encode.d.ts +27 -0
- package/node_modules/@formepdf/shared/dist/encode.js +93 -0
- package/node_modules/@formepdf/shared/dist/font.d.ts +13 -0
- package/node_modules/@formepdf/shared/dist/font.js +52 -0
- package/node_modules/@formepdf/shared/dist/index.d.ts +10 -0
- package/node_modules/@formepdf/shared/dist/index.js +15 -0
- package/node_modules/@formepdf/shared/dist/parser.d.ts +30 -0
- package/node_modules/@formepdf/shared/dist/parser.js +756 -0
- package/node_modules/@formepdf/shared/dist/semantics.d.ts +15 -0
- package/node_modules/@formepdf/shared/dist/semantics.js +44 -0
- package/node_modules/@formepdf/shared/dist/style.d.ts +7 -0
- package/node_modules/@formepdf/shared/dist/style.js +1024 -0
- package/node_modules/@formepdf/shared/dist/types.d.ts +743 -0
- package/node_modules/@formepdf/shared/dist/types.js +2 -0
- package/node_modules/@formepdf/shared/package.json +35 -0
- package/node_modules/@types/node/LICENSE +21 -0
- package/node_modules/@types/node/README.md +15 -0
- package/node_modules/@types/node/assert/strict.d.ts +111 -0
- package/node_modules/@types/node/assert.d.ts +1078 -0
- package/node_modules/@types/node/async_hooks.d.ts +603 -0
- package/node_modules/@types/node/buffer.buffer.d.ts +472 -0
- package/node_modules/@types/node/buffer.d.ts +1934 -0
- package/node_modules/@types/node/child_process.d.ts +1476 -0
- package/node_modules/@types/node/cluster.d.ts +578 -0
- package/node_modules/@types/node/compatibility/disposable.d.ts +14 -0
- package/node_modules/@types/node/compatibility/index.d.ts +9 -0
- package/node_modules/@types/node/compatibility/indexable.d.ts +20 -0
- package/node_modules/@types/node/compatibility/iterators.d.ts +20 -0
- package/node_modules/@types/node/console.d.ts +452 -0
- package/node_modules/@types/node/constants.d.ts +21 -0
- package/node_modules/@types/node/crypto.d.ts +4545 -0
- package/node_modules/@types/node/dgram.d.ts +600 -0
- package/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
- package/node_modules/@types/node/dns/promises.d.ts +503 -0
- package/node_modules/@types/node/dns.d.ts +923 -0
- package/node_modules/@types/node/domain.d.ts +170 -0
- package/node_modules/@types/node/events.d.ts +976 -0
- package/node_modules/@types/node/fs/promises.d.ts +1306 -0
- package/node_modules/@types/node/fs.d.ts +4463 -0
- package/node_modules/@types/node/globals.d.ts +172 -0
- package/node_modules/@types/node/globals.typedarray.d.ts +38 -0
- package/node_modules/@types/node/http.d.ts +2097 -0
- package/node_modules/@types/node/http2.d.ts +2843 -0
- package/node_modules/@types/node/https.d.ts +579 -0
- package/node_modules/@types/node/index.d.ts +98 -0
- package/node_modules/@types/node/inspector.d.ts +253 -0
- package/node_modules/@types/node/inspector.generated.d.ts +4052 -0
- package/node_modules/@types/node/module.d.ts +891 -0
- package/node_modules/@types/node/net.d.ts +1076 -0
- package/node_modules/@types/node/os.d.ts +506 -0
- package/node_modules/@types/node/package.json +145 -0
- package/node_modules/@types/node/path.d.ts +200 -0
- package/node_modules/@types/node/perf_hooks.d.ts +968 -0
- package/node_modules/@types/node/process.d.ts +2084 -0
- package/node_modules/@types/node/punycode.d.ts +117 -0
- package/node_modules/@types/node/querystring.d.ts +152 -0
- package/node_modules/@types/node/readline/promises.d.ts +161 -0
- package/node_modules/@types/node/readline.d.ts +594 -0
- package/node_modules/@types/node/repl.d.ts +428 -0
- package/node_modules/@types/node/sea.d.ts +162 -0
- package/node_modules/@types/node/sqlite.d.ts +722 -0
- package/node_modules/@types/node/stream/consumers.d.ts +38 -0
- package/node_modules/@types/node/stream/promises.d.ts +90 -0
- package/node_modules/@types/node/stream/web.d.ts +573 -0
- package/node_modules/@types/node/stream.d.ts +1694 -0
- package/node_modules/@types/node/string_decoder.d.ts +67 -0
- package/node_modules/@types/node/test.d.ts +2265 -0
- package/node_modules/@types/node/timers/promises.d.ts +108 -0
- package/node_modules/@types/node/timers.d.ts +287 -0
- package/node_modules/@types/node/tls.d.ts +1319 -0
- package/node_modules/@types/node/trace_events.d.ts +197 -0
- package/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +468 -0
- package/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +34 -0
- package/node_modules/@types/node/ts5.6/index.d.ts +98 -0
- package/node_modules/@types/node/tty.d.ts +208 -0
- package/node_modules/@types/node/url.d.ts +984 -0
- package/node_modules/@types/node/util.d.ts +2606 -0
- package/node_modules/@types/node/v8.d.ts +920 -0
- package/node_modules/@types/node/vm.d.ts +1053 -0
- package/node_modules/@types/node/wasi.d.ts +181 -0
- package/node_modules/@types/node/web-globals/abortcontroller.d.ts +34 -0
- package/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
- package/node_modules/@types/node/web-globals/events.d.ts +97 -0
- package/node_modules/@types/node/web-globals/fetch.d.ts +55 -0
- package/node_modules/@types/node/web-globals/navigator.d.ts +22 -0
- package/node_modules/@types/node/web-globals/storage.d.ts +24 -0
- package/node_modules/@types/node/web-globals/streams.d.ts +22 -0
- package/node_modules/@types/node/worker_threads.d.ts +819 -0
- package/node_modules/@types/node/zlib.d.ts +747 -0
- package/node_modules/@types/react/LICENSE +21 -0
- package/node_modules/@types/react/README.md +15 -0
- package/node_modules/@types/react/canary.d.ts +129 -0
- package/node_modules/@types/react/compiler-runtime.d.ts +4 -0
- package/node_modules/@types/react/experimental.d.ts +184 -0
- package/node_modules/@types/react/global.d.ts +166 -0
- package/node_modules/@types/react/index.d.ts +4378 -0
- package/node_modules/@types/react/jsx-dev-runtime.d.ts +33 -0
- package/node_modules/@types/react/jsx-runtime.d.ts +24 -0
- package/node_modules/@types/react/package.json +210 -0
- package/node_modules/@types/react/ts5.0/canary.d.ts +129 -0
- package/node_modules/@types/react/ts5.0/experimental.d.ts +184 -0
- package/node_modules/@types/react/ts5.0/global.d.ts +166 -0
- package/node_modules/@types/react/ts5.0/index.d.ts +4365 -0
- package/node_modules/@types/react/ts5.0/jsx-dev-runtime.d.ts +33 -0
- package/node_modules/@types/react/ts5.0/jsx-runtime.d.ts +24 -0
- package/node_modules/csstype/LICENSE +19 -0
- package/node_modules/csstype/README.md +291 -0
- package/node_modules/csstype/index.d.ts +22569 -0
- package/node_modules/csstype/index.js.flow +6863 -0
- package/node_modules/csstype/package.json +70 -0
- package/node_modules/entities/LICENSE +11 -0
- package/node_modules/entities/decode.d.ts +1 -0
- package/node_modules/entities/decode.js +3 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts +19 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.js +77 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.js.map +1 -0
- package/node_modules/entities/dist/commonjs/decode.d.ts +209 -0
- package/node_modules/entities/dist/commonjs/decode.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/decode.js +511 -0
- package/node_modules/entities/dist/commonjs/decode.js.map +1 -0
- package/node_modules/entities/dist/commonjs/encode.d.ts +22 -0
- package/node_modules/entities/dist/commonjs/encode.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/encode.js +73 -0
- package/node_modules/entities/dist/commonjs/encode.js.map +1 -0
- package/node_modules/entities/dist/commonjs/escape.d.ts +43 -0
- package/node_modules/entities/dist/commonjs/escape.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/escape.js +121 -0
- package/node_modules/entities/dist/commonjs/escape.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts +2 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.js +10 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts +2 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js +10 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts +8 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.js +13 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.js.map +1 -0
- package/node_modules/entities/dist/commonjs/index.d.ts +96 -0
- package/node_modules/entities/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/index.js +131 -0
- package/node_modules/entities/dist/commonjs/index.js.map +1 -0
- package/node_modules/entities/dist/commonjs/package.json +3 -0
- package/node_modules/entities/dist/esm/decode-codepoint.d.ts +19 -0
- package/node_modules/entities/dist/esm/decode-codepoint.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/decode-codepoint.js +72 -0
- package/node_modules/entities/dist/esm/decode-codepoint.js.map +1 -0
- package/node_modules/entities/dist/esm/decode.d.ts +209 -0
- package/node_modules/entities/dist/esm/decode.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/decode.js +497 -0
- package/node_modules/entities/dist/esm/decode.js.map +1 -0
- package/node_modules/entities/dist/esm/encode.d.ts +22 -0
- package/node_modules/entities/dist/esm/encode.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/encode.js +69 -0
- package/node_modules/entities/dist/esm/encode.js.map +1 -0
- package/node_modules/entities/dist/esm/escape.d.ts +43 -0
- package/node_modules/entities/dist/esm/escape.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/escape.js +117 -0
- package/node_modules/entities/dist/esm/escape.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts +2 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.js +7 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts +2 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.js +7 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/encode-html.d.ts +8 -0
- package/node_modules/entities/dist/esm/generated/encode-html.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/encode-html.js +10 -0
- package/node_modules/entities/dist/esm/generated/encode-html.js.map +1 -0
- package/node_modules/entities/dist/esm/index.d.ts +96 -0
- package/node_modules/entities/dist/esm/index.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/index.js +107 -0
- package/node_modules/entities/dist/esm/index.js.map +1 -0
- package/node_modules/entities/dist/esm/package.json +3 -0
- package/node_modules/entities/escape.d.ts +1 -0
- package/node_modules/entities/escape.js +3 -0
- package/node_modules/entities/package.json +118 -0
- package/node_modules/entities/readme.md +122 -0
- package/node_modules/entities/src/decode-codepoint.ts +81 -0
- package/node_modules/entities/src/decode.spec.ts +320 -0
- package/node_modules/entities/src/decode.ts +620 -0
- package/node_modules/entities/src/encode.spec.ts +78 -0
- package/node_modules/entities/src/encode.ts +77 -0
- package/node_modules/entities/src/escape.spec.ts +14 -0
- package/node_modules/entities/src/escape.ts +148 -0
- package/node_modules/entities/src/generated/.eslintrc.json +10 -0
- package/node_modules/entities/src/generated/decode-data-html.ts +8 -0
- package/node_modules/entities/src/generated/decode-data-xml.ts +8 -0
- package/node_modules/entities/src/generated/encode-html.ts +17 -0
- package/node_modules/entities/src/index.spec.ts +125 -0
- package/node_modules/entities/src/index.ts +188 -0
- package/node_modules/parse5/LICENSE +19 -0
- package/node_modules/parse5/README.md +38 -0
- package/node_modules/parse5/dist/cjs/common/doctype.d.ts +4 -0
- package/node_modules/parse5/dist/cjs/common/doctype.js +118 -0
- package/node_modules/parse5/dist/cjs/common/error-codes.d.ts +67 -0
- package/node_modules/parse5/dist/cjs/common/error-codes.js +66 -0
- package/node_modules/parse5/dist/cjs/common/foreign-content.d.ts +9 -0
- package/node_modules/parse5/dist/cjs/common/foreign-content.js +237 -0
- package/node_modules/parse5/dist/cjs/common/html.d.ts +289 -0
- package/node_modules/parse5/dist/cjs/common/html.js +528 -0
- package/node_modules/parse5/dist/cjs/common/token.d.ts +84 -0
- package/node_modules/parse5/dist/cjs/common/token.js +24 -0
- package/node_modules/parse5/dist/cjs/common/unicode.d.ts +42 -0
- package/node_modules/parse5/dist/cjs/common/unicode.js +70 -0
- package/node_modules/parse5/dist/cjs/index.d.ts +71 -0
- package/node_modules/parse5/dist/cjs/index.js +54 -0
- package/node_modules/parse5/dist/cjs/package.json +1 -0
- package/node_modules/parse5/dist/cjs/parser/formatting-element-list.d.ts +36 -0
- package/node_modules/parse5/dist/cjs/parser/formatting-element-list.js +114 -0
- package/node_modules/parse5/dist/cjs/parser/index.d.ts +221 -0
- package/node_modules/parse5/dist/cjs/parser/index.js +3240 -0
- package/node_modules/parse5/dist/cjs/parser/open-element-stack.d.ts +53 -0
- package/node_modules/parse5/dist/cjs/parser/open-element-stack.js +328 -0
- package/node_modules/parse5/dist/cjs/serializer/index.d.ts +60 -0
- package/node_modules/parse5/dist/cjs/serializer/index.js +172 -0
- package/node_modules/parse5/dist/cjs/tokenizer/index.d.ts +247 -0
- package/node_modules/parse5/dist/cjs/tokenizer/index.js +2714 -0
- package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.d.ts +36 -0
- package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.js +200 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/default.d.ts +84 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/default.js +176 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/interface.d.ts +255 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/interface.js +2 -0
- package/node_modules/parse5/dist/common/doctype.d.ts +4 -0
- package/node_modules/parse5/dist/common/doctype.js +114 -0
- package/node_modules/parse5/dist/common/error-codes.d.ts +67 -0
- package/node_modules/parse5/dist/common/error-codes.js +63 -0
- package/node_modules/parse5/dist/common/foreign-content.d.ts +9 -0
- package/node_modules/parse5/dist/common/foreign-content.js +228 -0
- package/node_modules/parse5/dist/common/html.d.ts +289 -0
- package/node_modules/parse5/dist/common/html.js +523 -0
- package/node_modules/parse5/dist/common/token.d.ts +84 -0
- package/node_modules/parse5/dist/common/token.js +20 -0
- package/node_modules/parse5/dist/common/unicode.d.ts +42 -0
- package/node_modules/parse5/dist/common/unicode.js +62 -0
- package/node_modules/parse5/dist/index.d.ts +71 -0
- package/node_modules/parse5/dist/index.js +42 -0
- package/node_modules/parse5/dist/parser/formatting-element-list.d.ts +36 -0
- package/node_modules/parse5/dist/parser/formatting-element-list.js +110 -0
- package/node_modules/parse5/dist/parser/index.d.ts +221 -0
- package/node_modules/parse5/dist/parser/index.js +3245 -0
- package/node_modules/parse5/dist/parser/open-element-stack.d.ts +53 -0
- package/node_modules/parse5/dist/parser/open-element-stack.js +324 -0
- package/node_modules/parse5/dist/serializer/index.d.ts +60 -0
- package/node_modules/parse5/dist/serializer/index.js +168 -0
- package/node_modules/parse5/dist/tokenizer/index.d.ts +247 -0
- package/node_modules/parse5/dist/tokenizer/index.js +2710 -0
- package/node_modules/parse5/dist/tokenizer/preprocessor.d.ts +36 -0
- package/node_modules/parse5/dist/tokenizer/preprocessor.js +196 -0
- package/node_modules/parse5/dist/tree-adapters/default.d.ts +84 -0
- package/node_modules/parse5/dist/tree-adapters/default.js +173 -0
- package/node_modules/parse5/dist/tree-adapters/interface.d.ts +255 -0
- package/node_modules/parse5/dist/tree-adapters/interface.js +1 -0
- package/node_modules/parse5/package.json +50 -0
- package/node_modules/undici-types/LICENSE +21 -0
- package/node_modules/undici-types/README.md +6 -0
- package/node_modules/undici-types/agent.d.ts +31 -0
- package/node_modules/undici-types/api.d.ts +43 -0
- package/node_modules/undici-types/balanced-pool.d.ts +29 -0
- package/node_modules/undici-types/cache.d.ts +36 -0
- package/node_modules/undici-types/client.d.ts +108 -0
- package/node_modules/undici-types/connector.d.ts +34 -0
- package/node_modules/undici-types/content-type.d.ts +21 -0
- package/node_modules/undici-types/cookies.d.ts +28 -0
- package/node_modules/undici-types/diagnostics-channel.d.ts +66 -0
- package/node_modules/undici-types/dispatcher.d.ts +256 -0
- package/node_modules/undici-types/env-http-proxy-agent.d.ts +21 -0
- package/node_modules/undici-types/errors.d.ts +149 -0
- package/node_modules/undici-types/eventsource.d.ts +61 -0
- package/node_modules/undici-types/fetch.d.ts +209 -0
- package/node_modules/undici-types/file.d.ts +39 -0
- package/node_modules/undici-types/filereader.d.ts +54 -0
- package/node_modules/undici-types/formdata.d.ts +108 -0
- package/node_modules/undici-types/global-dispatcher.d.ts +9 -0
- package/node_modules/undici-types/global-origin.d.ts +7 -0
- package/node_modules/undici-types/handlers.d.ts +15 -0
- package/node_modules/undici-types/header.d.ts +4 -0
- package/node_modules/undici-types/index.d.ts +71 -0
- package/node_modules/undici-types/interceptors.d.ts +17 -0
- package/node_modules/undici-types/mock-agent.d.ts +50 -0
- package/node_modules/undici-types/mock-client.d.ts +25 -0
- package/node_modules/undici-types/mock-errors.d.ts +12 -0
- package/node_modules/undici-types/mock-interceptor.d.ts +93 -0
- package/node_modules/undici-types/mock-pool.d.ts +25 -0
- package/node_modules/undici-types/package.json +55 -0
- package/node_modules/undici-types/patch.d.ts +33 -0
- package/node_modules/undici-types/pool-stats.d.ts +19 -0
- package/node_modules/undici-types/pool.d.ts +39 -0
- package/node_modules/undici-types/proxy-agent.d.ts +28 -0
- package/node_modules/undici-types/readable.d.ts +65 -0
- package/node_modules/undici-types/retry-agent.d.ts +8 -0
- package/node_modules/undici-types/retry-handler.d.ts +116 -0
- package/node_modules/undici-types/util.d.ts +18 -0
- package/node_modules/undici-types/webidl.d.ts +228 -0
- package/node_modules/undici-types/websocket.d.ts +150 -0
- package/package.json +80 -0
- package/scripts/rebuild-forme.mjs +61 -0
- package/src/app/AppearanceControl.tsx +44 -0
- package/src/app/AssetThemeDefaults.tsx +87 -0
- package/src/app/AssetsBrowser.tsx +273 -0
- package/src/app/CommentDock.tsx +108 -0
- package/src/app/CreateDocumentDialog.tsx +51 -0
- package/src/app/DocumentActions.tsx +69 -0
- package/src/app/DocumentCard.tsx +50 -0
- package/src/app/DocumentViewControl.tsx +31 -0
- package/src/app/DocumentsBrowser.tsx +70 -0
- package/src/app/ExportHistoryDialog.tsx +86 -0
- package/src/app/ExportMenu.tsx +127 -0
- package/src/app/GuideDialog.tsx +80 -0
- package/src/app/InspectionLayer.tsx +77 -0
- package/src/app/LogoUploadDialog.tsx +92 -0
- package/src/app/Markdown.tsx +34 -0
- package/src/app/MaterialsBrowser.tsx +149 -0
- package/src/app/PageNumberInput.tsx +56 -0
- package/src/app/Pdf.tsx +561 -0
- package/src/app/ProjectDialogs.tsx +100 -0
- package/src/app/Reader.tsx +769 -0
- package/src/app/SearchField.tsx +13 -0
- package/src/app/Sidebar.tsx +86 -0
- package/src/app/SkillIndex.tsx +30 -0
- package/src/app/TemplatesBrowser.tsx +149 -0
- package/src/app/ThemesBrowser.tsx +159 -0
- package/src/app/api.ts +47 -0
- package/src/app/appearance.ts +35 -0
- package/src/app/assets.css +139 -0
- package/src/app/catalogPreview.ts +20 -0
- package/src/app/colors.css +167 -0
- package/src/app/comment-dock.css +53 -0
- package/src/app/commentDrafts.ts +67 -0
- package/src/app/componentCorrection.ts +17 -0
- package/src/app/edit-workbench.css +87 -0
- package/src/app/editSession.ts +238 -0
- package/src/app/editorRecovery.ts +25 -0
- package/src/app/export-history.css +31 -0
- package/src/app/export.css +17 -0
- package/src/app/guideLinks.ts +21 -0
- package/src/app/guides.css +40 -0
- package/src/app/main.tsx +221 -0
- package/src/app/materials.css +53 -0
- package/src/app/pdfLoading.ts +12 -0
- package/src/app/pdfSelection.ts +112 -0
- package/src/app/projects.css +63 -0
- package/src/app/reader-toolbar.css +65 -0
- package/src/app/selection.css +150 -0
- package/src/app/sidebar.css +60 -0
- package/src/app/skills.css +7 -0
- package/src/app/style.css +1061 -0
- package/src/app/templates.css +49 -0
- package/src/app/themes.css +80 -0
- package/src/app/ui/Icon.tsx +92 -0
- package/src/app/ui/README.md +27 -0
- package/src/app/ui/fonts.css +36 -0
- package/src/app/ui/index.tsx +223 -0
- package/src/app/ui/ui.css +388 -0
- package/src/app/useReaderPreview.ts +19 -0
- package/src/app/useTextEditing.ts +155 -0
- package/src/assets/adapter.ts +122 -0
- package/src/assets/files.ts +378 -0
- package/src/assets/import-worker.ts +294 -0
- package/src/assets/imports.ts +124 -0
- package/src/assets/index.ts +60 -0
- package/src/assets/store.ts +798 -0
- package/src/assets/usage.ts +118 -0
- package/src/cli/check.ts +25 -0
- package/src/cli/init.ts +119 -0
- package/src/cli/lock.ts +34 -0
- package/src/cli/main.ts +118 -0
- package/src/cli/process.ts +19 -0
- package/src/cli/start.ts +96 -0
- package/src/cli/update.ts +348 -0
- package/src/cli/workspace.ts +94 -0
- package/src/document/index.tsx +641 -0
- package/src/document/page.tsx +53 -0
- package/src/document/text-targets.tsx +162 -0
- package/src/media/files.ts +124 -0
- package/src/media/render.ts +63 -0
- package/src/rendering/resolve-sources.ts +84 -0
- package/src/runtime/jsx-dev-runtime.ts +2 -0
- package/src/runtime/jsx-runtime.ts +2 -0
- package/src/runtime/paths.ts +12 -0
- package/src/server/assets-cli.ts +162 -0
- package/src/server/assets-http.ts +100 -0
- package/src/server/client.ts +50 -0
- package/src/server/clipboard.ts +22 -0
- package/src/server/comments-cli.ts +64 -0
- package/src/server/comments.ts +130 -0
- package/src/server/create-cli.ts +33 -0
- package/src/server/create.ts +228 -0
- package/src/server/dependencies.ts +91 -0
- package/src/server/documents.ts +143 -0
- package/src/server/edits.ts +249 -0
- package/src/server/export-batch.ts +105 -0
- package/src/server/export-errors.ts +2 -0
- package/src/server/export-file.ts +57 -0
- package/src/server/export-inputs.ts +66 -0
- package/src/server/export-preview.ts +69 -0
- package/src/server/export.ts +32 -0
- package/src/server/exports.ts +283 -0
- package/src/server/files.ts +21 -0
- package/src/server/guides.ts +71 -0
- package/src/server/index.ts +432 -0
- package/src/server/materials.ts +39 -0
- package/src/server/media-cli.ts +73 -0
- package/src/server/media-mutations.ts +168 -0
- package/src/server/pptx.ts +160 -0
- package/src/server/preflight.ts +129 -0
- package/src/server/projects-cli.ts +29 -0
- package/src/server/projects.ts +187 -0
- package/src/server/render-error.ts +9 -0
- package/src/server/render-source.ts +24 -0
- package/src/server/render.ts +48 -0
- package/src/server/review-cli.ts +40 -0
- package/src/server/review.ts +161 -0
- package/src/server/selection.ts +23 -0
- package/src/server/source-overrides.ts +97 -0
- package/src/server/templates-cli.ts +51 -0
- package/src/server/templates.ts +186 -0
- package/src/server/text-layout.ts +41 -0
- package/src/server/text-source.ts +307 -0
- package/src/server/themes-cli.ts +59 -0
- package/src/server/themes.ts +215 -0
- package/src/server/ttf2eot.d.ts +3 -0
- package/src/server/worker.ts +166 -0
- package/src/server/workspace.ts +242 -0
- package/src/shared/anchors.ts +69 -0
- package/src/shared/assets.ts +154 -0
- package/src/shared/export.ts +34 -0
- package/src/shared/media.ts +33 -0
- package/src/shared/projects.ts +19 -0
- package/src/shared/selection.ts +94 -0
- package/src/shared/skill-index.ts +14 -0
- package/src/shared/starters.ts +19 -0
- package/src/shared/templates.ts +18 -0
- package/src/shared/themes.ts +24 -0
- package/src/shared/types.ts +39 -0
- package/src/template/index.ts +27 -0
- package/src/themes/index.ts +3 -0
- package/src/themes/neutral.ts +20 -0
- package/src/themes/types.ts +110 -0
- package/starter/assets/brand/wordmark.png +0 -0
- package/starter/assets/fonts/InterUI-LICENSE.txt +93 -0
- package/starter/assets/fonts/InterUI-Medium.ttf +0 -0
- package/starter/assets/fonts/InterUI-Regular.ttf +0 -0
- package/starter/assets/fonts/InterUI-source.json +19 -0
- package/starter/assets/fonts/OpenDocMono-Regular.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-Italic.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-Regular.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-Semibold.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-SemiboldItalic.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-Italic.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-Regular.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-Semibold.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-SemiboldItalic.ttf +0 -0
- package/starter/assets/fonts/SourceCode-LICENSE.md +93 -0
- package/starter/assets/fonts/SourceSans-LICENSE.md +93 -0
- package/starter/assets/fonts/SourceSerif-LICENSE.md +93 -0
- package/starter/assets/fonts/geist/OFL.txt +93 -0
- package/starter/assets/fonts/geist/asset.json +7 -0
- package/starter/assets/fonts/geist/files/1a9874b3be0fc168692a3d2327bccb4d28835653d3b91537a755296a467a83e3.ttf +0 -0
- package/starter/assets/fonts/geist/files/a8eefb873ba9c9020665f8a98302697ce1f3b79ab2deef6ee508c0ca6a82e876.ttf +0 -0
- package/starter/assets/fonts/geist/files/ccce59465ae5c61930ada5453834f60500fbd95084d85db63e0e65fad0125455.ttf +0 -0
- package/starter/assets/fonts/geist/files/f5e95110d70593672515080bee9148463ada0a7f77b89ed65a3d43cb2b0ff83a.pdf +0 -0
- package/starter/assets/fonts/geist/revisions/9a2bc12fb2f23cb27bc227087e63e1407bb804ee0586480bd6b7966ec69fb474.json +60 -0
- package/starter/assets/fonts/inter/OFL.txt +93 -0
- package/starter/assets/fonts/inter/asset.json +7 -0
- package/starter/assets/fonts/inter/files/1b08e7fc267a5c7e1d614100f604b83e7e8a0be241f0f288faa2b3ac93a683ba.ttf +0 -0
- package/starter/assets/fonts/inter/files/5b6f0c6f26e5c554a64cdcc3a9b5d802b7f9aec6206f1dbcfcdcad7b5860a2a9.ttf +0 -0
- package/starter/assets/fonts/inter/files/957db8560d510a198a7d0333fae7b6b444b00c20801581126273978d778eb3c3.pdf +0 -0
- package/starter/assets/fonts/inter/files/b37284b5701b6b168dfc770aa1a4ac492106422fd3ba76bc7641e37434e8019c.ttf +0 -0
- package/starter/assets/fonts/inter/files/c1811d32ac0f6eed1bbf57529f2ecdfc6c717d48a969dd864942436315a1b198.ttf +0 -0
- package/starter/assets/fonts/inter/files/e7a1aaf7eda9f2fad4131725fa556265ec75ca7b2d756260173a040363e8d4f7.ttf +0 -0
- package/starter/assets/fonts/inter/files/ef8f755d933b9310804cc9152f1f18cb2ac460d6b05054ec913d889c9f11f79e.ttf +0 -0
- package/starter/assets/fonts/inter/revisions/600391517c413963b71e278a57c26c40366c81fa3939a6b9755f446206766d12.json +99 -0
- package/starter/assets/fonts/inter/source.json +57 -0
- package/starter/assets/fonts/lato/OFL.txt +93 -0
- package/starter/assets/fonts/lato/asset.json +7 -0
- package/starter/assets/fonts/lato/files/4a6b566dbb28adb473a8789ce5169306f42f0c8a070ac92bae93636f36348b0d.pdf +0 -0
- package/starter/assets/fonts/lato/files/5adeb6b334d8fb99ef053bc052b952773d544315e0e1d668a12c0ce8bd51375c.ttf +0 -0
- package/starter/assets/fonts/lato/files/62c1b7f0d2e74b45960154c3520efc337b553db0961bfdc950d5618334596cc8.ttf +0 -0
- package/starter/assets/fonts/lato/files/71b8b7decbe75a881ed267be539d402bd1e9420b799658aada4e0d1bd5af803c.ttf +0 -0
- package/starter/assets/fonts/lato/files/8a0aace75d33794eece4b28187bfc1df0bbd2888b5d8a56e01788c8d65d16be1.ttf +0 -0
- package/starter/assets/fonts/lato/files/d636e4683231f931eda222d588e944d082bfd3bdba02f928bee461c0f185b251.ttf +0 -0
- package/starter/assets/fonts/lato/files/e399c44efe1387100531d26c7e4800c5d12251b890d6654a3098c7c679cb1786.ttf +0 -0
- package/starter/assets/fonts/lato/revisions/49ccb93400a9d466fab7d9843b1ecf8916ec6d47a475dd79a597a22eb39616bc.json +99 -0
- package/starter/assets/fonts/lato/source.json +57 -0
- package/starter/assets/fonts/merriweather/OFL.txt +93 -0
- package/starter/assets/fonts/merriweather/asset.json +7 -0
- package/starter/assets/fonts/merriweather/files/1c54f91b910454251c4c2b7bd4e472e1abf265fba7ca3c0ef2eee2f41324099e.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/8bde8da2bb7f0265e27ba0481f70bb48d0f98a976c145f2f239c648ddd6532e0.pdf +0 -0
- package/starter/assets/fonts/merriweather/files/90b7db4460fcd1a5ca49575c2668a793f3cd6447664d312a068d690e1c01e6bc.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/afff81272b7653417bb6f8bef57add055b1f9fda36f27eba5f32b40752bd08da.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/e029d3b71e5bae3877c73f4f2b15af28db16593d49b0aed2a328d37ff7075846.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/e9864a6790bf712a04e20f3662b206a1535186ed3e877fd859dd5fb9682335df.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/fa71baebdd20a7d0de2e5e445a5922530fe9e1d740efbe791f113b682d3cb093.ttf +0 -0
- package/starter/assets/fonts/merriweather/revisions/1888e390b3e4f38a3d7cd2dc1bb805aeb6ce13f986a97656f0265fd436bc91d2.json +99 -0
- package/starter/assets/fonts/merriweather/source.json +57 -0
- package/starter/assets/fonts/open-sans/OFL.txt +92 -0
- package/starter/assets/fonts/open-sans/asset.json +7 -0
- package/starter/assets/fonts/open-sans/files/1bc0594a83762b2c25d38915a34464b7fec6088298ca22d151757bf98d6700ec.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/47ed1cfaa7ffca04a04ab850b2938fd52c09d1b44cfa3e2980878e166b0cbd87.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/574939af301f07df8e21cfff279465c5981dd9d9cf62086f7515897df951c6f5.pdf +0 -0
- package/starter/assets/fonts/open-sans/files/6d3884d0d57c1b67e9c50c54eca7b69c535c114e76bd7a9cfda0258588185553.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/733eb93b167e6d45de09aa768f6c0355647c2c26f5416dbc7407a08ed41e81c6.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/75367e6da7d914eaed87883ba51b2a2b5816b5cdbb39f96ec5c81a5b032bfd5a.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/ff4fdc11204e0edd14e9a0bb6c374b847a9093b0ec2c16702e03afca79ac4ef7.ttf +0 -0
- package/starter/assets/fonts/open-sans/revisions/bbbe3a4915b9bccbc883c0decb4097511c43b6bd09ae22a1516aff128c219bc5.json +99 -0
- package/starter/assets/fonts/open-sans/source.json +57 -0
- package/starter/assets/fonts/roboto/OFL.txt +93 -0
- package/starter/assets/fonts/roboto/asset.json +7 -0
- package/starter/assets/fonts/roboto/files/22d45d989248a624252b8382067ac56550212fa675dcdbaf12f03d297dd87a58.pdf +0 -0
- package/starter/assets/fonts/roboto/files/35757eaa996b3359022f47f164a67ee9eac04971af24c5b8fbd4b89e844ff190.ttf +0 -0
- package/starter/assets/fonts/roboto/files/4d3035883c531846bd1ce2dc89f36d932e72dc114f56062c7e3a9cdd74f3d3ea.ttf +0 -0
- package/starter/assets/fonts/roboto/files/be7639306a4fc4a02ce2ae2ff59eb1335e4db4a7379dd0a384ed7cc053817789.ttf +0 -0
- package/starter/assets/fonts/roboto/files/d2920cbb1b60a3fd11fbf22049286e43a6baf522d37fdf1e7c89562319bcfea5.ttf +0 -0
- package/starter/assets/fonts/roboto/files/dece7c71bbe61710787f0839c722c65e87355dd2eb4a823e6b5488121ff81e4b.ttf +0 -0
- package/starter/assets/fonts/roboto/files/f478ba88b0292e685e487901dfbb1401457d32d6ebee4030cdfd5698235bffa8.ttf +0 -0
- package/starter/assets/fonts/roboto/revisions/bda5e2d84c17313373dd2dbf3e64fe0dd450c7e1b59e6929e69557e122fe976e.json +99 -0
- package/starter/assets/fonts/roboto/source.json +57 -0
- package/starter/assets/logos/opendoc/asset.json +6 -0
- package/starter/assets/logos/opendoc/files/831d5ccd9eb6709cc8439ea257c03d81452e81a28a3d1eedbd6a3b7daff687b6.png +0 -0
- package/starter/assets/logos/opendoc/revisions/834dde8926ddb81de687254195a168bb13bfb77803307f1257de1f2228be63b2.json +33 -0
- package/starter/assets/ui-fonts/geist/OFL.txt +93 -0
- package/starter/assets/ui-fonts/geist/geist-latin-ext-wght-italic.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/geist-latin-ext-wght-normal.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/geist-latin-wght-italic.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/geist-latin-wght-normal.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/source.json +26 -0
- package/starter/documents/welcome/assets.json +7 -0
- package/starter/documents/welcome/index.tsx +160 -0
- package/starter/documents/welcome/media/.gitkeep +0 -0
- package/starter/documents/welcome/media/paper-architecture/image.png +0 -0
- package/starter/documents/welcome/media/paper-architecture/meta.json +9 -0
- package/starter/documents/welcome/media/paper-architecture/prompt.txt +1 -0
- package/starter/documents/welcome/media/studio-rhythm/chart.svg +2343 -0
- package/starter/documents/welcome/media/studio-rhythm/data.json +234 -0
- package/starter/documents/welcome/media/studio-rhythm/generation.json +9 -0
- package/starter/documents/welcome/media/studio-rhythm/image.png +0 -0
- package/starter/documents/welcome/media/studio-rhythm/meta.json +11 -0
- package/starter/documents/welcome/media/studio-rhythm/recipe.py +79 -0
- package/starter/documents/welcome/theme.tsx +5 -0
- package/starter/documents/welcome-presentation/assets.json +7 -0
- package/starter/documents/welcome-presentation/index.tsx +166 -0
- package/starter/documents/welcome-presentation/media/.gitkeep +0 -0
- package/starter/documents/welcome-presentation/media/paper-architecture/image.png +0 -0
- package/starter/documents/welcome-presentation/media/paper-architecture/meta.json +9 -0
- package/starter/documents/welcome-presentation/media/paper-architecture/prompt.txt +1 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/chart.svg +1336 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/data.json +234 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/generation.json +9 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/image.png +0 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/meta.json +13 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/recipe.py +49 -0
- package/starter/documents/welcome-presentation/theme.tsx +5 -0
- package/starter/projects.json +17 -0
- package/starter/templates/AGENTS.md +9 -0
- package/starter/templates/_shared/BusinessLogo.tsx +14 -0
- package/starter/templates/_shared/Pricing.tsx +40 -0
- package/starter/templates/_shared/commerce.ts +93 -0
- package/starter/templates/brand-guidelines/AGENTS.md +32 -0
- package/starter/templates/brand-guidelines/index.tsx +62 -0
- package/starter/templates/brand-guidelines/preview.tsx +181 -0
- package/starter/templates/brand-guidelines/starter.tsx +179 -0
- package/starter/templates/brand-guidelines/template.json +15 -0
- package/starter/templates/business-proposal/AGENTS.md +13 -0
- package/starter/templates/business-proposal/README.md +36 -0
- package/starter/templates/business-proposal/data.json +37 -0
- package/starter/templates/business-proposal/examples/long.json +142 -0
- package/starter/templates/business-proposal/examples/sparse.json +17 -0
- package/starter/templates/business-proposal/examples/typical.json +37 -0
- package/starter/templates/business-proposal/index.tsx +59 -0
- package/starter/templates/business-proposal/preview.tsx +47 -0
- package/starter/templates/business-proposal/schema.ts +14 -0
- package/starter/templates/business-proposal/starter.tsx +18 -0
- package/starter/templates/business-proposal/template.json +11 -0
- package/starter/templates/company-profile/AGENTS.md +48 -0
- package/starter/templates/company-profile/index.tsx +69 -0
- package/starter/templates/company-profile/preview.tsx +185 -0
- package/starter/templates/company-profile/starter.tsx +186 -0
- package/starter/templates/company-profile/template.json +15 -0
- package/starter/templates/consulting-report/AGENTS.md +11 -0
- package/starter/templates/consulting-report/README.md +13 -0
- package/starter/templates/consulting-report/RESEARCH.md +10 -0
- package/starter/templates/consulting-report/index.tsx +44 -0
- package/starter/templates/consulting-report/preview.tsx +39 -0
- package/starter/templates/consulting-report/starter.tsx +15 -0
- package/starter/templates/consulting-report/template.json +11 -0
- package/starter/templates/editorial-essay/AGENTS.md +11 -0
- package/starter/templates/editorial-essay/README.md +11 -0
- package/starter/templates/editorial-essay/index.tsx +30 -0
- package/starter/templates/editorial-essay/preview.tsx +26 -0
- package/starter/templates/editorial-essay/starter.tsx +15 -0
- package/starter/templates/editorial-essay/template.json +11 -0
- package/starter/templates/executive-brief/AGENTS.md +9 -0
- package/starter/templates/executive-brief/README.md +11 -0
- package/starter/templates/executive-brief/index.tsx +33 -0
- package/starter/templates/executive-brief/preview.tsx +37 -0
- package/starter/templates/executive-brief/starter.tsx +11 -0
- package/starter/templates/executive-brief/template.json +11 -0
- package/starter/templates/image-story/AGENTS.md +37 -0
- package/starter/templates/image-story/index.tsx +106 -0
- package/starter/templates/image-story/preview.tsx +33 -0
- package/starter/templates/image-story/starter.tsx +24 -0
- package/starter/templates/image-story/template.json +13 -0
- package/starter/templates/invoice/AGENTS.md +13 -0
- package/starter/templates/invoice/README.md +40 -0
- package/starter/templates/invoice/data.json +61 -0
- package/starter/templates/invoice/examples/long.json +241 -0
- package/starter/templates/invoice/examples/sparse.json +33 -0
- package/starter/templates/invoice/examples/typical.json +61 -0
- package/starter/templates/invoice/index.tsx +57 -0
- package/starter/templates/invoice/preview.tsx +12 -0
- package/starter/templates/invoice/schema.ts +45 -0
- package/starter/templates/invoice/starter.tsx +12 -0
- package/starter/templates/invoice/template.json +11 -0
- package/starter/templates/literary-text/AGENTS.md +9 -0
- package/starter/templates/literary-text/README.md +11 -0
- package/starter/templates/literary-text/index.tsx +31 -0
- package/starter/templates/literary-text/preview.tsx +20 -0
- package/starter/templates/literary-text/starter.tsx +11 -0
- package/starter/templates/literary-text/template.json +11 -0
- package/starter/templates/magazine-feature/AGENTS.md +11 -0
- package/starter/templates/magazine-feature/README.md +13 -0
- package/starter/templates/magazine-feature/index.tsx +41 -0
- package/starter/templates/magazine-feature/preview.tsx +34 -0
- package/starter/templates/magazine-feature/starter.tsx +15 -0
- package/starter/templates/magazine-feature/template.json +11 -0
- package/starter/templates/monthly-report/AGENTS.md +11 -0
- package/starter/templates/monthly-report/README.md +24 -0
- package/starter/templates/monthly-report/data.json +131 -0
- package/starter/templates/monthly-report/examples/long.json +519 -0
- package/starter/templates/monthly-report/examples/sparse.json +20 -0
- package/starter/templates/monthly-report/examples/typical.json +37 -0
- package/starter/templates/monthly-report/index.tsx +92 -0
- package/starter/templates/monthly-report/preview.tsx +14 -0
- package/starter/templates/monthly-report/schema.ts +127 -0
- package/starter/templates/monthly-report/starter.tsx +13 -0
- package/starter/templates/monthly-report/template.json +11 -0
- package/starter/templates/pitch-deck/AGENTS.md +32 -0
- package/starter/templates/pitch-deck/index.tsx +46 -0
- package/starter/templates/pitch-deck/preview.tsx +142 -0
- package/starter/templates/pitch-deck/starter.tsx +140 -0
- package/starter/templates/pitch-deck/template.json +15 -0
- package/starter/templates/proposal-deck/AGENTS.md +25 -0
- package/starter/templates/proposal-deck/index.tsx +52 -0
- package/starter/templates/proposal-deck/preview.tsx +172 -0
- package/starter/templates/proposal-deck/starter.tsx +168 -0
- package/starter/templates/proposal-deck/template.json +7 -0
- package/starter/templates/quotation/AGENTS.md +13 -0
- package/starter/templates/quotation/README.md +42 -0
- package/starter/templates/quotation/data.json +64 -0
- package/starter/templates/quotation/examples/long.json +272 -0
- package/starter/templates/quotation/examples/sparse.json +31 -0
- package/starter/templates/quotation/examples/typical.json +64 -0
- package/starter/templates/quotation/index.tsx +51 -0
- package/starter/templates/quotation/preview.tsx +12 -0
- package/starter/templates/quotation/schema.ts +27 -0
- package/starter/templates/quotation/starter.tsx +12 -0
- package/starter/templates/quotation/template.json +11 -0
- package/starter/templates/scientific-paper/AGENTS.md +11 -0
- package/starter/templates/scientific-paper/README.md +13 -0
- package/starter/templates/scientific-paper/index.tsx +47 -0
- package/starter/templates/scientific-paper/preview.tsx +43 -0
- package/starter/templates/scientific-paper/starter.tsx +15 -0
- package/starter/templates/scientific-paper/template.json +11 -0
- package/starter/themes/Specimen.tsx +54 -0
- package/starter/themes/civic-spectrum/components.tsx +92 -0
- package/starter/themes/civic-spectrum/design.md +70 -0
- package/starter/themes/civic-spectrum/index.ts +57 -0
- package/starter/themes/civic-spectrum/preview.tsx +66 -0
- package/starter/themes/field-manual/components.tsx +106 -0
- package/starter/themes/field-manual/design.md +72 -0
- package/starter/themes/field-manual/index.ts +57 -0
- package/starter/themes/field-manual/preview.tsx +82 -0
- package/starter/themes/index.ts +3 -0
- package/starter/themes/mckinsey-consulting/components.tsx +69 -0
- package/starter/themes/mckinsey-consulting/design.md +68 -0
- package/starter/themes/mckinsey-consulting/index.ts +60 -0
- package/starter/themes/mckinsey-consulting/preview.tsx +53 -0
- package/starter/themes/neutral/design.md +35 -0
- package/starter/themes/neutral/index.ts +21 -0
- package/starter/themes/neutral/preview.tsx +4 -0
- package/starter/themes/opendoc-neutral/components.tsx +77 -0
- package/starter/themes/opendoc-neutral/design.md +70 -0
- package/starter/themes/opendoc-neutral/index.ts +54 -0
- package/starter/themes/opendoc-neutral/preview.tsx +43 -0
- package/starter/themes/types.ts +3 -0
- package/tsconfig.workspace.json +24 -0
- package/vendor/formepdf/LICENSE +21 -0
- package/vendor/formepdf/README.md +97 -0
- package/vendor/formepdf/font-subset.patch +228 -0
- package/vendor/formepdf/text-writer.patch +507 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import * as F from '@formepdf/react';
|
|
3
|
+
import { TextSlot, Document, Heading, Paragraph, Prose, References, Page } from 'opendoc';
|
|
4
|
+
import { themePage, type DocTheme } from 'opendoc/themes';
|
|
5
|
+
|
|
6
|
+
export interface EditorialEssayProps {
|
|
7
|
+
title: string;
|
|
8
|
+
theme: DocTheme;
|
|
9
|
+
author?: string;
|
|
10
|
+
standfirst?: ReactNode;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
references?: Parameters<typeof Document>[0]['references'];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Page architecture only. Content remains ordinary, freely ordered PDF blocks. */
|
|
16
|
+
export function EditorialEssay({ title, theme, author, standfirst, children, references }: EditorialEssayProps) {
|
|
17
|
+
const layoutTheme: DocTheme = theme.design ? theme : { ...theme, fontSize: 11, lineHeight: 1.42, paragraphGap: 0 };
|
|
18
|
+
return <Document title={title} author={author} theme={layoutTheme} references={references}>
|
|
19
|
+
<Page {...themePage(theme, { top: 66, bottom: 62, left: 105, right: 105 })}>
|
|
20
|
+
{(!theme.design || theme.runningFooter) && <F.Fixed position="footer"><F.Text style={{ fontFamily: theme.body, fontSize: 8, color: theme.muted, textAlign: 'right', ...theme.design?.furniture?.text, ...theme.design?.furniture?.footer }}>{theme.design?.furniture?.pageNumber === 'total' ? '{{pageNumber}} / {{totalPages}}' : '{{pageNumber}}'}</F.Text></F.Fixed>}
|
|
21
|
+
<F.View style={theme.design?.title?.block}>
|
|
22
|
+
<Heading id="essay-title" level={1} baseStyle={{ fontSize: 36, lineHeight: 1.12, marginBottom: 12 }} style={theme.design?.title?.heading}><TextSlot slot="title" from="title">{title}</TextSlot></Heading>
|
|
23
|
+
{author && <Paragraph id="essay-byline" role="small" baseStyle={{ fontSize: 8.5, letterSpacing: 0.25, color: theme.muted, marginBottom: 24 }} style={theme.design?.title?.byline}><TextSlot slot="author" from="author">{author}</TextSlot></Paragraph>}
|
|
24
|
+
{standfirst && <Paragraph id="essay-standfirst" role="lead" baseStyle={{ fontSize: 13, lineHeight: 1.45, color: theme.muted, marginBottom: 28 }} style={theme.design?.title?.subtitle}><TextSlot slot="standfirst" from="standfirst">{standfirst}</TextSlot></Paragraph>}
|
|
25
|
+
</F.View>
|
|
26
|
+
<Prose paragraphGap={theme.design ? theme.paragraphGap : 6}>{children}</Prose>
|
|
27
|
+
<References headingBaseStyle={{ fontSize: 10, marginTop: 26, marginBottom: 8 }} />
|
|
28
|
+
</Page>
|
|
29
|
+
</Document>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as F from '@formepdf/react';
|
|
2
|
+
import { Paragraph, Figure, Heading } from 'opendoc';
|
|
3
|
+
import { neutral } from '../../themes';
|
|
4
|
+
import { type DocTheme } from 'opendoc/themes';
|
|
5
|
+
import { EditorialEssay } from './index';
|
|
6
|
+
|
|
7
|
+
export const meta = { title: 'Editorial essay', description: 'A neutral layout specimen with placeholder content.', kind: 'article' as const, theme: 'neutral' };
|
|
8
|
+
const paragraph = 'This is placeholder text for the reading column. Its purpose is to make the page’s proportions visible: the length of a line, the space between paragraphs, and the quiet area around the text. The words carry no argument and describe no findings. In a finished essay, the author’s own material occupies this space and continues naturally from one page to the next.';
|
|
9
|
+
|
|
10
|
+
export function Specimen({ length = 'typical', theme = neutral }: { length?: 'sparse' | 'typical' | 'long'; theme?: DocTheme } = {}) {
|
|
11
|
+
const count = length === 'sparse' ? 1 : length === 'long' ? 28 : 5;
|
|
12
|
+
return <EditorialEssay title={meta.title} theme={theme} author="Author name · Layout specimen" standfirst="A standfirst sits between the title and the essay: a larger, quieter passage with space to breathe before the reading column begins.">
|
|
13
|
+
{Array.from({ length: count }, (_, index) => <Paragraph key={index} id={`specimen-paragraph-${index + 1}`}>{paragraph}</Paragraph>)}
|
|
14
|
+
{length !== 'sparse' && <>
|
|
15
|
+
<Figure id="specimen-visual" caption="An optional visual spans the reading column. Placeholder only.">
|
|
16
|
+
<F.View style={{ height: 130, backgroundColor: neutral.paper, borderWidth: 0.6, borderColor: neutral.line, justifyContent: 'center', alignItems: 'center' }}>
|
|
17
|
+
<F.Text style={{ fontSize: 10, color: neutral.muted }}>Full-width visual</F.Text>
|
|
18
|
+
</F.View>
|
|
19
|
+
</Figure>
|
|
20
|
+
<Paragraph id="specimen-closing">{paragraph}</Paragraph>
|
|
21
|
+
<Heading id="specimen-reference-heading" style={{ fontSize: 11, marginTop: 24 }}>References</Heading>
|
|
22
|
+
<Paragraph id="specimen-reference" style={{ fontSize: 9.5, color: neutral.muted }}>Reference placement specimen. Real references appear here only when cited; no source is being claimed.</Paragraph>
|
|
23
|
+
</>}
|
|
24
|
+
</EditorialEssay>;
|
|
25
|
+
}
|
|
26
|
+
export default Specimen;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { EditorialEssay } from '../../templates/editorial-essay';
|
|
2
|
+
import { Paragraph } from 'opendoc';
|
|
3
|
+
// @ts-ignore The selected local theme module is inserted when this starter becomes a document.
|
|
4
|
+
import { theme } from "__OPENDOC_THEME_MODULE__";
|
|
5
|
+
|
|
6
|
+
const title = "__OPENDOC_TITLE__";
|
|
7
|
+
const themeId = "__OPENDOC_THEME__";
|
|
8
|
+
export const meta = { title, description: 'An editorial essay, ready for your material.', kind: 'article' as const, theme: themeId };
|
|
9
|
+
export const provenance = { template: 'templates/editorial-essay/index.tsx' };
|
|
10
|
+
|
|
11
|
+
export default function Essay() {
|
|
12
|
+
return <EditorialEssay title={title} theme={theme} author="Author name" standfirst="Standfirst — replace this placeholder with your opening summary.">
|
|
13
|
+
<Paragraph id="essay-opening">Your essay begins here. This is placeholder text, ready to be replaced with your own material.</Paragraph>
|
|
14
|
+
</EditorialEssay>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Editorial essay",
|
|
3
|
+
"description": "A literary reading column with indented paragraphs, a considered opening, and quiet page furniture. For essays, opinion pieces, and long-form reflections.",
|
|
4
|
+
"format": "A4 · Single column",
|
|
5
|
+
"structure": [
|
|
6
|
+
"Title, byline, and standfirst share the opening page with the body.",
|
|
7
|
+
"A narrow column and close paragraph rhythm support sustained reading. Openings sit flush left; subsequent paragraphs begin with a first-line indent.",
|
|
8
|
+
"Occasional visuals span the full text width; references sit quietly at the end.",
|
|
9
|
+
"Discreet page numbers leave the page free of running headers and rules."
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Executive brief
|
|
2
|
+
|
|
3
|
+
Treat this as a soft foundation with room for variation and creativity. Its starting character is a compact opening, a visible takeaway, and a broad reading column with economical section spacing. It suggests a concise one- or two-page document; that is a useful aim, not a page limit or a mandated writing method.
|
|
4
|
+
|
|
5
|
+
Let content and reader guide the composition. A long title may benefit from smaller type through `titleStyle`, a prominent exhibit may need more space, or a short note may need no headings at all. The label, author, date, and takeaway are optional. Do not invent a recommendation, force a problem/solution outline, or add sections to match the specimen. Dates are supplied text; do not imply a review date that has not occurred.
|
|
6
|
+
|
|
7
|
+
Use ordinary OpenDoc blocks and native Forme flow. Keep titles and takeaways breakable; do not shrink content automatically, split lines by hand, or patch the renderer to force a page count. BriefHeading provides compact defaults. A native unbreakable View can keep a heading with a genuinely short lead; longer prose belongs outside that group. Use readable captions, units, and source notes for exhibits. Preserve stable IDs and evidence accuracy.
|
|
8
|
+
|
|
9
|
+
The caller's theme supplies visual hierarchy, rhythm, and component treatments. Keep variations for one document local, and preserve other templates and documents. Review the adapted PDF. Shared changes need sparse, typical, and long specimens, a second theme, long opening material, and a working starter. Catalog specimens use Neutral and identify illustrative material explicitly.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Executive brief
|
|
2
|
+
|
|
3
|
+
A flexible, compact layout for updates, briefings, and decision notes. Defaults are A4 portrait, 52-point side and 48-point top/bottom margins, a 491-point reading column, 11/15.4-point body type, and 8-point paragraph gaps. A 26-point title opens the same page as the body. The optional 14-point takeaway gives the opening emphasis. Page numbers sit at the bottom right.
|
|
4
|
+
|
|
5
|
+
`ExecutiveBrief` accepts `title`, `theme`, and ordinary OpenDoc blocks as `children`. Optional `label`, `author`, and `date` add small opening details; `date` is supplied display text. `takeaway` accepts inline text and formatting, with no mandatory label or content formula. `titleStyle` accepts native styles for a longer title or an adapted opening. Fonts and colors come from the theme. Optional verified `references` work with the existing Cite blocks and appear after the body.
|
|
6
|
+
|
|
7
|
+
`BriefHeading` accepts a stable `id`, `children`, and optional native `style`; its starting size is 12.5 points. Use a native `<F.View wrap={false}>` around a heading and a short lead when they need to stay together. Keep the rest in normal flow. Tables and figures use existing OpenDoc blocks with captions and accurate source notes.
|
|
8
|
+
|
|
9
|
+
One or two pages is an editorial aim, not an enforced limit. Titles, takeaways, and body prose remain breakable, and longer material can continue across pages. There is no custom layout engine, automatic fitting, or required section outline. Adapt the defaults to the content and review the result. See [AGENTS.md](AGENTS.md) for the intended freedom and functional boundaries.
|
|
10
|
+
|
|
11
|
+
`preview.tsx` supplies sparse, typical, and long specimens, with optional theme selection for review. The catalog uses Neutral; all sample values are explicitly synthetic. `starter.tsx` creates an ordinary linked document, with no extra data format or runtime.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import * as F from '@formepdf/react';
|
|
3
|
+
import { TextSlot, Document, Heading, Paragraph, References, Page } from 'opendoc';
|
|
4
|
+
import { themePage, type DocTheme } from 'opendoc/themes';
|
|
5
|
+
|
|
6
|
+
export function ExecutiveBrief({ title, theme, author, date, label, takeaway, titleStyle, children, references }: {
|
|
7
|
+
title: string; theme: DocTheme; author?: string; date?: string; label?: string;
|
|
8
|
+
takeaway?: ReactNode; titleStyle?: F.Style; children: ReactNode;
|
|
9
|
+
references?: Parameters<typeof Document>[0]['references'];
|
|
10
|
+
}) {
|
|
11
|
+
const layoutTheme: DocTheme = theme.design ? theme : { ...theme, fontSize: 11, lineHeight: 1.4, paragraphGap: 8 };
|
|
12
|
+
const details = author || date;
|
|
13
|
+
return <Document title={title} author={author} theme={layoutTheme} references={references}>
|
|
14
|
+
<Page {...themePage(theme, { top: 48, bottom: 48, left: 52, right: 52 })} style={{ lineBreaking: 'greedy', ...theme.design?.page?.style }}>
|
|
15
|
+
{(!theme.design || theme.runningFooter) && <F.Fixed position="footer"><F.Text style={{ fontFamily: theme.body, fontSize: 8, color: theme.muted, textAlign: 'right', ...theme.design?.furniture?.text, ...theme.design?.furniture?.footer }}>{theme.design?.furniture?.pageNumber === 'total' ? '{{pageNumber}} / {{totalPages}}' : '{{pageNumber}}'}</F.Text></F.Fixed>}
|
|
16
|
+
<F.View style={theme.design?.title?.block}>
|
|
17
|
+
{label && <Paragraph id="brief-label" role="label" baseStyle={{ fontSize: 8.5, color: theme.muted, letterSpacing: 0.6, marginBottom: 8 }} style={theme.design?.title?.eyebrow}>{theme.design?.title?.uppercaseEyebrow ? label.toUpperCase() : <TextSlot slot="label" from="label">{label}</TextSlot>}</Paragraph>}
|
|
18
|
+
<Heading id="brief-title" level={1} baseStyle={{ fontSize: 26, lineHeight: 1.12, marginBottom: 10 }} style={{ ...theme.design?.title?.heading, ...titleStyle }}><TextSlot slot="title" from="title">{title}</TextSlot></Heading>
|
|
19
|
+
{details && <Paragraph id="brief-details" role="small" baseStyle={{ fontSize: 9, color: theme.muted, marginBottom: 10 }} style={theme.design?.title?.byline}>{author && <TextSlot slot="author" from="author">{author}</TextSlot>}{author && date ? ' · ' : ''}{date && <TextSlot slot="date" from="date">{date}</TextSlot>}</Paragraph>}
|
|
20
|
+
{takeaway && <Paragraph id="brief-takeaway" role="lead" baseStyle={{ fontSize: 14, fontWeight: 600, lineHeight: 1.35, marginTop: 8, marginBottom: 16 }} style={theme.design?.title?.subtitle}><TextSlot slot="takeaway" from="takeaway">{takeaway}</TextSlot></Paragraph>}
|
|
21
|
+
</F.View>
|
|
22
|
+
<F.View style={{ marginTop: takeaway ? 0 : 10 }}>
|
|
23
|
+
{children}
|
|
24
|
+
<References headingBaseStyle={{ fontSize: 12.5, marginTop: 16, marginBottom: 6 }} />
|
|
25
|
+
</F.View>
|
|
26
|
+
</Page>
|
|
27
|
+
</Document>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Compact section hierarchy with ordinary native styles available to the author. */
|
|
31
|
+
export function BriefHeading({ id, style, children }: { id: string; style?: F.Style; children: ReactNode }) {
|
|
32
|
+
return <Heading id={id} level={2} baseStyle={{ fontSize: 12.5, marginTop: 12, marginBottom: 6 }} style={style}><TextSlot slot="children" from="children">{children}</TextSlot></Heading>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as F from '@formepdf/react';
|
|
2
|
+
import { DataTable, Figure, Paragraph } from 'opendoc';
|
|
3
|
+
import { neutral } from '../../themes';
|
|
4
|
+
import { type DocTheme } from 'opendoc/themes';
|
|
5
|
+
import { BriefHeading, ExecutiveBrief } from './index';
|
|
6
|
+
|
|
7
|
+
export const meta = { title: 'Executive brief', description: 'A Neutral brief specimen with illustrative placeholders only.', kind: 'report' as const, theme: 'neutral' };
|
|
8
|
+
const paragraph = 'This is placeholder prose for the brief. It demonstrates a compact reading rhythm and the relationship between a section heading, supporting detail, and a small exhibit. In an authored document, the reader’s needs and the available evidence determine what belongs here. No business result or recommendation is being claimed.';
|
|
9
|
+
|
|
10
|
+
export function Specimen({ length = 'typical', theme = neutral }: { length?: 'sparse' | 'typical' | 'long'; theme?: DocTheme } = {}) {
|
|
11
|
+
const sparse = length === 'sparse';
|
|
12
|
+
return <ExecutiveBrief title={meta.title} theme={theme}
|
|
13
|
+
author={sparse ? undefined : 'Author or team'} date={sparse ? undefined : 'Date placeholder'}
|
|
14
|
+
takeaway={sparse ? undefined : 'A short opening takeaway receives emphasis while the supporting detail remains easy to scan. This is a layout specimen, not a finding.'}>
|
|
15
|
+
<Paragraph id="specimen-opening">{paragraph}</Paragraph>
|
|
16
|
+
{!sparse && <>
|
|
17
|
+
<F.View wrap={false}>
|
|
18
|
+
<BriefHeading id="specimen-detail-heading">A compact section</BriefHeading>
|
|
19
|
+
<Paragraph id="specimen-detail-lead">A short lead stays with its heading. Section names and order belong to the writer; this specimen does not prescribe a briefing method.</Paragraph>
|
|
20
|
+
</F.View>
|
|
21
|
+
{length === 'long' && Array.from({ length: 9 }, (_, index) => <Paragraph key={index} id={`specimen-detail-${index + 1}`}>{paragraph}</Paragraph>)}
|
|
22
|
+
<DataTable id="specimen-table" caption="Synthetic values for layout review"
|
|
23
|
+
columns={[{ label: 'Item', width: 2 }, { label: 'Value (a.u.)', width: 1, align: 'right' }, { label: 'Status', width: 2 }]}
|
|
24
|
+
rows={Array.from({ length: length === 'long' ? 24 : 3 }, (_, index) => [`Example ${index + 1}`, 10 + index, 'Illustrative only'])}
|
|
25
|
+
sourceNote="All values are synthetic. a.u. means arbitrary units; no measured outcome is claimed." />
|
|
26
|
+
{length === 'long' && <Figure id="specimen-figure" caption="A small exhibit can follow the narrative in normal flow." sourceNote="Illustrative placeholder only; no data or source is claimed.">
|
|
27
|
+
<F.View style={{ height: 95, backgroundColor: theme.paper, borderWidth: 0.6, borderColor: theme.line, justifyContent: 'center', alignItems: 'center' }}><F.Text style={{ fontSize: 10, color: theme.muted }}>Figure area · Illustrative placeholder</F.Text></F.View>
|
|
28
|
+
</Figure>}
|
|
29
|
+
<F.View wrap={false}>
|
|
30
|
+
<BriefHeading id="specimen-closing-heading">A closing section</BriefHeading>
|
|
31
|
+
<Paragraph id="specimen-closing">This final passage shows the spacing after an exhibit. The actual brief may end here or continue with further material. Its length follows the content, without shrinking type to meet a page count.</Paragraph>
|
|
32
|
+
</F.View>
|
|
33
|
+
<Paragraph id="specimen-reference-note" style={{ fontSize: 9, color: theme.muted, marginTop: 10 }}>Reference placement specimen. Verified references appear after the body when cited; no source is being claimed here.</Paragraph>
|
|
34
|
+
</>}
|
|
35
|
+
</ExecutiveBrief>;
|
|
36
|
+
}
|
|
37
|
+
export default Specimen;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ExecutiveBrief } from '../../templates/executive-brief';
|
|
2
|
+
import { Paragraph } from 'opendoc';
|
|
3
|
+
// @ts-ignore The selected local theme module is inserted when this starter becomes a document.
|
|
4
|
+
import { theme } from "__OPENDOC_THEME_MODULE__";
|
|
5
|
+
const title = "__OPENDOC_TITLE__";
|
|
6
|
+
const themeId = "__OPENDOC_THEME__";
|
|
7
|
+
export const meta = { title, description: 'An executive brief, ready for your content.', kind: 'report' as const, theme: themeId };
|
|
8
|
+
export const provenance = { template: 'templates/executive-brief/index.tsx' };
|
|
9
|
+
export default function Brief() {
|
|
10
|
+
return <ExecutiveBrief title={title} theme={theme} takeaway="Replace this placeholder with a concise opening takeaway, or omit it when the brief does not need one."><Paragraph id="brief-opening">Your brief begins here. Add the prose, evidence, and exhibits your reader needs, in the order that makes the material clearest.</Paragraph></ExecutiveBrief>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Executive brief",
|
|
3
|
+
"description": "A compact title block, an optional prominent takeaway, and closely spaced sections with room for small exhibits. For concise updates, briefings, and decision notes.",
|
|
4
|
+
"format": "A4 · Compact brief",
|
|
5
|
+
"structure": [
|
|
6
|
+
"A compact, left-aligned title shares the opening page with the text. A label, author, and date are optional.",
|
|
7
|
+
"An optional opening takeaway uses larger, stronger type without requiring a particular argument or outline.",
|
|
8
|
+
"A broad single column and compact section headings make room for prose, a small table, or a figure in the author's chosen order.",
|
|
9
|
+
"References follow the text and page numbers sit quietly below. Aim for a concise document; longer material flows naturally without forced fitting."
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Image story
|
|
2
|
+
|
|
3
|
+
An adaptable layout skeleton for image-led documents. Every catalog image position is a replaceable placeholder; no actual artwork, brand identity, or subject matter belongs in this template. Themes supply the appearance and each document owns its content. Use one or two layouts when they help; the seven-page specimen is a menu, not an outline to reproduce. The catalog uses Neutral so the architecture is visible independently of branding.
|
|
4
|
+
|
|
5
|
+
## Start with the image's job
|
|
6
|
+
|
|
7
|
+
- `cover`: establish atmosphere with full bleed and a short title in quiet image space.
|
|
8
|
+
- `split-left`: give a portrait image half the page and concise prose a separate column.
|
|
9
|
+
- `split-top`: introduce a scene before the writing; often better for longer headlines.
|
|
10
|
+
- `panorama`: contrast a wide band with a square inset; explain the relationship in the nearby copy.
|
|
11
|
+
- `diptych`: align an unequal pair for comparison or two perspectives.
|
|
12
|
+
- `collage`: three pictures with unequal scale and one overlap, connected by short copy.
|
|
13
|
+
- `overlay`: full bleed with an opaque text panel when the artwork is busy.
|
|
14
|
+
|
|
15
|
+
The half-page split and panorama with inset are strong everyday defaults. Collages and overlays work best as occasional emphasis. White space, image scale, and changes of rhythm do more than adding a picture to every passage.
|
|
16
|
+
|
|
17
|
+
## Authoring contract
|
|
18
|
+
|
|
19
|
+
Create through `pnpm run create -- <id> --project <project> --template image-story --title "Title"`. Keep the generated theme adapter and asset bindings. `ImageStory` is the document root; `ImageStoryPage` accepts a stable `id`, the adapted `theme`, a `layout`, native `title` and optional `eyebrow`, `lead`, `children`, `caption`, and named image props (`image`, `secondary`, `detail`). Each image is `{item:'media-folder-id', fit:'cover', position:{x:0.5,y:0.5}}`; omit fit/position for centered cover. Named media must exist and pass freshness checks. An omitted image prop creates a visible starter placeholder, never a silent blank. `lead` inherits the composition's foreground, including white on image covers. If you add custom `children` over artwork, explicitly choose their foreground against that image too.
|
|
20
|
+
|
|
21
|
+
Import or generate actual images into the **instance's** `media/<id>/` folder and review them using [Media](../../docs/MEDIA.md). The template and its specimen contain no artwork or prompts; new documents begin with replaceable placeholders. Do not borrow other documents' filesystem paths or bake brand/subject matter into the skeleton.
|
|
22
|
+
|
|
23
|
+
Image pages are deliberately bounded. Keep their copy short. Adjust `titleStyle` (for example `{fontSize:30}`), change a layout, or make a local variation for a long headline. Put long prose in ordinary OpenDoc `Pages`; add image pages between those flowing sections. The bounded text regions fail preflight if copy clips rather than silently discarding it. Preserve the caller's body typography and spacing. A4/Letter dimensions and colors come from the theme; the composition owns its edge-to-edge geometry. On covers, choose `coverColor` against the actual artwork. A page-background crop is centered; use a local `MediaFrame` composition when exact crop alignment matters.
|
|
24
|
+
|
|
25
|
+
## Use the primitives outside this template
|
|
26
|
+
|
|
27
|
+
Use `MediaFrame` from `opendoc` for exact image boxes anywhere. It supports proportional `cover` or `contain`, crop alignment, and `radius` (half a square's width creates a circle). Wrap it in `Figure` for captions or `Block` for an image-only feedback target. Use `Page backgroundMedia="id"` for managed full bleed. See the copyable examples in [Media](../../docs/MEDIA.md). Keep prose and labels native so they remain selectable.
|
|
28
|
+
|
|
29
|
+
## Lessons already handled by OpenDoc
|
|
30
|
+
|
|
31
|
+
- Local page-background paths now resolve explicitly. Prefer `backgroundMedia` for provenance and freshness.
|
|
32
|
+
- Native SVG image elements can disappear without failing export. `MediaFrame` prepares the bounded picture through the installed renderer; agents need no base64/filesystem/native-addon helper.
|
|
33
|
+
- Media frames and backgrounds report their use and reject stale generated inputs just like ordinary `Media`.
|
|
34
|
+
- Crop alignment is not anatomical or semantic understanding. Review faces, objects, and focal points. Use `contain` when the whole subject, labels, or evidence must remain visible.
|
|
35
|
+
- Compilation and geometry checks cannot establish image visibility or good composition. Review **every PDF page**, especially the final crop, layering, contrast, captions, and extracted text.
|
|
36
|
+
|
|
37
|
+
Vary the composition freely to serve the material. Preserve stable block/text identities, accurate image provenance, and the reviewed-PDF workflow.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import * as F from '@formepdf/react';
|
|
3
|
+
import { Block, Document, Heading, MediaFrame, Page, Paragraph, TextSlot, type ImageFrameOptions } from 'opendoc';
|
|
4
|
+
import { themePage, themeType, type DocTheme } from 'opendoc/themes';
|
|
5
|
+
|
|
6
|
+
export type ImageStoryLayout = 'cover' | 'split-left' | 'split-top' | 'panorama' | 'diptych' | 'collage' | 'overlay';
|
|
7
|
+
export type StoryImage = Pick<ImageFrameOptions, 'fit' | 'position' | 'radius'> & { item: string; alt?: string };
|
|
8
|
+
export interface ImageStoryPageProps {
|
|
9
|
+
/** A stable identity for this composition, independent of its physical page number. */
|
|
10
|
+
id: string;
|
|
11
|
+
theme: DocTheme;
|
|
12
|
+
layout?: ImageStoryLayout;
|
|
13
|
+
title: ReactNode;
|
|
14
|
+
eyebrow?: ReactNode;
|
|
15
|
+
image?: StoryImage;
|
|
16
|
+
secondary?: StoryImage;
|
|
17
|
+
detail?: StoryImage;
|
|
18
|
+
lead?: ReactNode;
|
|
19
|
+
children?: ReactNode;
|
|
20
|
+
caption?: ReactNode;
|
|
21
|
+
footer?: string;
|
|
22
|
+
titleStyle?: F.Style;
|
|
23
|
+
/** Cover text must contrast with the actual artwork. Defaults to white on an image. */
|
|
24
|
+
coverColor?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function ImageStory({ children, ...props }: Parameters<typeof Document>[0]) {
|
|
28
|
+
return <Document {...props}>{children}</Document>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type Box = { x: number; y: number; w: number; h: number };
|
|
32
|
+
const boxStyle = ({x,y,w,h}: Box): F.Style => ({ position: 'absolute', left: x, top: y, width: w, height: h });
|
|
33
|
+
|
|
34
|
+
/** An omitted image is a visible starter placeholder. A supplied, broken media item is an error. */
|
|
35
|
+
function Picture({id, image, box, theme, backdrop=false}: {id:string;image?:StoryImage;box:Box;theme:DocTheme;backdrop?:boolean}) {
|
|
36
|
+
return <Block id={id} style={boxStyle(box)}>
|
|
37
|
+
{image ? <MediaFrame {...image} width={box.w} height={box.h}/> : <F.View style={{width:box.w,height:box.h,backgroundColor:theme.line,alignItems:backdrop?'flex-end':'center',justifyContent:backdrop?'flex-start':'center',padding:backdrop?24:0}}>
|
|
38
|
+
<F.Text style={{fontFamily:theme.body,fontSize:10,color:theme.ink}}>Image position</F.Text>
|
|
39
|
+
</F.View>}
|
|
40
|
+
</Block>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Bounded editorial pages, paired with ordinary Pages for long, naturally flowing content. */
|
|
44
|
+
export function ImageStoryPage({id,theme,layout='split-left',title,eyebrow,image,secondary,detail,lead,children,caption,footer='IMAGE STORY',titleStyle,coverColor}: ImageStoryPageProps) {
|
|
45
|
+
if (!['cover','split-left','split-top','panorama','diptych','collage','overlay'].includes(layout)) throw new Error(`Unknown image-story layout: ${layout}.`);
|
|
46
|
+
const page = themePage(theme);
|
|
47
|
+
const W = page.size === 'Letter' ? 612 : 595.28, H = page.size === 'Letter' ? 792 : 841.89;
|
|
48
|
+
const full = layout === 'cover' || layout === 'overlay';
|
|
49
|
+
const foreground = layout === 'cover' && image ? coverColor ?? '#ffffff' : theme.ink;
|
|
50
|
+
const footerColor = full && image ? coverColor ?? '#ffffff' : theme.muted;
|
|
51
|
+
const picture = (slot:string, source:StoryImage|undefined, box:Box, backdrop=false) => <Picture id={`${id}-${slot}`} image={source} box={box} theme={theme} backdrop={backdrop}/>;
|
|
52
|
+
const prose = <>{lead && <Paragraph id={`${id}-lead`} style={{color:foreground}}><TextSlot slot="lead" from="lead">{lead}</TextSlot></Paragraph>}{children}</>;
|
|
53
|
+
const text = (box:Box, size:number, body:ReactNode=prose) => <F.View style={{...boxStyle(box),overflow:'hidden'}}>
|
|
54
|
+
{eyebrow && <Paragraph id={`${id}-eyebrow`} role="label" baseStyle={{marginBottom:18}} style={{color:foreground}}><TextSlot slot="eyebrow" from="eyebrow">{eyebrow}</TextSlot></Paragraph>}
|
|
55
|
+
<Heading id={`${id}-title`} level={layout==='cover'?1:2} baseStyle={{fontSize:size,lineHeight:1.08,marginTop:0,marginBottom:22}} style={{color:foreground,...titleStyle}}><TextSlot slot="title" from="title">{title}</TextSlot></Heading>
|
|
56
|
+
<F.View style={{color:foreground}}>{body}</F.View>
|
|
57
|
+
</F.View>;
|
|
58
|
+
const body = (box:Box) => <F.View style={{...boxStyle(box),overflow:'hidden'}}>{prose}</F.View>;
|
|
59
|
+
const note = (box:Box) => caption && <F.View style={{...boxStyle(box),overflow:'hidden'}}><Paragraph id={`${id}-caption`} role="caption" style={{marginBottom:0}}><TextSlot slot="caption" from="caption">{caption}</TextSlot></Paragraph></F.View>;
|
|
60
|
+
return <Page size={page.size} margin={0} style={{...page.style,lineBreaking:'greedy',backgroundColor:theme.paper}}
|
|
61
|
+
backgroundMedia={full ? image?.item : undefined} backgroundSize="cover" backgroundPosition="center">
|
|
62
|
+
{layout === 'cover' && <>
|
|
63
|
+
{!image && picture('image',undefined,{x:0,y:0,w:W,h:H},true)}
|
|
64
|
+
{text({x:42,y:H*.23,w:W-110,h:H*.65},56)}
|
|
65
|
+
</>}
|
|
66
|
+
{layout === 'split-left' && <>
|
|
67
|
+
{picture('image',image,{x:0,y:0,w:W/2,h:H})}
|
|
68
|
+
{text({x:W/2+28,y:H*.22,w:W/2-56,h:H*.66},36)}
|
|
69
|
+
</>}
|
|
70
|
+
{layout === 'split-top' && <>
|
|
71
|
+
{picture('image',image,{x:0,y:0,w:W,h:H/2})}
|
|
72
|
+
{text({x:42,y:H/2+30,w:W-84,h:H/2-100},40)}
|
|
73
|
+
</>}
|
|
74
|
+
{layout === 'panorama' && <>
|
|
75
|
+
{text({x:42,y:67,w:W-84,h:H*.22},43,null)}
|
|
76
|
+
{picture('image',image,{x:0,y:H*.32,w:W,h:H*.2})}
|
|
77
|
+
<F.View style={{position:'absolute',left:W-241,top:H*.47,width:211,height:211,backgroundColor:theme.paper}}/>
|
|
78
|
+
{picture('secondary',secondary,{x:W-229,y:H*.47+12,w:187,h:187})}
|
|
79
|
+
{body({x:42,y:H*.57,w:W-313,h:H*.32})}
|
|
80
|
+
{note({x:W-229,y:H*.47+222,w:187,h:H*.16})}
|
|
81
|
+
</>}
|
|
82
|
+
{layout === 'diptych' && <>
|
|
83
|
+
{text({x:42,y:67,w:W-84,h:H*.2},43,null)}
|
|
84
|
+
{picture('image',image,{x:42,y:H*.29,w:(W-100)*.30,h:H*.43})}
|
|
85
|
+
{picture('secondary',secondary,{x:58+(W-100)*.30,y:H*.29,w:(W-100)*.70,h:H*.43})}
|
|
86
|
+
{body({x:42,y:H*.77,w:W-84,h:H*.15})}
|
|
87
|
+
</>}
|
|
88
|
+
{layout === 'collage' && <>
|
|
89
|
+
{text({x:42,y:67,w:W-84,h:H*.15},43,null)}
|
|
90
|
+
{picture('image',image,{x:42,y:H*.22,w:W*.365,h:H*.455})}
|
|
91
|
+
{picture('secondary',secondary,{x:W*.465,y:H*.22,w:W*.535-42,h:W*.535-42})}
|
|
92
|
+
{body({x:W*.465,y:H*.22+W*.535-24,w:W*.535-42,h:60})}
|
|
93
|
+
{picture('detail',detail,{x:W*.26,y:H*.67,w:W*.74-42,h:H*.17})}
|
|
94
|
+
{note({x:42,y:H*.875,w:W-84,h:H*.07})}
|
|
95
|
+
</>}
|
|
96
|
+
{layout === 'overlay' && <>
|
|
97
|
+
{!image && picture('image',undefined,{x:0,y:0,w:W,h:H},true)}
|
|
98
|
+
<F.View style={{position:'absolute',left:42,top:H*.28,width:W*.60,height:H*.59,backgroundColor:theme.paper}}/>
|
|
99
|
+
{text({x:68,y:H*.28+28,w:W*.60-52,h:H*.59-56},44)}
|
|
100
|
+
</>}
|
|
101
|
+
{theme.runningFooter && <F.View style={{position:'absolute',left:layout==='split-left'?W/2+28:42,top:H-34,width:layout==='split-left'?W/2-56:W-84,flexDirection:'row',justifyContent:'space-between'}}>
|
|
102
|
+
<F.Text style={{...themeType(theme,'small',{fontFamily:theme.body,fontSize:8}),color:footerColor}}>{footer}</F.Text>
|
|
103
|
+
<F.Text style={{...themeType(theme,'small',{fontFamily:theme.body,fontSize:8}),color:footerColor}}>{'{{pageNumber}}'}</F.Text>
|
|
104
|
+
</F.View>}
|
|
105
|
+
</Page>;
|
|
106
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ImageStory, ImageStoryPage, type ImageStoryLayout } from './index';
|
|
2
|
+
import { Pages, Paragraph, Section } from 'opendoc';
|
|
3
|
+
import { neutral } from '../../themes';
|
|
4
|
+
import { type DocTheme } from 'opendoc/themes';
|
|
5
|
+
|
|
6
|
+
export const meta = { title: 'Image story', description: 'A neutral layout skeleton. All text and image positions are replaceable placeholders.', kind: 'layout specimen', theme: 'neutral' };
|
|
7
|
+
const layouts: {id:ImageStoryLayout; title:string; copy:string}[] = [
|
|
8
|
+
{id:'cover',title:'Document title\ngoes here.',copy:'Subtitle placeholder. Replace with a brief introduction and choose artwork with enough quiet space for the title.'},
|
|
9
|
+
{id:'split-left',title:'Feature title\ngoes here.',copy:'Lead paragraph placeholder. Replace this text with a short introduction alongside a portrait image.'},
|
|
10
|
+
{id:'split-top',title:'Section title\ngoes here.',copy:'Introductory paragraph placeholder. Replace with the context the reader needs after viewing the opening image.'},
|
|
11
|
+
{id:'panorama',title:'Section title goes here.',copy:'Body text placeholder. Explain the relationship between the panoramic image and the smaller inset.'},
|
|
12
|
+
{id:'diptych',title:'Comparison title\ngoes here.',copy:'Body text placeholder. Describe the two images or viewpoints and why they belong together.'},
|
|
13
|
+
{id:'collage',title:'Section title goes here.',copy:'Short text placeholder connecting the three image positions.'},
|
|
14
|
+
{id:'overlay',title:'Feature title\ngoes here.',copy:'Body text placeholder. Replace with concise writing placed on an opaque surface over your chosen image.'},
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
export function Specimen({length='typical',theme=neutral}: {length?:'sparse'|'typical'|'long';theme?:DocTheme} = {}) {
|
|
18
|
+
const sparse = length === 'sparse', long = length === 'long';
|
|
19
|
+
return <ImageStory title={meta.title} theme={theme}>
|
|
20
|
+
{(sparse || long ? layouts.filter(item=>item.id==='split-top') : layouts).map(item=><ImageStoryPage key={item.id} id={`sample-${item.id}`} theme={theme} layout={item.id}
|
|
21
|
+
title={long && item.id==='split-top' ? 'A longer editorial title can change the composition without changing the story' : item.title}
|
|
22
|
+
titleStyle={long && item.id==='split-top' ? {fontSize:29} : undefined}
|
|
23
|
+
eyebrow={sparse ? undefined : item.id.replaceAll('-',' ').toUpperCase()}
|
|
24
|
+
caption="Caption placeholder. Describe the image and provide attribution where appropriate."
|
|
25
|
+
lead={sparse ? undefined : item.copy}/>)}
|
|
26
|
+
{long && <Pages title="The story continues">
|
|
27
|
+
<Section id="long-opening" title="Let the prose flow" lead="Image compositions are moments within a longer document, not containers for every paragraph.">
|
|
28
|
+
{Array.from({length:20},(_,index)=><Paragraph key={index} id={`long-passage-${index+1}`}>{'This is illustrative prose used to demonstrate native pagination. The writing keeps its normal size and reading rhythm while the surrounding image pages remain deliberate pauses. '.repeat(4)}{index===19?' END OF STORY':''}</Paragraph>)}
|
|
29
|
+
</Section>
|
|
30
|
+
</Pages>}
|
|
31
|
+
</ImageStory>;
|
|
32
|
+
}
|
|
33
|
+
export default Specimen;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ImageStory, ImageStoryPage } from '../../templates/image-story';
|
|
2
|
+
import { Pages, Paragraph, Section } from 'opendoc';
|
|
3
|
+
// @ts-ignore The selected local theme module is inserted when this starter becomes a document.
|
|
4
|
+
import { theme } from "__OPENDOC_THEME_MODULE__";
|
|
5
|
+
|
|
6
|
+
const title = "__OPENDOC_TITLE__";
|
|
7
|
+
export const meta = { title, description: 'An image-led document, ready for your material.', kind: 'illustrated feature', theme: "__OPENDOC_THEME__" };
|
|
8
|
+
export const provenance = { template: 'templates/image-story/index.tsx' };
|
|
9
|
+
|
|
10
|
+
export default function Story() {
|
|
11
|
+
return <ImageStory title={title} theme={theme}>
|
|
12
|
+
{/* Import and review document-owned media, then add image={{item:'your-image'}}.
|
|
13
|
+
Missing image props intentionally show a placeholder; named items must exist.
|
|
14
|
+
Choose split-top for a longer title, or adjust titleStyle after reviewing the PDF. */}
|
|
15
|
+
<ImageStoryPage id="opening" theme={theme} layout="split-top" title={title} eyebrow="ILLUSTRATED FEATURE">
|
|
16
|
+
<Paragraph id="opening-lead">Replace this placeholder with a short introduction. Choose an image that adds meaning to the story and a crop that preserves its subject.</Paragraph>
|
|
17
|
+
</ImageStoryPage>
|
|
18
|
+
<Pages title={title}>
|
|
19
|
+
<Section id="story" title="Continue the story" lead="Long passages belong in ordinary flowing pages.">
|
|
20
|
+
<Paragraph id="story-opening">Replace this placeholder with your material. Add selected image-story compositions where they help the reader, using stable IDs and document-owned images. There is no required sequence or page count.</Paragraph>
|
|
21
|
+
</Section>
|
|
22
|
+
</Pages>
|
|
23
|
+
</ImageStory>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Image story",
|
|
3
|
+
"description": "Image-led editorial pages: full-bleed covers, half-page splits, panoramas with insets, diptychs, collage, and floating text panels. Mix selected compositions with flowing prose.",
|
|
4
|
+
"format": "A4 or Letter · Flexible image compositions",
|
|
5
|
+
"structure": [
|
|
6
|
+
"Replaceable image and text placeholders only; artwork belongs to each document and appearance comes from its theme.",
|
|
7
|
+
"Choose individual compositions; the specimen is a menu, not a required seven-page sequence.",
|
|
8
|
+
"Managed image frames support proportional crops, containment, alignment, and rounded or circular windows.",
|
|
9
|
+
"Covers and overlays use reliable full-page managed artwork with native selectable text.",
|
|
10
|
+
"Bounded feature pages carry concise copy; ordinary Pages carry long prose and references.",
|
|
11
|
+
"Theme typography, paper, and colors remain live. Adapt title sizes and image balance for the material."
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Invoice
|
|
2
|
+
|
|
3
|
+
Use this as a soft foundation for an invoice, with room for variation and creativity. The starting composition makes the amount due easy to find, keeps references and dates near the opening, and gives the itemized charges enough width to read. Seller and customer details share a row; payment details and supporting notes follow the pricing. Adapt the title size, spacing, and emphasis to the business and content. A long title may use a smaller `titleStyle`; a simple invoice may omit a project reference, introduction, or notes.
|
|
4
|
+
|
|
5
|
+
Each invoice owns its `data.json`; the shared template owns layout and the caller's theme owns visual hierarchy, rhythm, and component treatments. Keep variations for one document local or preserve existing shared defaults. Do not add signature or acceptance fields merely because the quotation has them. No invoice status, overdue label, payment deadline, or payment event is inferred from the current date. Use supplied dates and recorded payment amounts only.
|
|
6
|
+
|
|
7
|
+
Preserve validation, stable IDs, and calculated pricing. Quantities and amounts are decimal strings, currency precision is explicit, and the documented half-up rounding sequence applies. `amountPaid` is a supplied cumulative payment, not a discount; it reduces the balance after tax. Omission starts a new invoice with no recorded payments. Do not type a competing balance into prose or invent bank details. A zero balance does not trigger a fabricated receipt or payment date.
|
|
8
|
+
|
|
9
|
+
The current contract supports one currency, an optional fixed discount, one supplied tax rate on the discounted subtotal, and payments up to the invoice total. Credits, overpayments, inclusive tax, mixed rates, and other accounting cases need explicit contract extensions. This is a generic invoice format; do not label it compliant with a particular jurisdiction or an electronic-invoicing system without doing that separate work. Sample parties, prices, dates, and payment instructions remain visibly illustrative until replaced with supplied facts.
|
|
10
|
+
|
|
11
|
+
Use native Forme flow and existing OpenDoc blocks. Keep totals together and let tables, instructions, and notes continue across pages. Keep party details bounded; longer explanations belong in the introduction or notes. Do not manually split lines, force one page, auto-shrink content, or modify the renderer. Review every adapted PDF. Shared changes need sparse, typical, and long data, another theme, zero/partial/full payment checks, currency precision checks, a working instance, and confirmation that quotation pricing remains unchanged. Preserve unrelated work.
|
|
12
|
+
|
|
13
|
+
The opening logo placeholder is an adaptable brand slot. Replace it with supplied, proportionally sized artwork through `logo`, or pass null to omit it. Do not invent a real company logo or alter its colors to match a theme. Keep the stable logo block ID and check the opening and downstream page breaks after replacement.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Invoice
|
|
2
|
+
|
|
3
|
+
A native Forme invoice with a prominent amount due, invoice references and dates, paired seller/customer details, line items, calculated totals, and optional payment instructions. Defaults are A4 portrait, 48-point top/side and 52-point bottom margins, 10.5/14.7-point body text, a 28-point title, and a larger opening balance. The caller's theme supplies appearance. Treat the composition as an adaptable starting point; no page count is enforced.
|
|
4
|
+
|
|
5
|
+
`invoiceTemplate(theme)` uses the existing `parse`, `meta`, and `render` contract. Bind it to the instance's `data.json` with `bindTemplate`. The catalog creates a separate data file for each invoice and records template/data provenance. Editing that file updates content, metadata, and calculations. `Invoice` accepts parsed `data`, `theme`, and optional native `titleStyle` for a local design variation. The catalog preview uses Neutral.
|
|
6
|
+
|
|
7
|
+
## Data contract
|
|
8
|
+
|
|
9
|
+
Required fields are `schemaVersion: 1`, `title`, `number`, `issuedOn`, `seller`, `customer`, `synthetic`, and `pricing`. Optional `dueOn` is a real date on or after the issue date. All dates use `YYYY-MM-DD`; dates and status are not inferred from today's clock. Optional `reference` can identify a supplied purchase order, quotation, or project reference.
|
|
10
|
+
|
|
11
|
+
Each party has a required single-line `name` of up to 180 characters and optional `details` of up to 700 characters and eight supplied lines. Names and address/contact details wrap naturally in the paired columns. Supplied registration or tax identifiers can appear in these details when appropriate. This generic format does not certify regulatory or electronic-invoicing compliance.
|
|
12
|
+
|
|
13
|
+
Optional `introduction`, `paymentInstructions`, and `paymentReference` provide supplied prose and remittance details. No bank account is invented. Optional `notes` is an array of `{ id, title, text }` with unique stable IDs. Notes have stable length-prefixed comment targets, while the item table remains one target through pagination. Unknown fields and unsupported amounts fail clearly.
|
|
14
|
+
|
|
15
|
+
`synthetic` must be explicit. All bundled examples mark their parties, prices, dates, payment details, and recorded payments as illustrative. Set it to false only after replacing the samples with real supplied material. The template does not send invoices or execute payments.
|
|
16
|
+
|
|
17
|
+
## Pricing and payments
|
|
18
|
+
|
|
19
|
+
The pricing contract and rounding rules are shared with [Quotation](../quotation/README.md): decimal-string quantities and amounts, explicit currency precision from 0 to 3, each line rounded half up, a fixed discount subtracted from the subtotal, then one supplied tax rate applied to that net subtotal and rounded half up. No tax rate is inferred. The example's 10% is illustrative only.
|
|
20
|
+
|
|
21
|
+
Optional `amountPaid` is the cumulative amount already received, as a nonnegative decimal string with no more fractional digits than the currency allows. Omission means no payment has been recorded for this new invoice; the payments row is omitted. An explicit `"0.00"` displays a zero-payment row. A supplied payment may cover the whole invoice but cannot exceed it. Amounts must fit within `Number.MAX_SAFE_INTEGER` minor units, although arithmetic uses BigInt throughout.
|
|
22
|
+
|
|
23
|
+
`calculateInvoice` returns the shared totals, `paidMinor`, and `balanceMinor`. Payments are subtracted **after** discounts and tax; they never change taxable pricing. The opening and final amount due use the same calculated balance. The typical example is USD 1,320.00 total − USD 320.00 received = USD 1,000.00 due. A full payment produces a zero balance without generating an unverified status, receipt, or payment date.
|
|
24
|
+
|
|
25
|
+
Credits, overpayments, multiple tax rates, inclusive tax, additional charges, and payment-history reconciliation are outside this version's data contract. Extend them explicitly rather than putting a contradictory total in a note. Long tables repeat headers, totals stay together, and long payment instructions or notes remain normal flowing paragraphs. See [AGENTS.md](AGENTS.md) for design flexibility and preservation requirements.
|
|
26
|
+
|
|
27
|
+
## Logo
|
|
28
|
+
|
|
29
|
+
The opening has a quiet, outlined **YOUR LOGO** placeholder at the upper right. It appears once, on the cover when present or at the start of the body. Replace it with supplied artwork through the optional `logo` prop, or pass `logo={null}` to omit it. The placeholder follows the selected theme; actual artwork retains its own colors. Keep logo dimensions bounded and preserve its aspect ratio; 88 × 28 points is a starting size, not a brand requirement.
|
|
30
|
+
|
|
31
|
+
Import reusable artwork into the shared [asset library](../../docs/ASSETS.md), inspect its variation guidance, and bind an exact version to the intended document:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
pnpm assets -- inspect logo acme
|
|
35
|
+
pnpm assets -- bind my-document logo acme --variation default
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Import `Logo` from `opendoc` and supply `<Logo width={88} height={28} />` through the `logo` prop. Choose a variation for the actual page background, preserve its proportions, and review the PDF. The existing logo block provides the feedback target; a decorative mark needs no figure caption. Artwork belongs in the layout, separately from commercial JSON.
|
|
39
|
+
|
|
40
|
+
The bound starter accepts `invoiceTemplate(theme, { logo: <Logo width={88} height={28} /> })`; use `{ logo: null }` to omit it. Pass the adapted document theme from `./theme` to this factory.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"title": "__OPENDOC_TITLE__",
|
|
4
|
+
"number": "SAMPLE-INV-001",
|
|
5
|
+
"issuedOn": "2026-09-08",
|
|
6
|
+
"dueOn": "2026-09-22",
|
|
7
|
+
"reference": "SAMPLE-Q-001",
|
|
8
|
+
"seller": {
|
|
9
|
+
"name": "Example Studio",
|
|
10
|
+
"details": "Studio address placeholder\nContact details placeholder"
|
|
11
|
+
},
|
|
12
|
+
"customer": {
|
|
13
|
+
"name": "Example Client",
|
|
14
|
+
"details": "Client address placeholder\nAttention: project contact"
|
|
15
|
+
},
|
|
16
|
+
"synthetic": true,
|
|
17
|
+
"pricing": {
|
|
18
|
+
"currency": {
|
|
19
|
+
"code": "USD",
|
|
20
|
+
"decimals": 2
|
|
21
|
+
},
|
|
22
|
+
"items": [
|
|
23
|
+
{
|
|
24
|
+
"id": "planning",
|
|
25
|
+
"description": "Content planning workshop",
|
|
26
|
+
"quantity": "2.5",
|
|
27
|
+
"unit": "hours",
|
|
28
|
+
"unitPrice": "160.00"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "writing",
|
|
32
|
+
"description": "Website copy package: supplied scope and agreed deliverables",
|
|
33
|
+
"quantity": "1",
|
|
34
|
+
"unit": "package",
|
|
35
|
+
"unitPrice": "600.00"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": "review",
|
|
39
|
+
"description": "Review and revision sessions",
|
|
40
|
+
"quantity": "3",
|
|
41
|
+
"unit": "hours",
|
|
42
|
+
"unitPrice": "75.00"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"discount": "25.00",
|
|
46
|
+
"tax": {
|
|
47
|
+
"label": "Illustrative tax",
|
|
48
|
+
"ratePercent": "10"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"amountPaid": "320.00",
|
|
52
|
+
"paymentInstructions": "Payment details placeholder. Supply the agreed method and verified recipient details before issuing a real invoice.",
|
|
53
|
+
"paymentReference": "SAMPLE-INV-001",
|
|
54
|
+
"notes": [
|
|
55
|
+
{
|
|
56
|
+
"id": "scope",
|
|
57
|
+
"title": "Scope note",
|
|
58
|
+
"text": "Illustrative services only. Replace the sample with the actual goods or services and any necessary supporting details."
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|