@xiaobuyu/nodesign 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +140 -0
  3. package/bin/nodesign.js +176 -0
  4. package/package.json +104 -0
  5. package/server/api/README.md +45 -0
  6. package/server/api/_guard.js +75 -0
  7. package/server/api/admin.js +187 -0
  8. package/server/api/assets/docx-page.js +103 -0
  9. package/server/api/assets/helpers.js +22 -0
  10. package/server/api/assets/notes.js +144 -0
  11. package/server/api/assets.js +896 -0
  12. package/server/api/board.js +57 -0
  13. package/server/api/browse.js +138 -0
  14. package/server/api/canvas.js +444 -0
  15. package/server/api/chatai.js +324 -0
  16. package/server/api/exports/build-standalone.js +980 -0
  17. package/server/api/exports/cards.js +118 -0
  18. package/server/api/exports/docx-pdf.js +46 -0
  19. package/server/api/exports/export-page.js +142 -0
  20. package/server/api/exports/handoff.js +147 -0
  21. package/server/api/exports.js +690 -0
  22. package/server/api/instruction.js +75 -0
  23. package/server/api/local.js +115 -0
  24. package/server/api/me.js +116 -0
  25. package/server/api/memory.js +185 -0
  26. package/server/api/pending-changes.js +366 -0
  27. package/server/api/plugins.js +164 -0
  28. package/server/api/projects.js +220 -0
  29. package/server/api/publish.js +64 -0
  30. package/server/api/recent.js +73 -0
  31. package/server/api/sessions.js +589 -0
  32. package/server/api/skills.js +77 -0
  33. package/server/api/standalone-fit.js +168 -0
  34. package/server/api/turn-compose.js +180 -0
  35. package/server/api/turn-inflight.js +44 -0
  36. package/server/api/turn.js +669 -0
  37. package/server/auth/README.md +17 -0
  38. package/server/auth/middleware.js +138 -0
  39. package/server/auth/origin-guard.js +71 -0
  40. package/server/auth/session.js +108 -0
  41. package/server/auth/tier.js +113 -0
  42. package/server/auth/users-store.js +348 -0
  43. package/server/edit/README.md +29 -0
  44. package/server/engine/README.md +113 -0
  45. package/server/engine/agent/agent-shared.js +550 -0
  46. package/server/engine/agent/auto-mode-default-hard-deny.txt +4 -0
  47. package/server/engine/agent/auto-mode-rules.js +78 -0
  48. package/server/engine/agent/context.js +418 -0
  49. package/server/engine/agent/events.js +464 -0
  50. package/server/engine/agent/hooks/canvas-validate.js +199 -0
  51. package/server/engine/agent/hooks/failure.js +120 -0
  52. package/server/engine/agent/hooks/file-events.js +75 -0
  53. package/server/engine/agent/hooks/lifecycle.js +233 -0
  54. package/server/engine/agent/hooks/post-canvas-focus.js +80 -0
  55. package/server/engine/agent/hooks/post-guidance.js +206 -0
  56. package/server/engine/agent/hooks/post-subagent-report.js +104 -0
  57. package/server/engine/agent/hooks/post-trim.js +58 -0
  58. package/server/engine/agent/hooks/pre-board-neighborhood.js +34 -0
  59. package/server/engine/agent/hooks/pre-defaults.js +84 -0
  60. package/server/engine/agent/hooks/pre-injectors.js +277 -0
  61. package/server/engine/agent/hooks/pre-performance-log-guard.js +78 -0
  62. package/server/engine/agent/hooks/pre-starter-files.js +61 -0
  63. package/server/engine/agent/hooks/pre-workspace-scope-guard.js +78 -0
  64. package/server/engine/agent/hooks/site-validate.js +94 -0
  65. package/server/engine/agent/hooks/tool-prompts.js +31 -0
  66. package/server/engine/agent/hooks/turn-state-memory.js +56 -0
  67. package/server/engine/agent/hooks/user-prompt-submit.js +215 -0
  68. package/server/engine/agent/hooks.js +354 -0
  69. package/server/engine/agent/init-contract.js +69 -0
  70. package/server/engine/agent/isolation.js +159 -0
  71. package/server/engine/agent/model-context.js +359 -0
  72. package/server/engine/agent/model-table.js +292 -0
  73. package/server/engine/agent/plugin-loader.js +266 -0
  74. package/server/engine/agent/prompts/nodesign-prelude.md +336 -0
  75. package/server/engine/agent/prompts/tools/ask-user-question-protocol.md +71 -0
  76. package/server/engine/agent/prompts/tools/direct-edit-protocol.md +98 -0
  77. package/server/engine/agent/prompts/tools/generate-image-cookbook.gemini-gateway.md +583 -0
  78. package/server/engine/agent/prompts/tools/generate-image-cookbook.md +483 -0
  79. package/server/engine/agent/prompts/tools/hybrid-reference.md +100 -0
  80. package/server/engine/agent/prompts/tools/paint-still-cookbook.md +270 -0
  81. package/server/engine/agent/prompts/tools/roll-film-cookbook.md +70 -0
  82. package/server/engine/agent/prompts/tools/site-reference.md +106 -0
  83. package/server/engine/agent/prompts/tools/tweaks-syntax.md +125 -0
  84. package/server/engine/agent/prompts/tools/vision-checker-dispatch.md +48 -0
  85. package/server/engine/agent/session-loop.js +1024 -0
  86. package/server/engine/agent/session-model.js +164 -0
  87. package/server/engine/agent/skill.js +204 -0
  88. package/server/engine/agent/system-prompts.js +86 -0
  89. package/server/engine/agent/task-events.js +78 -0
  90. package/server/engine/agents/ds-extractor.md +132 -0
  91. package/server/engine/agents/explorer.md +190 -0
  92. package/server/engine/agents/index.js +230 -0
  93. package/server/engine/agents/schemas/design-system.json +156 -0
  94. package/server/engine/agents/schemas/tweak-schema.json +113 -0
  95. package/server/engine/agents/tweak-proposer.md +127 -0
  96. package/server/engine/agents/vision-checker.md +254 -0
  97. package/server/engine/browse/capture.js +422 -0
  98. package/server/engine/browse/card.js +137 -0
  99. package/server/engine/browse/handover.js +59 -0
  100. package/server/engine/browse/page-digest.js +119 -0
  101. package/server/engine/browse/refs.js +196 -0
  102. package/server/engine/browse/registry.js +307 -0
  103. package/server/engine/browse/screencast.js +170 -0
  104. package/server/engine/browse/state.js +121 -0
  105. package/server/engine/chatai/chat-log.js +79 -0
  106. package/server/engine/chatai/index.js +193 -0
  107. package/server/engine/chatai/openai-compat.js +152 -0
  108. package/server/engine/chatai/orchestrate.js +309 -0
  109. package/server/engine/chatai/perform.js +40 -0
  110. package/server/engine/chatai/summarize.js +79 -0
  111. package/server/engine/mcp/capability-gate.js +52 -0
  112. package/server/engine/mcp/index.js +339 -0
  113. package/server/engine/mcp/param-sanitizer.js +142 -0
  114. package/server/engine/mcp/tools/arrange-on-board.js +124 -0
  115. package/server/engine/mcp/tools/artifact-session.js +278 -0
  116. package/server/engine/mcp/tools/browse-computer.js +421 -0
  117. package/server/engine/mcp/tools/browse-find-batch.js +183 -0
  118. package/server/engine/mcp/tools/browse-screenshot.js +157 -0
  119. package/server/engine/mcp/tools/browse.js +480 -0
  120. package/server/engine/mcp/tools/build-docx.js +101 -0
  121. package/server/engine/mcp/tools/clear-pending-changes.js +99 -0
  122. package/server/engine/mcp/tools/create-on-board.js +155 -0
  123. package/server/engine/mcp/tools/crystallize-skill.js +168 -0
  124. package/server/engine/mcp/tools/deliver-files.js +0 -0
  125. package/server/engine/mcp/tools/explain-style.js +237 -0
  126. package/server/engine/mcp/tools/export-handoff.js +133 -0
  127. package/server/engine/mcp/tools/expose-tweaks.js +149 -0
  128. package/server/engine/mcp/tools/generate-image.js +842 -0
  129. package/server/engine/mcp/tools/get-computed-styles.js +164 -0
  130. package/server/engine/mcp/tools/get-pending-changes.js +205 -0
  131. package/server/engine/mcp/tools/h3box-ssh.js +84 -0
  132. package/server/engine/mcp/tools/helpers/acquire-page.js +82 -0
  133. package/server/engine/mcp/tools/helpers/motion-lab.js +554 -0
  134. package/server/engine/mcp/tools/helpers/motion-scroll.js +112 -0
  135. package/server/engine/mcp/tools/helpers/perception-page.js +215 -0
  136. package/server/engine/mcp/tools/helpers/reference-download.js +103 -0
  137. package/server/engine/mcp/tools/helpers/rembg-bridge.py +80 -0
  138. package/server/engine/mcp/tools/helpers/rembg.js +273 -0
  139. package/server/engine/mcp/tools/helpers/shot-pipeline.js +280 -0
  140. package/server/engine/mcp/tools/highlight.js +68 -0
  141. package/server/engine/mcp/tools/list-pages.js +222 -0
  142. package/server/engine/mcp/tools/lookup-tags.js +59 -0
  143. package/server/engine/mcp/tools/navigate-to-page.js +60 -0
  144. package/server/engine/mcp/tools/organize-board.js +64 -0
  145. package/server/engine/mcp/tools/paint-still.js +434 -0
  146. package/server/engine/mcp/tools/pin-to-board.js +130 -0
  147. package/server/engine/mcp/tools/preview-deck.js +130 -0
  148. package/server/engine/mcp/tools/profile-scroll.js +305 -0
  149. package/server/engine/mcp/tools/publish-site.js +102 -0
  150. package/server/engine/mcp/tools/query-elements.js +195 -0
  151. package/server/engine/mcp/tools/read-board.js +103 -0
  152. package/server/engine/mcp/tools/read-document.js +93 -0
  153. package/server/engine/mcp/tools/read-page.js +264 -0
  154. package/server/engine/mcp/tools/read-tavern-json.js +143 -0
  155. package/server/engine/mcp/tools/record-decision.js +140 -0
  156. package/server/engine/mcp/tools/relate-on-board.js +110 -0
  157. package/server/engine/mcp/tools/remove-background.js +391 -0
  158. package/server/engine/mcp/tools/report-issue.js +115 -0
  159. package/server/engine/mcp/tools/roll-film.js +266 -0
  160. package/server/engine/mcp/tools/screenshot-docx.js +138 -0
  161. package/server/engine/mcp/tools/screenshot-url.js +195 -0
  162. package/server/engine/mcp/tools/screenshot.js +583 -0
  163. package/server/engine/mcp/tools/tier-gate.js +96 -0
  164. package/server/engine/mcp/tools/trace-motion.js +215 -0
  165. package/server/engine/mcp/tools/web-search.js +548 -0
  166. package/server/engine/motion/inventory.js +349 -0
  167. package/server/engine/perception/session.js +235 -0
  168. package/server/engine/plugins/nodesign/.claude-plugin/plugin.json +5 -0
  169. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/SKILL.md +192 -0
  170. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/canvas.template.html +667 -0
  171. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/hybrid-grid.md +22 -0
  172. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/image-led-cover.md +25 -0
  173. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/portrait.md +23 -0
  174. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/quote-backdrop.md +21 -0
  175. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/section-divider.md +23 -0
  176. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/text-led.md +21 -0
  177. package/server/engine/plugins/nodesign/skills/docx-craft/SKILL.md +162 -0
  178. package/server/engine/plugins/nodesign/skills/docx-craft/references/token-schema.md +407 -0
  179. package/server/engine/plugins/nodesign/skills/docx-craft//346/226/207/346/241/243.template.json +80 -0
  180. package/server/engine/plugins/nodesign/skills/rp-craft/SKILL.md +228 -0
  181. package/server/engine/plugins/nodesign/skills/rp-craft/patterns//346/274/224/345/207/272/351/241/265-/346/234/200/345/260/217/345/256/236/347/216/260.html +78 -0
  182. package/server/engine/plugins/nodesign/skills/rp-craft//346/274/224/345/207/272.template.js +268 -0
  183. package/server/engine/plugins/nodesign/skills/site-craft/SKILL.md +323 -0
  184. package/server/engine/plugins/nodesign/skills/site-craft/patterns/build-lane.md +134 -0
  185. package/server/engine/plugins/nodesign/skills/site-craft/patterns/cutout-collage.md +61 -0
  186. package/server/engine/plugins/nodesign/skills/site-craft/patterns/mock-app.md +163 -0
  187. package/server/engine/plugins/nodesign/skills/site-craft/patterns/page-transitions.md +86 -0
  188. package/server/engine/runs/active-runs.js +698 -0
  189. package/server/engine/runs/live-turn.js +252 -0
  190. package/server/engine/runs/store.js +364 -0
  191. package/server/engine/runs/turn-relay.js +217 -0
  192. package/server/engine/runtime/workspace.js +164 -0
  193. package/server/index.js +235 -0
  194. package/server/lib/artifact-file-path.js +80 -0
  195. package/server/lib/artifact-target.js +284 -0
  196. package/server/lib/asset-refs.js +239 -0
  197. package/server/lib/async-queue.js +104 -0
  198. package/server/lib/auto-relations.js +130 -0
  199. package/server/lib/binding-types.js +60 -0
  200. package/server/lib/board-kind-sizes.js +62 -0
  201. package/server/lib/board-relations.js +133 -0
  202. package/server/lib/browse-proxy.js +180 -0
  203. package/server/lib/canvas-id.js +36 -0
  204. package/server/lib/cover.js +227 -0
  205. package/server/lib/danbooru-tags.js +291 -0
  206. package/server/lib/doc-extract.js +156 -0
  207. package/server/lib/docx/build-from-source.js +260 -0
  208. package/server/lib/docx/build.js +490 -0
  209. package/server/lib/docx/dump-styles.js +287 -0
  210. package/server/lib/docx/fonts/nodesign-cjk.conf +164 -0
  211. package/server/lib/docx/merge-runs.js +129 -0
  212. package/server/lib/docx/numbering.js +218 -0
  213. package/server/lib/docx/order.js +152 -0
  214. package/server/lib/docx/rawzip.js +172 -0
  215. package/server/lib/docx/render.js +92 -0
  216. package/server/lib/docx/text-lint.js +225 -0
  217. package/server/lib/docx/tokens.js +335 -0
  218. package/server/lib/docx/units.js +29 -0
  219. package/server/lib/docx/xml.js +291 -0
  220. package/server/lib/docx-pages.js +187 -0
  221. package/server/lib/export-collect.js +289 -0
  222. package/server/lib/export-package.js +210 -0
  223. package/server/lib/html-srcset.js +145 -0
  224. package/server/lib/image-variant.js +460 -0
  225. package/server/lib/ingress/forward-openai-chat.js +305 -0
  226. package/server/lib/ingress/openai-chat.js +491 -0
  227. package/server/lib/ingress/session-notice.js +66 -0
  228. package/server/lib/ingress/session-routes.js +68 -0
  229. package/server/lib/ingress/slot-probe.js +130 -0
  230. package/server/lib/ingress/upstream-billing.js +52 -0
  231. package/server/lib/ingress/upstream-fail-streak.js +72 -0
  232. package/server/lib/ingress/upstream-truncation.js +48 -0
  233. package/server/lib/issues-store.js +182 -0
  234. package/server/lib/kinds/deck.js +72 -0
  235. package/server/lib/kinds/docx.js +283 -0
  236. package/server/lib/kinds/file-kinds.js +113 -0
  237. package/server/lib/kinds/index.js +202 -0
  238. package/server/lib/kinds/site.js +161 -0
  239. package/server/lib/model-ingress.js +543 -0
  240. package/server/lib/moderation.js +255 -0
  241. package/server/lib/notice-store.js +103 -0
  242. package/server/lib/plugin-install.js +104 -0
  243. package/server/lib/plugin-validator.js +721 -0
  244. package/server/lib/publish-store.js +115 -0
  245. package/server/lib/quick-summary.js +52 -0
  246. package/server/lib/quota.js +270 -0
  247. package/server/lib/rate-window.js +29 -0
  248. package/server/lib/reference-assets.js +92 -0
  249. package/server/lib/region-shot.js +135 -0
  250. package/server/lib/safe-path.js +73 -0
  251. package/server/lib/sdk-session.js +33 -0
  252. package/server/lib/showcase-store.js +92 -0
  253. package/server/lib/site-publish.js +465 -0
  254. package/server/lib/ssrf-guard.js +432 -0
  255. package/server/lib/task-scan.js +158 -0
  256. package/server/lib/tavern-json.js +154 -0
  257. package/server/lib/video-variant.js +237 -0
  258. package/server/lib/workspace-path.js +33 -0
  259. package/server/ops/fix-sdk-musl.mjs +40 -0
  260. package/server/ops/install-macos-fonts.sh +114 -0
  261. package/server/ops/macos-fonts.conf +336 -0
  262. package/server/ops/sandbox-shim/bwrap +57 -0
  263. package/server/projects/assets-summary.js +119 -0
  264. package/server/projects/auto-name.js +53 -0
  265. package/server/projects/board-store.js +640 -0
  266. package/server/projects/move-entry.js +103 -0
  267. package/server/projects/store.js +270 -0
  268. package/server/projects/ui-config.js +54 -0
  269. package/server/projects/workspace-templates.js +53 -0
  270. package/server/projects/workspace.js +1025 -0
  271. package/server/runtime/capabilities.js +153 -0
  272. package/server/runtime/local-config.js +177 -0
  273. package/server/runtime/local-env.js +88 -0
  274. package/server/runtime/platform.js +342 -0
  275. package/server/runtime/profile.js +72 -0
  276. package/server/services/rembg-launcher.js +313 -0
  277. package/server/services/rembg-service.py +334 -0
  278. package/server/shared/README.md +25 -0
  279. package/server/shared/deck.js +54 -0
  280. package/server/shared/time.js +49 -0
  281. package/server/style-pipeline/README.md +53 -0
  282. package/server/ws/broker.js +36 -0
  283. package/server/ws/browse-channel.js +177 -0
  284. package/server/ws/index.js +386 -0
  285. package/web/README.md +89 -0
  286. package/web/dist/assets/BrowserWindow-Dc7J7CYc.js +11 -0
  287. package/web/dist/assets/DeckWindow-4G0xX7P3.js +16 -0
  288. package/web/dist/assets/DocxWindow-BXQsoPkh.js +16 -0
  289. package/web/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  290. package/web/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  291. package/web/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  292. package/web/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  293. package/web/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  294. package/web/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  295. package/web/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  296. package/web/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  297. package/web/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  298. package/web/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  299. package/web/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  300. package/web/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  301. package/web/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  302. package/web/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  303. package/web/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  304. package/web/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  305. package/web/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  306. package/web/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  307. package/web/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  308. package/web/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  309. package/web/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  310. package/web/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  311. package/web/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  312. package/web/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  313. package/web/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  314. package/web/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  315. package/web/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  316. package/web/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  317. package/web/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  318. package/web/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  319. package/web/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  320. package/web/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  321. package/web/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  322. package/web/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  323. package/web/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  324. package/web/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  325. package/web/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  326. package/web/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  327. package/web/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  328. package/web/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  329. package/web/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  330. package/web/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  331. package/web/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  332. package/web/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  333. package/web/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  334. package/web/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  335. package/web/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  336. package/web/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  337. package/web/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  338. package/web/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  339. package/web/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  340. package/web/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  341. package/web/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  342. package/web/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  343. package/web/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  344. package/web/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  345. package/web/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  346. package/web/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  347. package/web/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  348. package/web/dist/assets/SiteWindow-D6eS-2gM.js +18 -0
  349. package/web/dist/assets/again-D8tfgKKO.webp +0 -0
  350. package/web/dist/assets/caveat-nd-CP6HlsNg.woff2 +0 -0
  351. package/web/dist/assets/clock-xJhvfYpS.webp +0 -0
  352. package/web/dist/assets/film-cut-BBKMwH7q.webp +0 -0
  353. package/web/dist/assets/film-still-BZ_DL9Tt.webp +0 -0
  354. package/web/dist/assets/index-C0KUf6Wd.css +1 -0
  355. package/web/dist/assets/index-Cbl3ATvp.js +2125 -0
  356. package/web/dist/assets/ink-desk-BRbxeDsR.webp +0 -0
  357. package/web/dist/assets/ink-night-Bz4BT3XH.webp +0 -0
  358. package/web/dist/assets/ink-portrait-C0DM4V8Q.webp +0 -0
  359. package/web/dist/assets/longcang-regular-C0uvTuKa.woff2 +0 -0
  360. package/web/dist/assets/lxgw-nd-bold-DbRfiTgo.woff2 +0 -0
  361. package/web/dist/assets/lxgw-nd-regular-CpMw9Ehg.woff2 +0 -0
  362. package/web/dist/assets/pending-edit-apply-DTjo2geW.js +31 -0
  363. package/web/dist/assets/question-8H4HSqxh.webp +0 -0
  364. package/web/dist/assets/reject-BaPJqElj.webp +0 -0
  365. package/web/dist/assets/rotate-cw-LMT3x1Zj.js +11 -0
  366. package/web/dist/assets/rp-portrait-CbrGpew2.webp +0 -0
  367. package/web/dist/assets/rp-street-C4jVKjxx.webp +0 -0
  368. package/web/dist/assets/square-dashed-mouse-pointer-CBoAkfhi.js +11 -0
  369. package/web/dist/assets/tangle-DIxHVNuT.webp +0 -0
  370. package/web/dist/assets/thisone-BylZKglV.webp +0 -0
  371. package/web/dist/assets/thumb-DO1wfK1I.webp +0 -0
  372. package/web/dist/index.html +18 -0
@@ -0,0 +1,667 @@
1
+ <!--
2
+ ╔══════════════════════════════════════════════════════════════════════╗
3
+ ║ NoDesign · canvas.html starter template (Hybrid 范式 · 2026-05-08) ║
4
+ ╠══════════════════════════════════════════════════════════════════════╣
5
+ ║ ║
6
+ ║ cp 这份做起点。下面 4 块预置好的,**别动结构**: ║
7
+ ║ 1. <head> 里的 Tailwind / importmap / Babel + design-tokens ║
8
+ ║ 2. <head> base CSS 里 section[data-page] var(--deck-w/h) ║
9
+ ║ (设计稿坐标系,由 wrap data-deck-aspect 4 档决定 W×H) ║
10
+ ║ 3. body 的 .__nd-deck-wrap 包裹 + <section data-page> ║
11
+ ║ 4. <script id="__nd-shadcn-lite"> 里的 4 件 shadcn-lite 组件 ║
12
+ ║ (Card/Button/Badge/Tabs),直接 <Card> 用,不需要 import ║
13
+ ║ ║
14
+ ║ 渲染范式(系统统一处理,agent 不操心): ║
15
+ ║ · 每个 <section data-page> 写设计稿原坐标 ║
16
+ ║ · 系统给每 section 包 100vw×100vh frame + scroll-snap → ║
17
+ ║ 单页铺满屏幕;滚轮 / 键盘 ↑↓ Space PgUp/PgDn 都按页切 ║
18
+ ║ · 缩放纯 CSS min(100vw/W, 100vh/H) letterbox 居中 ║
19
+ ║ ║
20
+ ║ Deck 比例(钉锚阶段必须跟用户对齐 → 改 wrap data-deck-aspect 四选一):║
21
+ ║ "16:9" 1920×1080 默认(PPT / 演讲 / 文档) ║
22
+ ║ "16:10" 1920×1200 宽屏笔电 / Mac 屏(介于 16:9 和 4:3) ║
23
+ ║ "9:16" 1080×1920 竖屏(手机 / 短故事 / 直播 cover) ║
24
+ ║ "4:3" 1440×1080 老投影 / 经典 PPT ║
25
+ ║ 比例**只能创建时定**——版面写死针对某比例,切了版面错乱 ║
26
+ ║ ║
27
+ ║ 你要做的: ║
28
+ ║ · 改 design-tokens(颜色 / 字号 / 字体)—— 按 deck 隐喻整组覆盖 ║
29
+ ║ · 在 .__nd-deck-wrap 里写 N 个 <section data-page="N"> ║
30
+ ║ · **决定每页 layout-role 后**→ Read patterns/<role>.md 拿 reference║
31
+ ║ (image-led-cover / section-divider / portrait / quote-backdrop ║
32
+ ║ / text-led / hybrid-grid) ║
33
+ ║ · 简单页:纯 HTML + Tailwind utility class ║
34
+ ║ · 复杂页(图表 / 动画 / Tabs/Card 阵列):放 <div data-react-mount="..."> ║
35
+ ║ 然后在底部 <script id="__nd-app"> 里 createRoot mount 组件 ║
36
+ ║ ║
37
+ ║ Tweaks 桥接:可调维度(颜色/字号)用 text-[var(--accent)] 写 ║
38
+ ║ 骨架(间距/flex/radius)用 Tailwind utility 写 ║
39
+ ║ expose_tweaks 改 CSS var → arbitrary value 实时响应 ║
40
+ ║ ║
41
+ ║ Anchor 单写:关键元素只写 data-anchor(deck 内唯一,重名加 -pN 后缀) ║
42
+ ║ 不再写 data-node-id(已废) ║
43
+ ║ ║
44
+ ║ 库速查见 prelude § Hybrid 全家桶库速查 + SKILL.md § Hybrid 选型表 ║
45
+ ║ ║
46
+ ╚══════════════════════════════════════════════════════════════════════╝
47
+ -->
48
+ <!DOCTYPE html>
49
+ <html lang="zh-CN">
50
+ <head>
51
+ <meta charset="UTF-8">
52
+ <meta name="viewport" content="width=device-width, initial-scale=1">
53
+ <title>{Deck 标题 · 改我}</title>
54
+
55
+ <!-- ══ 1. Google Fonts(按需改) ══ -->
56
+ <!-- ⚠️ 字体 chain 铁律:每个 latin family 后面**必须**跟显式的 CJK family。 -->
57
+ <!-- 标准 chain 4 段:latin → 苹果 CJK → Noto CJK 兜底 → generic -->
58
+ <!-- - sans 类 → 'Inter', 'PingFang SC', 'Noto Sans SC', system-ui, sans-serif -->
59
+ <!-- - serif 类 → 'Playfair Display', 'Songti SC', 'Noto Serif SC', serif -->
60
+ <!-- - mono 类 → 'JetBrains Mono', monospace(mono 极少含中文,不配 CJK) -->
61
+ <!-- -->
62
+ <!-- 为什么 4 段而不是 3 段: -->
63
+ <!-- PingFang/Songti 是苹果字体,preview(macOS)和 server 渲染都装了,命中 -->
64
+ <!-- 它们后字体效果"原汁原味"(设计师爱的 PingFang Light 骨感)。 -->
65
+ <!-- Noto SC 是 Google Fonts inline 的兜底——用户下载 baked HTML 在 Windows/ -->
66
+ <!-- Linux 双击打开时(没装苹果字体)能命中 inline 的 Noto SC,不掉链。 -->
67
+ <!-- -->
68
+ <!-- ❌ 反例: -->
69
+ <!-- font-family: 'Playfair', serif ← 缺 CJK,跨 OS 命中不一致 -->
70
+ <!-- font-family: 'Inter', system-ui ← system-ui 跨 OS 命中不一致 -->
71
+ <link rel="preconnect" href="https://fonts.googleapis.com">
72
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
73
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&family=JetBrains+Mono:wght@400;600&family=Instrument+Serif:ital@0;1&family=Noto+Sans+SC:wght@300;400;500;700&family=Noto+Serif+SC:wght@400;600;700&display=swap" rel="stylesheet">
74
+
75
+ <!-- ══ 2. Tailwind Play CDN(运行时编译,所有 utility class 立即可用) ══ -->
76
+ <script src="https://cdn.tailwindcss.com"></script>
77
+ <script>
78
+ tailwind.config = {
79
+ theme: {
80
+ extend: {
81
+ // ⚠️ 4 段 chain:latin → 苹果 CJK(preview/server 命中)→ Noto CJK 兜底 → generic
82
+ fontFamily: {
83
+ sans: ['Inter', 'PingFang SC', 'Noto Sans SC', 'system-ui', 'sans-serif'],
84
+ mono: ['JetBrains Mono', 'monospace'],
85
+ display: ['Instrument Serif', 'Songti SC', 'Noto Serif SC', 'serif'],
86
+ },
87
+ },
88
+ },
89
+ };
90
+ </script>
91
+
92
+ <!-- ══════════════════════════════════════════════════════════════════════════════ -->
93
+ <!-- ══ 3. importmap:21 库预置 + 按 deck-kind 分组(agent import 哪个浏览器才下哪个)══ -->
94
+ <!-- -->
95
+ <!-- 按 deck-kind 选型 → SKILL.md § Hybrid 选型按 deck-kind 分流 -->
96
+ <!-- 按内容类型查("我要画图表 → recharts")→ prelude § Hybrid 全家桶库速查 -->
97
+ <!-- -->
98
+ <!-- 库分组(下方 JSON 按此顺序排列): -->
99
+ <!-- Core ............... react / react-dom(必装) -->
100
+ <!-- 数据可视化 ......... recharts / echarts -->
101
+ <!-- 适用:decision / sales / funding / data / academic -->
102
+ <!-- 动效装饰 ........... framer-motion / motion / gsap / lenis -->
103
+ <!-- 放开:emotion / launch / ceremony -->
104
+ <!-- 慎用:decision / academic / data 默认 0 motion -->
105
+ <!-- 流程公式代码 ....... mermaid / katex / react-katex / shiki -->
106
+ <!-- 适用:knowledge / academic -->
107
+ <!-- 专业组件 ........... lucide-react (icon) / embla-carousel-react (轮播) -->
108
+ <!-- reactflow (节点图) -->
109
+ <!-- Radix 组件 ......... 6 件 a11y 全功能 (要键盘导航时;inline 4 件已自带简化版) -->
110
+ <!-- 3D ................. three / r3f / drei -->
111
+ <!-- launch 类产品 hero 偶用,体积大耗 GPU 慎用 -->
112
+ <!-- ══════════════════════════════════════════════════════════════════════════════ -->
113
+ <script type="importmap">
114
+ {
115
+ "imports": {
116
+ "react": "https://esm.sh/react@19.0.0",
117
+ "react/": "https://esm.sh/react@19.0.0/",
118
+ "react-dom": "https://esm.sh/react-dom@19.0.0",
119
+ "react-dom/": "https://esm.sh/react-dom@19.0.0/",
120
+
121
+ "recharts": "https://esm.sh/recharts@2.13.3?deps=react@19.0.0,react-dom@19.0.0",
122
+ "echarts": "https://esm.sh/echarts@5.5.1",
123
+ "echarts-for-react": "https://esm.sh/echarts-for-react@3.0.2?deps=react@19.0.0,react-dom@19.0.0,echarts@5.5.1",
124
+
125
+ "framer-motion": "https://esm.sh/framer-motion@11.15.0?deps=react@19.0.0,react-dom@19.0.0",
126
+ "motion": "https://esm.sh/motion@11.15.0?deps=react@19.0.0,react-dom@19.0.0",
127
+ "gsap": "https://esm.sh/gsap@3.12.5",
128
+ "lenis": "https://esm.sh/lenis@1.1.20",
129
+
130
+ "mermaid": "https://esm.sh/mermaid@11.4.1",
131
+ "katex": "https://esm.sh/katex@0.16.11",
132
+ "react-katex": "https://esm.sh/react-katex@3.0.1?deps=react@19.0.0,katex@0.16.11",
133
+ "shiki": "https://esm.sh/shiki@1.24.4",
134
+
135
+ "lucide-react": "https://esm.sh/lucide-react@0.460.0?deps=react@19.0.0",
136
+ "embla-carousel-react": "https://esm.sh/embla-carousel-react@8.5.1?deps=react@19.0.0",
137
+ "reactflow": "https://esm.sh/reactflow@11.11.4?deps=react@19.0.0,react-dom@19.0.0",
138
+
139
+ "@radix-ui/react-dialog": "https://esm.sh/@radix-ui/react-dialog@1.1.4?deps=react@19.0.0,react-dom@19.0.0",
140
+ "@radix-ui/react-tabs": "https://esm.sh/@radix-ui/react-tabs@1.1.2?deps=react@19.0.0,react-dom@19.0.0",
141
+ "@radix-ui/react-tooltip": "https://esm.sh/@radix-ui/react-tooltip@1.1.5?deps=react@19.0.0,react-dom@19.0.0",
142
+ "@radix-ui/react-accordion": "https://esm.sh/@radix-ui/react-accordion@1.2.2?deps=react@19.0.0,react-dom@19.0.0",
143
+ "@radix-ui/react-popover": "https://esm.sh/@radix-ui/react-popover@1.1.4?deps=react@19.0.0,react-dom@19.0.0",
144
+ "@radix-ui/react-scroll-area":"https://esm.sh/@radix-ui/react-scroll-area@1.2.2?deps=react@19.0.0,react-dom@19.0.0",
145
+
146
+ "three": "https://esm.sh/three@0.171.0",
147
+ "@react-three/fiber": "https://esm.sh/@react-three/fiber@8.17.10?deps=react@19.0.0,react-dom@19.0.0,three@0.171.0",
148
+ "@react-three/drei": "https://esm.sh/@react-three/drei@9.121.4?deps=react@19.0.0,react-dom@19.0.0,three@0.171.0,@react-three/fiber@8.17.10"
149
+ }
150
+ }
151
+ </script>
152
+
153
+ <!-- ══ 4. Babel Standalone:浏览器内编译 TSX ══ -->
154
+ <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
155
+
156
+ <!-- ══ 5. Design tokens —— **可调维度全在这里**,agent 改这里、Tweaks 暴露这里 ══ -->
157
+ <!-- ┄┄┄ 下面这套 token 值是 fallback,主题对齐后**应主动按隐喻覆盖**: ┄┄┄ -->
158
+ <!-- ┄┄┄ · Scientific Witchery → 暗紫 / 公式 mono / 旧纸纹 ┄┄┄ -->
159
+ <!-- ┄┄┄ · Cyberpunk → 霓虹 / 等宽数字 / 玻璃拟态 ┄┄┄ -->
160
+ <!-- ┄┄┄ · Wabi-sabi → 米黄 / 手写字 / 大量留白 ┄┄┄ -->
161
+ <!-- ┄┄┄ 直接套用预置 = 5 deck 出来都长一样的 AI default。每份 deck 的 token ┄┄┄ -->
162
+ <!-- ┄┄┄ 应该被它的隐喻穿透,把整组 --bg / --ink / --accent / --muted 重写。┄┄┄ -->
163
+ <style id="design-tokens">
164
+ :root {
165
+ /* === Color (fallback values — override per theme) === */
166
+ --bg: #F9F8F6;
167
+ --paper: #F9F8F6;
168
+ --surface: #ffffff;
169
+ --ink: #1a120a;
170
+ --accent: #2d2418;
171
+ --muted: #6b5d4f;
172
+ --cream: #efe8df;
173
+
174
+ /* === Type scale === */
175
+ --hero: 112px;
176
+ --h1: 72px;
177
+ --h2: 48px;
178
+ --h3: 32px;
179
+ --body: 18px;
180
+ --caption: 13px;
181
+
182
+ /* === Spacing (8pt grid) === */
183
+ --gap-xs: 8px;
184
+ --gap-sm: 16px;
185
+ --gap-md: 24px;
186
+ --gap-lg: 48px;
187
+ --gap-xl: 96px;
188
+
189
+ /* === Generated image slots === */
190
+ --hero-image: none;
191
+ --bg-image-1: none;
192
+ --bg-image-2: none;
193
+ --bg-image-3: none;
194
+ --decoration-1: none;
195
+ --frame-1: none;
196
+ --pattern-tile: none;
197
+ }
198
+
199
+ /* per-page / per-layout scoped overrides 跟 expose_tweaks(target_scope) 配对 */
200
+ /* section[data-page="1"] { --hero: 140px; } ← 封面字更大 */
201
+ /* [data-layout="quote"] { --body: 24px; } ← 引言页正文更大 */
202
+ </style>
203
+
204
+ <!-- ══ 6. Base —— **不要动**,跟系统注入 fit script 共契约 className ══ -->
205
+ <style id="base">
206
+ * { box-sizing: border-box; margin: 0; padding: 0; }
207
+ body {
208
+ font-family: Inter, 'PingFang SC', 'Noto Sans SC', system-ui, sans-serif;
209
+ color: var(--ink);
210
+ background: var(--bg);
211
+ -webkit-font-smoothing: antialiased;
212
+ }
213
+
214
+ /* section 尺寸跟随 wrap data-deck-aspect 派发的 CSS var;不声明 = 16:9 默认 */
215
+ section[data-page] {
216
+ width: var(--deck-w, 1920px);
217
+ height: var(--deck-h, 1080px);
218
+ position: relative;
219
+ overflow: hidden;
220
+ page-break-after: always;
221
+ }
222
+ </style>
223
+
224
+ <!-- ══ 7. Page-styles —— 页内细化样式(per-page 重写 token / 个别页 layout 微调) ══ -->
225
+ <style id="page-styles">
226
+ /* 例:page 3 数字超大字 */
227
+ /* section[data-page="3"] .stat-num { font-family: var(--font-display); font-size: 200px; } */
228
+ </style>
229
+ </head>
230
+
231
+ <body>
232
+
233
+ <!-- ════════════════════════════════════════════════════════════ -->
234
+ <!-- 所有 section 必须放在 .__nd-deck-wrap 里。 -->
235
+ <!-- -->
236
+ <!-- 渲染范式(系统统一): -->
237
+ <!-- · 每个 <section data-page="N"> 写设计稿原坐标 -->
238
+ <!-- · 系统在 preview / 导出 / 离线打开时自动给每 section 包 -->
239
+ <!-- 100vw×100vh frame + scroll-snap → 单页铺满屏幕 -->
240
+ <!-- 滚轮一次切一整页 / 键盘 ↑↓ Space PgUp/PgDn 也按页切 -->
241
+ <!-- · 缩放 CSS min(100vw/W, 100vh/H) letterbox 居中 -->
242
+ <!-- -->
243
+ <!-- deck 比例 data-deck-aspect 四档(**钉锚阶段必须跟用户对齐**): -->
244
+ <!-- "16:9" 1920×1080 默认(PPT / 演讲 / 文档 / scrollytelling) -->
245
+ <!-- "16:10" 1920×1200 宽屏笔电 / Mac 屏(多一点垂直空间) -->
246
+ <!-- "9:16" 1080×1920 竖屏(手机宣发 / 短故事 / 直播 cover) -->
247
+ <!-- "4:3" 1440×1080 老投影 / 经典 PPT 投影仪适配 -->
248
+ <!-- -->
249
+ <!-- 漏写 = 默认 16:9。比例**只能在 deck 创建时定**,不能导出时切—— -->
250
+ <!-- 因为 layout 写死针对某个比例,切了就版面错乱。 -->
251
+ <!-- ════════════════════════════════════════════════════════════ -->
252
+ <div class="__nd-deck-wrap" data-deck-aspect="16:9">
253
+
254
+ <!-- ══════════════════════════════════════════════════════════ -->
255
+ <!-- PAGE 1 · COVER (text-led 范例) -->
256
+ <!-- · 这是最简 cover 起手骨架;image-led / 其他 layout-role -->
257
+ <!-- **必 Read patterns/<role>.md** 拿专属 reference -->
258
+ <!-- · DirectEdit 双击文字可改 -->
259
+ <!-- · 颜色用 text-[var(--xxx)],骨架用 Tailwind utility -->
260
+ <!-- · Anchor 单写:data-anchor 唯一,不写 data-node-id -->
261
+ <!-- ══════════════════════════════════════════════════════════ -->
262
+ <section data-page="1" data-anchor="cover" data-layout="cover"
263
+ data-layout-role="text-led" class="bg-[var(--paper)]">
264
+ <div class="h-full flex flex-col justify-between p-32">
265
+ <div class="font-mono text-sm tracking-[0.3em] uppercase text-[var(--muted)]">
266
+ {Section · 改我}
267
+ </div>
268
+
269
+ <div class="flex flex-col gap-8">
270
+ <h1 data-anchor="cover-title"
271
+ class="font-display text-[var(--ink)] leading-[0.95]"
272
+ style="font-size: var(--hero); letter-spacing: -0.04em;">
273
+ {封面标题 · 改我}
274
+ </h1>
275
+ <p data-anchor="cover-sub"
276
+ class="text-2xl text-[var(--muted)] max-w-3xl leading-relaxed"
277
+ style="font-family: 'Instrument Serif', 'Songti SC', 'Noto Serif SC', serif; font-style: italic;">
278
+ {副标题 · 一句话讲清这个 deck 是什么 · 改我}
279
+ </p>
280
+ </div>
281
+
282
+ <div class="flex justify-between items-end font-mono text-xs uppercase tracking-widest text-[var(--muted)]">
283
+ <span>{author · date}</span>
284
+ <span>01 / N</span>
285
+ </div>
286
+ </div>
287
+ </section>
288
+
289
+ <!-- ══════════════════════════════════════════════════════════ -->
290
+ <!-- 6 个 page-type 范例已搬到 patterns/ 目录(按需 Read) -->
291
+ <!-- -->
292
+ <!-- 决定每页 layout-role 后立即 Read 对应 patterns/*.md: -->
293
+ <!-- image-led 封面 / 大 hero → patterns/image-led-cover.md -->
294
+ <!-- image-led 章节扉页 → patterns/section-divider.md -->
295
+ <!-- image-led 人物 / quote → patterns/portrait.md / quote-backdrop.md -->
296
+ <!-- text-led 文为主页 → patterns/text-led.md -->
297
+ <!-- hybrid 图文 grid / Card 阵列 → patterns/hybrid-grid.md -->
298
+ <!-- -->
299
+ <!-- 每个 patterns/ 文件含:何时用 / 标记规约 / 写法铁律 / 最小代码片段 -->
300
+ <!-- 别照抄当 final layout —— patterns/ 是 reference,按你 deck 的隐喻填 -->
301
+ <!-- ══════════════════════════════════════════════════════════ -->
302
+
303
+ <!-- ══════════════════════════════════════════════════════════ -->
304
+ <!-- ⚡ 骨架范例(Phase A · ≤ 400 行起步用) -->
305
+ <!-- 多页 deck 或预估 > 400 行的复杂单页:先把每页 section 写成空骨架 -->
306
+ <!-- 整文件 ≤ 400 行 → expose_tweaks 一次 → 逐页 Edit 填充 -->
307
+ <!-- 详见 SKILL.md § 二、展开 起手式 -->
308
+ <!-- ══════════════════════════════════════════════════════════ -->
309
+
310
+ <!-- ┄┄┄ 骨架 section 范例(cp 改 N 份,N = 你 plan 的页数) ┄┄┄
311
+ <section data-page="1" data-layout-role="image-led" data-layout="cover"
312
+ data-anchor="cover" data-skeleton="cover-hero">
313
+ <div class="h-full flex items-center justify-center bg-[var(--ink)]/5
314
+ text-[var(--muted)] font-mono text-sm tracking-widest">
315
+ PAGE 1 · cover-hero · WIP
316
+ </div>
317
+ </section>
318
+ ┄┄┄ -->
319
+
320
+ <!-- ┄┄┄ React mount 占位(在底部 <script id="__nd-app"> 里)┄┄┄
321
+ // §mount:2 · data-led page 2 chart component 待填
322
+ ┄┄┄ -->
323
+
324
+ <!-- ══════════════════════════════════════════════════════════ -->
325
+ <!-- PAGE 2 · React mount section 范例 -->
326
+ <!-- · 复杂图表/动画/组件用 React mount -->
327
+ <!-- · 必须 <div data-react-mount="..."> 包裹(DirectEdit guard)-->
328
+ <!-- · mount 实现写在底部 <script id="__nd-app"> 里 -->
329
+ <!-- ══════════════════════════════════════════════════════════ -->
330
+ <section data-page="2" data-anchor="example-mount" data-layout="data"
331
+ data-layout-role="data-led" class="bg-[var(--cream)]">
332
+ <div class="h-full flex flex-col p-24">
333
+ <header class="mb-12 pb-8 border-b border-[var(--ink)]/10">
334
+ <div class="font-mono text-xs uppercase tracking-[0.3em] text-[var(--muted)] mb-2">
335
+ Section · React mount example
336
+ </div>
337
+ <h2 data-anchor="example-mount-title"
338
+ class="font-display text-[var(--ink)]"
339
+ style="font-size: var(--h1); letter-spacing: -0.02em; line-height: 1;">
340
+ {改成你的 page 标题}
341
+ </h2>
342
+ </header>
343
+
344
+ <!-- React mount point ↓ —— DirectEdit 不会挂这里面(guard by data-react-mount) -->
345
+ <div data-react-mount="example-chart" id="example-chart-mount" class="flex-1"></div>
346
+ </div>
347
+ </section>
348
+
349
+ <!-- ══════════════════════════════════════════════════════════ -->
350
+ <!-- PAGE N · CLOSING —— 静态 + 优雅落幕 -->
351
+ <!-- ══════════════════════════════════════════════════════════ -->
352
+ <section data-page="3" data-anchor="closing" data-layout="closing"
353
+ data-layout-role="text-led" class="bg-[var(--ink)] text-[var(--paper)]">
354
+ <div class="h-full flex flex-col justify-center items-center text-center p-32">
355
+ <div class="font-mono text-xs uppercase tracking-[0.4em] text-[var(--paper)]/50 mb-8">
356
+ — Fin —
357
+ </div>
358
+ <h2 data-anchor="closing-title"
359
+ class="font-display"
360
+ style="font-size: var(--h1); line-height: 0.95; letter-spacing: -0.04em; font-style: italic;">
361
+ {收尾一句话 · 改我}
362
+ </h2>
363
+ <p class="mt-8 text-xl text-[var(--paper)]/70 max-w-3xl"
364
+ style="font-family: 'Instrument Serif', 'Songti SC', 'Noto Serif SC', serif;">
365
+ {补充信息 · 改我}
366
+ </p>
367
+ </div>
368
+ </section>
369
+
370
+ </div>
371
+
372
+ <!-- ══════════════════════════════════════════════════════════════ -->
373
+ <!-- 4 件 inline shadcn-lite 组件 —— 直接 <Card> 用,不需要 import -->
374
+ <!-- 适用场景:comparison-table / feature-cards / use-cases / -->
375
+ <!-- variant-showcase / step-switcher / quadrant 等 -->
376
+ <!-- 详见 SKILL.md § Hybrid 选型表(decision/sales/launch/knowledge) -->
377
+ <!-- 要 a11y / 全功能 → import @radix-ui/react-* 自己组(importmap 已就位)-->
378
+ <!-- ══════════════════════════════════════════════════════════════ -->
379
+ <script type="text/babel" id="__nd-shadcn-lite" data-type="module" data-presets="react,typescript" data-nodesign-keep="components">
380
+ import React, { useState } from 'react';
381
+
382
+ function Card({ children, className = '', ...rest }) {
383
+ return (
384
+ <div className={`rounded-xl border border-[var(--ink)]/10 bg-[var(--surface)] shadow-sm ${className}`} {...rest}>
385
+ {children}
386
+ </div>
387
+ );
388
+ }
389
+ function CardHeader({ children, className = '' }) {
390
+ return <div className={`flex flex-col gap-1.5 p-6 ${className}`}>{children}</div>;
391
+ }
392
+ function CardTitle({ children, className = '' }) {
393
+ return <h3 className={`font-semibold text-2xl leading-none text-[var(--ink)] ${className}`}>{children}</h3>;
394
+ }
395
+ function CardContent({ children, className = '' }) {
396
+ return <div className={`p-6 pt-0 ${className}`}>{children}</div>;
397
+ }
398
+
399
+ function Button({ variant = 'default', children, className = '', ...rest }) {
400
+ const base = 'inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium px-4 py-2 transition-colors';
401
+ const variants = {
402
+ default: 'bg-[var(--accent)] text-[var(--paper)] hover:opacity-90',
403
+ outline: 'border border-[var(--ink)]/20 bg-transparent text-[var(--ink)] hover:bg-[var(--ink)]/5',
404
+ ghost: 'bg-transparent text-[var(--ink)] hover:bg-[var(--ink)]/5',
405
+ };
406
+ return (
407
+ <button className={`${base} ${variants[variant] || variants.default} ${className}`} {...rest}>
408
+ {children}
409
+ </button>
410
+ );
411
+ }
412
+
413
+ function Badge({ variant = 'default', children, className = '' }) {
414
+ const variants = {
415
+ default: 'bg-[var(--accent)] text-[var(--paper)]',
416
+ secondary: 'bg-[var(--ink)]/10 text-[var(--ink)]',
417
+ outline: 'border border-[var(--ink)]/20 text-[var(--ink)]',
418
+ };
419
+ return (
420
+ <span className={`inline-flex items-center rounded-full px-3 py-1 text-xs font-medium ${variants[variant] || variants.default} ${className}`}>
421
+ {children}
422
+ </span>
423
+ );
424
+ }
425
+
426
+ // 受控/非受控两用 Tabs(不依赖 Radix;要 a11y 就 import @radix-ui/react-tabs)
427
+ function Tabs({ defaultValue, value, onValueChange, children, className = '' }) {
428
+ const [internal, setInternal] = useState(defaultValue);
429
+ const active = value !== undefined ? value : internal;
430
+ const setActive = (v) => { onValueChange ? onValueChange(v) : setInternal(v); };
431
+ return (
432
+ <div className={className}>
433
+ {React.Children.map(children, (child) =>
434
+ React.isValidElement(child) ? React.cloneElement(child, { active, setActive }) : child
435
+ )}
436
+ </div>
437
+ );
438
+ }
439
+ function TabsList({ children, active, setActive, className = '' }) {
440
+ return (
441
+ <div className={`inline-flex items-center justify-center rounded-md bg-[var(--ink)]/5 p-1 ${className}`}>
442
+ {React.Children.map(children, (child) =>
443
+ React.isValidElement(child) ? React.cloneElement(child, { active, setActive }) : child
444
+ )}
445
+ </div>
446
+ );
447
+ }
448
+ function TabsTrigger({ value, active, setActive, children, className = '' }) {
449
+ const isActive = active === value;
450
+ return (
451
+ <button onClick={() => setActive(value)}
452
+ className={`px-4 py-2 text-sm font-medium rounded transition-colors ${
453
+ isActive
454
+ ? 'bg-[var(--surface)] shadow-sm text-[var(--ink)]'
455
+ : 'text-[var(--muted)] hover:text-[var(--ink)]'
456
+ } ${className}`}>
457
+ {children}
458
+ </button>
459
+ );
460
+ }
461
+ function TabsContent({ value, active, children, className = '' }) {
462
+ if (active !== value) return null;
463
+ return <div className={className}>{children}</div>;
464
+ }
465
+
466
+ // 暴露到全局供下方 __nd-app 段使用
467
+ window.__ndShadcn = { Card, CardHeader, CardTitle, CardContent, Button, Badge, Tabs, TabsList, TabsTrigger, TabsContent };
468
+ </script>
469
+
470
+ <!-- ══════════════════════════════════════════════════════════════ -->
471
+ <!-- 应用入口 —— 复杂页 React mount 的 createRoot 都写这里 -->
472
+ <!-- 上方 __nd-shadcn-lite 已暴露 window.__ndShadcn 供本段使用 -->
473
+ <!-- ══════════════════════════════════════════════════════════════ -->
474
+ <script type="text/babel" id="__nd-app" data-type="module" data-presets="react,typescript">
475
+ import React, { useState, useEffect } from 'react';
476
+ import { createRoot } from 'react-dom/client';
477
+
478
+ // 范例 mount:Recharts 折线图(按需改 / 删 / 加)
479
+ import { LineChart, Line, ResponsiveContainer, XAxis, YAxis, CartesianGrid, Tooltip } from 'recharts';
480
+
481
+ // 4 件 shadcn-lite 组件(上方 __nd-shadcn-lite 段定义并暴露 window.__ndShadcn)
482
+ // 这里全 destructure 一次让 agent 写新 mount 时直接 <Card> / <Tabs> 就能用,0 friction
483
+ const { Card, CardHeader, CardTitle, CardContent, Button, Badge, Tabs, TabsList, TabsTrigger, TabsContent } = window.__ndShadcn;
484
+
485
+ function ExampleChart() {
486
+ const data = [
487
+ { x: 'Mon', y: 30 }, { x: 'Tue', y: 45 }, { x: 'Wed', y: 38 },
488
+ { x: 'Thu', y: 62 }, { x: 'Fri', y: 78 }, { x: 'Sat', y: 95 }, { x: 'Sun', y: 110 },
489
+ ];
490
+ return (
491
+ <Card className="h-full p-8 flex flex-col">
492
+ <CardTitle className="mb-6">改成你的图表标题</CardTitle>
493
+ <div className="flex-1 min-h-0">
494
+ <ResponsiveContainer width="100%" height="100%">
495
+ <LineChart data={data} margin={{ top: 10, right: 10, bottom: 0, left: 0 }}>
496
+ <CartesianGrid strokeDasharray="3 3" stroke="var(--ink)" opacity={0.06} vertical={false} />
497
+ <XAxis dataKey="x" stroke="var(--muted)" fontSize={12} tickLine={false} axisLine={false} />
498
+ <YAxis stroke="var(--muted)" fontSize={12} tickLine={false} axisLine={false} />
499
+ <Tooltip contentStyle={{ borderRadius: 8, border: '1px solid rgba(0,0,0,0.08)', fontFamily: 'JetBrains Mono', fontSize: 12 }} />
500
+ <Line dataKey="y" stroke="var(--accent)" strokeWidth={2.5} dot={false} />
501
+ </LineChart>
502
+ </ResponsiveContainer>
503
+ </div>
504
+ </Card>
505
+ );
506
+ }
507
+
508
+ const exampleEl = document.getElementById('example-chart-mount');
509
+ if (exampleEl) createRoot(exampleEl).render(<ExampleChart />);
510
+
511
+ // 加你自己的 mount:
512
+ // const myEl = document.getElementById('my-mount');
513
+ // if (myEl) createRoot(myEl).render(<MyComponent />);
514
+ </script>
515
+
516
+ <!-- ══════════════════════════════════════════════════════════════ -->
517
+ <!-- Keyboard nav: ←↑/PgUp = prev, →↓/Space/PgDn = next, Home/End -->
518
+ <!-- 滚轮按页切由系统 fit script 注的 scroll-snap-y mandatory 自动处理 -->
519
+ <!-- 这里只补键盘 + 父窗口 postMessage 同步当前页号 -->
520
+ <!-- 多页才装;单页 deck 自动 noop -->
521
+ <!-- data-nodesign-keep 让 build-standalone postprocess 永不删此脚本 -->
522
+ <!-- ══════════════════════════════════════════════════════════════ -->
523
+ <script data-nodesign-keep="navigation">
524
+ (function(){
525
+ var sections = Array.prototype.slice.call(
526
+ document.querySelectorAll('section[data-page]')
527
+ );
528
+ if (sections.length < 2) return;
529
+
530
+ sections.sort(function(a, b){
531
+ return (parseInt(a.dataset.page, 10) || 0) - (parseInt(b.dataset.page, 10) || 0);
532
+ });
533
+
534
+ var current = 0;
535
+
536
+ function go(i){
537
+ if (i < 0) i = 0;
538
+ if (i >= sections.length) i = sections.length - 1;
539
+ if (i === current) return;
540
+ current = i;
541
+ sections[i].scrollIntoView({ behavior: 'smooth', block: 'start' });
542
+ var page = parseInt(sections[i].dataset.page, 10) || (i + 1);
543
+ try {
544
+ window.parent.postMessage({ type: 'canvas-page-change', page: page }, '*');
545
+ } catch (e) { /* parent 不可达时无声 */ }
546
+ }
547
+
548
+ document.addEventListener('keydown', function(e){
549
+ var t = e.target;
550
+ if (t && (t.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName))) return;
551
+ switch (e.key) {
552
+ case 'ArrowLeft':
553
+ case 'ArrowUp':
554
+ case 'PageUp':
555
+ e.preventDefault(); go(current - 1); break;
556
+ case 'ArrowRight':
557
+ case 'ArrowDown':
558
+ case 'PageDown':
559
+ case ' ':
560
+ case 'Spacebar':
561
+ e.preventDefault(); go(current + 1); break;
562
+ case 'Home':
563
+ e.preventDefault(); go(0); break;
564
+ case 'End':
565
+ e.preventDefault(); go(sections.length - 1); break;
566
+ }
567
+ });
568
+
569
+ if ('IntersectionObserver' in window) {
570
+ var io = new IntersectionObserver(function(entries){
571
+ var best = null;
572
+ entries.forEach(function(en){
573
+ if (!best || en.intersectionRatio > best.intersectionRatio) best = en;
574
+ });
575
+ if (best && best.isIntersecting) {
576
+ var idx = sections.indexOf(best.target);
577
+ if (idx >= 0 && idx !== current) {
578
+ current = idx;
579
+ var page = parseInt(best.target.dataset.page, 10) || (idx + 1);
580
+ try {
581
+ window.parent.postMessage({ type: 'canvas-page-change', page: page }, '*');
582
+ } catch (e) { /* ignore */ }
583
+ }
584
+ }
585
+ }, { threshold: [0.5] });
586
+ sections.forEach(function(s){ io.observe(s); });
587
+ }
588
+
589
+ window.addEventListener('message', function(ev){
590
+ if (!ev.data || ev.data.type !== 'canvas-go-page') return;
591
+ var target = parseInt(ev.data.page, 10);
592
+ if (!isFinite(target)) return;
593
+ var idx = sections.findIndex(function(s){
594
+ return (parseInt(s.dataset.page, 10) || 0) === target;
595
+ });
596
+ if (idx >= 0) go(idx);
597
+ });
598
+ })();
599
+ </script>
600
+
601
+ <!-- ══════════════════════════════════════════════════════════════ -->
602
+ <!-- 演讲模式(presenter mode) -->
603
+ <!-- -->
604
+ <!-- 默认已经有的(别重写、别移除 data-nodesign-keep): -->
605
+ <!-- • 键盘翻页 ←↑/PgUp / →↓/Space/PgDn / Home/End(上面那段) -->
606
+ <!-- • F 键 fullscreen 切换(系统 fit script 注入,自带 ESC 退出) -->
607
+ <!-- • 滚动条隐藏(系统 fit style 注入) -->
608
+ <!-- -->
609
+ <!-- letterbox 边框填充色(画布比例 ≠ 屏幕比例时两侧 / 上下的填色): -->
610
+ <!-- 默认继承 deck 主背景 var(--bg),无 --bg 时兜底黑色。 -->
611
+ <!-- 想定制就在你的 :root / theme CSS 里加: -->
612
+ <!-- --nd-letterbox-bg: #000; /* 投影标准黑边 */ -->
613
+ <!-- --nd-letterbox-bg: transparent; /* 透明(让父级容器透出)*/ -->
614
+ <!-- --nd-letterbox-bg: var(--brand-dark); /* 品牌色 */ -->
615
+ <!-- 按 deck 主调选——暗色 deck 用黑边沉浸,浅色 deck 用白/品牌色。 -->
616
+ <!-- -->
617
+ <!-- 下面是可选增强 snippet。觉得演讲场景需要就把对应 <script> -->
618
+ <!-- 解开注释;不需要就保留为注释(HTML 注释不执行也不污染)。 -->
619
+ <!-- 不强求都加。一般 16:9 投影 + 默认能力已经够用。 -->
620
+ <!-- ══════════════════════════════════════════════════════════════ -->
621
+
622
+ <!-- 可选 1: 页码角标("03 / 08" 右下角,跟随当前页号自动更新)
623
+ <script data-nodesign-keep="page-indicator">
624
+ (function(){
625
+ var sections = Array.prototype.slice.call(document.querySelectorAll('section[data-page]'));
626
+ if (sections.length < 2) return;
627
+ var total = sections.length;
628
+ var el = document.createElement('div');
629
+ el.id = '__nd-page-indicator';
630
+ el.style.cssText = 'position:fixed;right:24px;bottom:20px;z-index:9999;'
631
+ + 'font:500 13px/1 ui-monospace,Menlo,monospace;letter-spacing:0.08em;'
632
+ + 'color:rgba(255,255,255,0.6);mix-blend-mode:difference;'
633
+ + 'padding:6px 10px;pointer-events:none;user-select:none;';
634
+ el.textContent = '01 / ' + String(total).padStart(2, '0');
635
+ document.body.appendChild(el);
636
+ function pad(n){ return String(n).padStart(2, '0'); }
637
+ window.addEventListener('message', function(ev){
638
+ if (ev.data && ev.data.type === 'canvas-page-change') {
639
+ el.textContent = pad(ev.data.page) + ' / ' + pad(total);
640
+ }
641
+ });
642
+ })();
643
+ </script>
644
+ -->
645
+
646
+ <!-- 可选 2: idle 隐藏鼠标(3s 不动鼠标自动消失,移动 / 翻页恢复)
647
+ <script data-nodesign-keep="idle-cursor">
648
+ (function(){
649
+ var timer = null;
650
+ var hidden = false;
651
+ function show(){
652
+ if (hidden) { document.body.style.cursor = ''; hidden = false; }
653
+ if (timer) clearTimeout(timer);
654
+ timer = setTimeout(function(){
655
+ document.body.style.cursor = 'none';
656
+ hidden = true;
657
+ }, 3000);
658
+ }
659
+ document.addEventListener('mousemove', show, { passive: true });
660
+ document.addEventListener('keydown', show);
661
+ show();
662
+ })();
663
+ </script>
664
+ -->
665
+
666
+ </body>
667
+ </html>