@design-ai/cli 4.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (529) hide show
  1. package/.claude-plugin/plugin.json +164 -0
  2. package/AGENTS.ko.md +126 -0
  3. package/AGENTS.md +182 -0
  4. package/CHANGELOG.md +6883 -0
  5. package/CLAUDE.md +39 -0
  6. package/LICENSE +21 -0
  7. package/README.ko.md +245 -0
  8. package/README.md +277 -0
  9. package/agents/README.md +14 -0
  10. package/agents/a11y-reviewer.md +121 -0
  11. package/agents/component-architect.md +57 -0
  12. package/agents/design-critic.md +46 -0
  13. package/agents/token-extractor.md +63 -0
  14. package/cli/bin/design-ai-mcp.mjs +6 -0
  15. package/cli/bin/design-ai.mjs +40 -0
  16. package/cli/commands/audit.mjs +111 -0
  17. package/cli/commands/check.mjs +226 -0
  18. package/cli/commands/doctor.mjs +141 -0
  19. package/cli/commands/examples.mjs +58 -0
  20. package/cli/commands/help.mjs +271 -0
  21. package/cli/commands/install.mjs +161 -0
  22. package/cli/commands/learn.mjs +1871 -0
  23. package/cli/commands/list.mjs +143 -0
  24. package/cli/commands/mcp.mjs +27 -0
  25. package/cli/commands/pack.mjs +211 -0
  26. package/cli/commands/prompt.mjs +199 -0
  27. package/cli/commands/route.mjs +247 -0
  28. package/cli/commands/search.mjs +60 -0
  29. package/cli/commands/show.mjs +52 -0
  30. package/cli/commands/site.mjs +558 -0
  31. package/cli/commands/status.mjs +161 -0
  32. package/cli/commands/uninstall.mjs +119 -0
  33. package/cli/commands/update.mjs +184 -0
  34. package/cli/commands/version.mjs +94 -0
  35. package/cli/commands/workspace.mjs +176 -0
  36. package/cli/lib/brief.mjs +52 -0
  37. package/cli/lib/check.mjs +642 -0
  38. package/cli/lib/dispatch.mjs +109 -0
  39. package/cli/lib/doctor.mjs +505 -0
  40. package/cli/lib/examples.mjs +258 -0
  41. package/cli/lib/exec.mjs +63 -0
  42. package/cli/lib/help-flags.mjs +5 -0
  43. package/cli/lib/learn.mjs +3694 -0
  44. package/cli/lib/log.mjs +47 -0
  45. package/cli/lib/mcp-server.mjs +426 -0
  46. package/cli/lib/output.mjs +101 -0
  47. package/cli/lib/pack.mjs +599 -0
  48. package/cli/lib/paths.mjs +63 -0
  49. package/cli/lib/prompt.mjs +603 -0
  50. package/cli/lib/route.mjs +740 -0
  51. package/cli/lib/search.mjs +158 -0
  52. package/cli/lib/show.mjs +161 -0
  53. package/cli/lib/signals.mjs +2337 -0
  54. package/cli/lib/site.mjs +6617 -0
  55. package/cli/lib/skill-proposals.mjs +2046 -0
  56. package/cli/lib/suggest.mjs +66 -0
  57. package/cli/lib/workspace.mjs +1056 -0
  58. package/commands/README.md +25 -0
  59. package/commands/component-spec.md +34 -0
  60. package/commands/conversational.md +44 -0
  61. package/commands/design-from-brief.md +141 -0
  62. package/commands/design-review.md +62 -0
  63. package/commands/document-from-brief.md +47 -0
  64. package/commands/extract-tokens.md +38 -0
  65. package/commands/game-ui.md +40 -0
  66. package/commands/illustration.md +37 -0
  67. package/commands/iterate.md +167 -0
  68. package/commands/motion-design.md +54 -0
  69. package/commands/palette-from-brand.md +50 -0
  70. package/commands/print.md +49 -0
  71. package/commands/slide-deck.md +46 -0
  72. package/commands/spatial.md +47 -0
  73. package/commands/stability-review.md +74 -0
  74. package/commands/video.md +42 -0
  75. package/commands/website-improvement.md +77 -0
  76. package/docs/AGENT-DEVELOPMENT.md +658 -0
  77. package/docs/AI-LEARNING.md +429 -0
  78. package/docs/AIDER-INTEGRATION.md +224 -0
  79. package/docs/ARCHITECTURE.ko.md +183 -0
  80. package/docs/ARCHITECTURE.md +105 -0
  81. package/docs/CODEX-INTEGRATION.md +311 -0
  82. package/docs/COMPANY-WEBSITE-DOGFOOD.ko.md +144 -0
  83. package/docs/COMPANY-WEBSITE-DOGFOOD.md +150 -0
  84. package/docs/COMPANY-WEBSITE-INTAKE-TEMPLATE.ko.md +153 -0
  85. package/docs/COMPANY-WEBSITE-INTAKE-TEMPLATE.md +154 -0
  86. package/docs/CONTRIBUTING.ko.md +203 -0
  87. package/docs/CONTRIBUTING.md +242 -0
  88. package/docs/CURSOR-INTEGRATION.md +220 -0
  89. package/docs/DISTRIBUTION.ko.md +248 -0
  90. package/docs/DISTRIBUTION.md +253 -0
  91. package/docs/DOGFOOD-FINDINGS.md +180 -0
  92. package/docs/DOGFOOD-V4-FINDINGS.md +139 -0
  93. package/docs/DOGFOOD-V4-MKDOCS-FINDINGS.md +233 -0
  94. package/docs/DOGFOOD-V4-NPM-FINDINGS.md +157 -0
  95. package/docs/DOGFOOD-V4-VSCODE-FINDINGS.md +135 -0
  96. package/docs/FIGMA-INTEGRATION.md +222 -0
  97. package/docs/MCP-INTEGRATION.md +243 -0
  98. package/docs/MIGRATION-v4.md +121 -0
  99. package/docs/PLUGIN-PACKAGING.md +240 -0
  100. package/docs/PRODUCT-READINESS.md +66 -0
  101. package/docs/QUICKSTART.ko.md +178 -0
  102. package/docs/QUICKSTART.md +179 -0
  103. package/docs/RELEASE-CHECKLIST.md +292 -0
  104. package/docs/ROADMAP.md +19495 -0
  105. package/docs/SESSION-LOG.md +940 -0
  106. package/docs/TOKEN-SYNC.md +237 -0
  107. package/docs/USING.ko.md +206 -0
  108. package/docs/USING.md +218 -0
  109. package/docs/WEBSITE-IMPROVEMENT.ko.md +75 -0
  110. package/docs/WEBSITE-IMPROVEMENT.md +89 -0
  111. package/docs/announcements/README.md +56 -0
  112. package/docs/announcements/dev-to-korea.md +206 -0
  113. package/docs/announcements/hashnode-post.ko.md +232 -0
  114. package/docs/announcements/okky-post.ko.md +158 -0
  115. package/docs/announcements/press-kit.md +101 -0
  116. package/docs/announcements/reddit-r-korea.md +196 -0
  117. package/docs/announcements/show-hn.md +114 -0
  118. package/docs/announcements/twitter-thread.md +255 -0
  119. package/docs/external-status.md +34 -0
  120. package/docs/integrations/aider-walkthrough.ko.md +275 -0
  121. package/docs/integrations/aider-walkthrough.md +274 -0
  122. package/docs/integrations/codex-walkthrough.ko.md +297 -0
  123. package/docs/integrations/codex-walkthrough.md +297 -0
  124. package/docs/integrations/cursor-walkthrough.ko.md +281 -0
  125. package/docs/integrations/cursor-walkthrough.md +284 -0
  126. package/docs/integrations/design-ai-mcp-server.md +169 -0
  127. package/docs/integrations/figma-mcp.md +149 -0
  128. package/docs/integrations/github-mcp.md +178 -0
  129. package/docs/integrations/linear-mcp.md +215 -0
  130. package/docs/integrations/notion-mcp.md +174 -0
  131. package/docs/integrations/sdk-walkthrough.ko.md +375 -0
  132. package/docs/integrations/sdk-walkthrough.md +375 -0
  133. package/docs/integrations/slack-mcp.md +208 -0
  134. package/docs/integrations/vscode-walkthrough.ko.md +202 -0
  135. package/docs/integrations/vscode-walkthrough.md +205 -0
  136. package/docs/requirements.txt +16 -0
  137. package/docs/site-overrides/extra.css +83 -0
  138. package/docs/site-overrides/favicon.svg +4 -0
  139. package/docs/site-overrides/logo.svg +10 -0
  140. package/docs/site-overrides/main.html +18 -0
  141. package/docs/website-console/app.js +2540 -0
  142. package/docs/website-console/index.html +24 -0
  143. package/docs/website-console/styles.css +975 -0
  144. package/examples/README.md +252 -0
  145. package/examples/cases/dogfood-v4-korean-hr-onboarding.md +356 -0
  146. package/examples/component-accordion-actions.md +153 -0
  147. package/examples/component-accordion-details.md +147 -0
  148. package/examples/component-accordion-summary.md +180 -0
  149. package/examples/component-accordion.md +229 -0
  150. package/examples/component-account-card.md +284 -0
  151. package/examples/component-address-input.md +260 -0
  152. package/examples/component-affix.md +190 -0
  153. package/examples/component-alert-dialog.md +210 -0
  154. package/examples/component-alert-title.md +77 -0
  155. package/examples/component-alert.md +192 -0
  156. package/examples/component-amount-input.md +278 -0
  157. package/examples/component-anchor.md +198 -0
  158. package/examples/component-app-bar.md +249 -0
  159. package/examples/component-aspect-ratio.md +156 -0
  160. package/examples/component-auto-complete.md +199 -0
  161. package/examples/component-avatar-group.md +170 -0
  162. package/examples/component-avatar.md +191 -0
  163. package/examples/component-back-top.md +123 -0
  164. package/examples/component-backdrop.md +148 -0
  165. package/examples/component-badge.md +181 -0
  166. package/examples/component-banner.md +237 -0
  167. package/examples/component-biometric-gate.md +281 -0
  168. package/examples/component-blockquote.md +153 -0
  169. package/examples/component-border-beam.md +207 -0
  170. package/examples/component-bottom-navigation.md +226 -0
  171. package/examples/component-box.md +112 -0
  172. package/examples/component-breadcrumb.md +222 -0
  173. package/examples/component-button-base.md +190 -0
  174. package/examples/component-button-group.md +117 -0
  175. package/examples/component-button.md +213 -0
  176. package/examples/component-calendar.md +280 -0
  177. package/examples/component-callout.md +131 -0
  178. package/examples/component-card-actions.md +101 -0
  179. package/examples/component-card-content.md +90 -0
  180. package/examples/component-card-header.md +122 -0
  181. package/examples/component-card-media.md +79 -0
  182. package/examples/component-card.md +233 -0
  183. package/examples/component-carousel.md +266 -0
  184. package/examples/component-cascader.md +135 -0
  185. package/examples/component-category-picker.md +271 -0
  186. package/examples/component-chart.md +237 -0
  187. package/examples/component-chat-interface.md +399 -0
  188. package/examples/component-checkbox.md +149 -0
  189. package/examples/component-click-away-listener.md +87 -0
  190. package/examples/component-code.md +213 -0
  191. package/examples/component-collapsible.md +219 -0
  192. package/examples/component-color-picker.md +110 -0
  193. package/examples/component-combobox.md +267 -0
  194. package/examples/component-command.md +299 -0
  195. package/examples/component-config-provider.md +190 -0
  196. package/examples/component-context-menu.md +179 -0
  197. package/examples/component-css-baseline.md +148 -0
  198. package/examples/component-date-picker.md +249 -0
  199. package/examples/component-descriptions.md +242 -0
  200. package/examples/component-dialog-actions.md +111 -0
  201. package/examples/component-dialog-content-text.md +76 -0
  202. package/examples/component-dialog-content.md +105 -0
  203. package/examples/component-dialog-title.md +104 -0
  204. package/examples/component-dialog.md +176 -0
  205. package/examples/component-divider.md +182 -0
  206. package/examples/component-doc-page.md +217 -0
  207. package/examples/component-drawer.md +257 -0
  208. package/examples/component-dropdown.md +220 -0
  209. package/examples/component-email-layout.md +253 -0
  210. package/examples/component-empty-state.md +269 -0
  211. package/examples/component-empty.md +172 -0
  212. package/examples/component-fade.md +87 -0
  213. package/examples/component-feature-grid.md +201 -0
  214. package/examples/component-field.md +266 -0
  215. package/examples/component-filled-input.md +114 -0
  216. package/examples/component-flex.md +117 -0
  217. package/examples/component-float-button.md +214 -0
  218. package/examples/component-form-control-label.md +134 -0
  219. package/examples/component-form-control.md +113 -0
  220. package/examples/component-form-controls.md +251 -0
  221. package/examples/component-form-group.md +86 -0
  222. package/examples/component-form-helper-text.md +95 -0
  223. package/examples/component-form-label.md +98 -0
  224. package/examples/component-form.md +291 -0
  225. package/examples/component-game-hud.md +362 -0
  226. package/examples/component-game-menu.md +327 -0
  227. package/examples/component-grid.md +140 -0
  228. package/examples/component-grow.md +79 -0
  229. package/examples/component-hero-block.md +252 -0
  230. package/examples/component-hover-card.md +211 -0
  231. package/examples/component-icon-button.md +142 -0
  232. package/examples/component-icon.md +102 -0
  233. package/examples/component-illustration.md +280 -0
  234. package/examples/component-image-list.md +107 -0
  235. package/examples/component-image.md +282 -0
  236. package/examples/component-input-adornment.md +101 -0
  237. package/examples/component-input-base.md +134 -0
  238. package/examples/component-input-number.md +141 -0
  239. package/examples/component-input-otp.md +271 -0
  240. package/examples/component-input.md +213 -0
  241. package/examples/component-item.md +243 -0
  242. package/examples/component-kbd.md +197 -0
  243. package/examples/component-krw-amount.md +219 -0
  244. package/examples/component-label.md +118 -0
  245. package/examples/component-layout.md +217 -0
  246. package/examples/component-link.md +223 -0
  247. package/examples/component-list-item-avatar.md +72 -0
  248. package/examples/component-list-item-button.md +139 -0
  249. package/examples/component-list-item-icon.md +82 -0
  250. package/examples/component-list-item-text.md +98 -0
  251. package/examples/component-list-item.md +116 -0
  252. package/examples/component-list-subheader.md +70 -0
  253. package/examples/component-list.md +198 -0
  254. package/examples/component-loading-button.md +125 -0
  255. package/examples/component-loading-sequence.md +254 -0
  256. package/examples/component-lottie-player.md +279 -0
  257. package/examples/component-masonry.md +191 -0
  258. package/examples/component-mentions.md +189 -0
  259. package/examples/component-menu-item.md +102 -0
  260. package/examples/component-menu-list.md +98 -0
  261. package/examples/component-menu.md +139 -0
  262. package/examples/component-menubar.md +259 -0
  263. package/examples/component-message.md +162 -0
  264. package/examples/component-mobile-stepper.md +155 -0
  265. package/examples/component-modal.md +220 -0
  266. package/examples/component-navigation-menu.md +295 -0
  267. package/examples/component-notification.md +166 -0
  268. package/examples/component-otp-countdown.md +245 -0
  269. package/examples/component-outlined-input.md +145 -0
  270. package/examples/component-page-transition.md +281 -0
  271. package/examples/component-pagination.md +226 -0
  272. package/examples/component-paper.md +199 -0
  273. package/examples/component-pass-auth.md +265 -0
  274. package/examples/component-payment-brand-button.md +253 -0
  275. package/examples/component-payment-method-selector.md +272 -0
  276. package/examples/component-payment-receipt.md +277 -0
  277. package/examples/component-popconfirm.md +144 -0
  278. package/examples/component-popover.md +239 -0
  279. package/examples/component-popper.md +129 -0
  280. package/examples/component-pricing-cards.md +247 -0
  281. package/examples/component-progress.md +195 -0
  282. package/examples/component-qr-code.md +201 -0
  283. package/examples/component-radio.md +167 -0
  284. package/examples/component-rate.md +202 -0
  285. package/examples/component-resizable.md +163 -0
  286. package/examples/component-result.md +270 -0
  287. package/examples/component-scroll-area.md +199 -0
  288. package/examples/component-scroll-reveal.md +320 -0
  289. package/examples/component-segmented.md +178 -0
  290. package/examples/component-select.md +258 -0
  291. package/examples/component-separator.md +177 -0
  292. package/examples/component-sheet.md +277 -0
  293. package/examples/component-sidebar.md +257 -0
  294. package/examples/component-skeleton.md +178 -0
  295. package/examples/component-slide.md +89 -0
  296. package/examples/component-slider.md +208 -0
  297. package/examples/component-snackbar-content.md +92 -0
  298. package/examples/component-snackbar.md +121 -0
  299. package/examples/component-sonner.md +165 -0
  300. package/examples/component-space.md +125 -0
  301. package/examples/component-spatial-locomotion.md +373 -0
  302. package/examples/component-spatial-panel.md +330 -0
  303. package/examples/component-speed-dial-action.md +78 -0
  304. package/examples/component-speed-dial.md +177 -0
  305. package/examples/component-spin.md +173 -0
  306. package/examples/component-spinner.md +204 -0
  307. package/examples/component-splitter.md +210 -0
  308. package/examples/component-stack.md +130 -0
  309. package/examples/component-statistic.md +282 -0
  310. package/examples/component-step-button.md +157 -0
  311. package/examples/component-step-connector.md +157 -0
  312. package/examples/component-step-content.md +121 -0
  313. package/examples/component-step-icon.md +115 -0
  314. package/examples/component-step-label.md +101 -0
  315. package/examples/component-step.md +84 -0
  316. package/examples/component-steps.md +264 -0
  317. package/examples/component-stock-chart.md +251 -0
  318. package/examples/component-swipeable-drawer.md +149 -0
  319. package/examples/component-switch.md +99 -0
  320. package/examples/component-tab-scroll-button.md +180 -0
  321. package/examples/component-tab.md +120 -0
  322. package/examples/component-table-body.md +82 -0
  323. package/examples/component-table-cell.md +118 -0
  324. package/examples/component-table-container.md +75 -0
  325. package/examples/component-table-footer.md +72 -0
  326. package/examples/component-table-head.md +78 -0
  327. package/examples/component-table-pagination.md +137 -0
  328. package/examples/component-table-row.md +113 -0
  329. package/examples/component-table-sort-label.md +109 -0
  330. package/examples/component-table.md +202 -0
  331. package/examples/component-tabs.md +184 -0
  332. package/examples/component-tag-badge.md +309 -0
  333. package/examples/component-tag.md +102 -0
  334. package/examples/component-testimonial-carousel.md +218 -0
  335. package/examples/component-textarea-autosize.md +114 -0
  336. package/examples/component-textarea.md +173 -0
  337. package/examples/component-time-picker.md +205 -0
  338. package/examples/component-timeline.md +170 -0
  339. package/examples/component-toast.md +224 -0
  340. package/examples/component-toggle-button.md +129 -0
  341. package/examples/component-toggle.md +220 -0
  342. package/examples/component-toolbar.md +104 -0
  343. package/examples/component-tooltip.md +178 -0
  344. package/examples/component-tour.md +176 -0
  345. package/examples/component-transaction-list-item.md +243 -0
  346. package/examples/component-transfer.md +156 -0
  347. package/examples/component-tree-select.md +202 -0
  348. package/examples/component-tree.md +297 -0
  349. package/examples/component-typography.md +215 -0
  350. package/examples/component-upload.md +295 -0
  351. package/examples/component-video-hero.md +409 -0
  352. package/examples/component-video-player.md +340 -0
  353. package/examples/component-voice-input.md +408 -0
  354. package/examples/component-watermark.md +217 -0
  355. package/examples/component-zoom.md +92 -0
  356. package/examples/doc-explanation-example.md +196 -0
  357. package/examples/doc-how-to-example.md +205 -0
  358. package/examples/doc-tutorial-example.md +162 -0
  359. package/examples/dogfood-korean-fintech-system.md +433 -0
  360. package/examples/email-transactional-example.md +259 -0
  361. package/examples/palette-saas-violet.md +235 -0
  362. package/examples/print-business-card-spec.md +205 -0
  363. package/examples/print-packaging-spec.md +285 -0
  364. package/examples/report-example.md +228 -0
  365. package/examples/slide-deck-example.md +237 -0
  366. package/examples/website-improvement-report.md +128 -0
  367. package/examples/website-improvement-workspace.json +126 -0
  368. package/install.sh +189 -0
  369. package/knowledge/COVERAGE.md +740 -0
  370. package/knowledge/PRINCIPLES.md +108 -0
  371. package/knowledge/a11y/contrast.md +70 -0
  372. package/knowledge/a11y/keyboard-and-focus.md +108 -0
  373. package/knowledge/colors/color-theory.md +90 -0
  374. package/knowledge/colors/mui-palette-structure.md +105 -0
  375. package/knowledge/colors/palettes-by-product-type.md +876 -0
  376. package/knowledge/components/INDEX.md +231 -0
  377. package/knowledge/components/index.json +1470 -0
  378. package/knowledge/components/shadcn-registry.md +159 -0
  379. package/knowledge/conversational/ai-chat-interfaces.md +323 -0
  380. package/knowledge/conversational/chatbot-design.md +312 -0
  381. package/knowledge/conversational/conversational-ui-fundamentals.md +299 -0
  382. package/knowledge/conversational/korean-voice-conventions.md +281 -0
  383. package/knowledge/conversational/voice-ui-patterns.md +297 -0
  384. package/knowledge/design-tokens/ant-design.md +124 -0
  385. package/knowledge/design-tokens/material-3.md +235 -0
  386. package/knowledge/design-tokens/polaris-and-carbon.md +231 -0
  387. package/knowledge/design-tokens/tailwind-v4.md +284 -0
  388. package/knowledge/game-ui/game-accessibility.md +317 -0
  389. package/knowledge/game-ui/game-ui-fundamentals.md +281 -0
  390. package/knowledge/game-ui/hud-design.md +324 -0
  391. package/knowledge/game-ui/korean-gaming-conventions.md +312 -0
  392. package/knowledge/game-ui/menu-systems.md +388 -0
  393. package/knowledge/i18n/korean-app-store-visual.md +223 -0
  394. package/knowledge/i18n/korean-document-style.md +301 -0
  395. package/knowledge/i18n/korean-payments.md +211 -0
  396. package/knowledge/i18n/korean-product-conventions.md +96 -0
  397. package/knowledge/i18n/korean-publishing.md +139 -0
  398. package/knowledge/i18n/korean-typography.md +123 -0
  399. package/knowledge/icons/curated-sets.md +225 -0
  400. package/knowledge/illustration/hero-illustrations.md +234 -0
  401. package/knowledge/illustration/illustration-systems.md +221 -0
  402. package/knowledge/illustration/mascot-design.md +208 -0
  403. package/knowledge/illustration/spot-illustrations.md +246 -0
  404. package/knowledge/illustration/svg-optimization.md +308 -0
  405. package/knowledge/layout/spacing-and-grid.md +119 -0
  406. package/knowledge/motion/app-loading-sequences.md +277 -0
  407. package/knowledge/motion/choreography-depth.md +297 -0
  408. package/knowledge/motion/marketing-motion.md +223 -0
  409. package/knowledge/motion/micro-interactions.md +266 -0
  410. package/knowledge/motion/motion-tools.md +281 -0
  411. package/knowledge/motion/principles.md +126 -0
  412. package/knowledge/patterns/auth-flow-design.md +316 -0
  413. package/knowledge/patterns/b2b-onboarding-flows.md +182 -0
  414. package/knowledge/patterns/brand-identity.md +238 -0
  415. package/knowledge/patterns/brand-references.md +97 -0
  416. package/knowledge/patterns/chart-color-encoding.md +269 -0
  417. package/knowledge/patterns/chart-types.md +344 -0
  418. package/knowledge/patterns/dashboard-composition.md +299 -0
  419. package/knowledge/patterns/design-system-qa.md +356 -0
  420. package/knowledge/patterns/document-typography.md +248 -0
  421. package/knowledge/patterns/email-design.md +338 -0
  422. package/knowledge/patterns/empty-states.md +263 -0
  423. package/knowledge/patterns/error-states.md +318 -0
  424. package/knowledge/patterns/form-design.md +237 -0
  425. package/knowledge/patterns/information-architecture.md +341 -0
  426. package/knowledge/patterns/landing-hero-design.md +283 -0
  427. package/knowledge/patterns/landing-page-patterns.md +681 -0
  428. package/knowledge/patterns/list-and-feed.md +371 -0
  429. package/knowledge/patterns/mobile-navigation.md +278 -0
  430. package/knowledge/patterns/money-and-amount.md +301 -0
  431. package/knowledge/patterns/onboarding.md +300 -0
  432. package/knowledge/patterns/pricing-page-design.md +261 -0
  433. package/knowledge/patterns/realtime-data.md +280 -0
  434. package/knowledge/patterns/report-design.md +330 -0
  435. package/knowledge/patterns/search-ux.md +373 -0
  436. package/knowledge/patterns/settings-page.md +325 -0
  437. package/knowledge/patterns/slide-deck-design.md +316 -0
  438. package/knowledge/patterns/styles-catalog.md +2599 -0
  439. package/knowledge/patterns/technical-writing.md +306 -0
  440. package/knowledge/patterns/ui-reasoning.md +1853 -0
  441. package/knowledge/patterns/ux-guidelines.md +1454 -0
  442. package/knowledge/platforms/react-native.md +395 -0
  443. package/knowledge/print/brochures-and-flyers.md +276 -0
  444. package/knowledge/print/korean-print-conventions.md +284 -0
  445. package/knowledge/print/packaging.md +321 -0
  446. package/knowledge/print/print-fundamentals.md +238 -0
  447. package/knowledge/print/signage-and-posters.md +235 -0
  448. package/knowledge/print/stationery.md +262 -0
  449. package/knowledge/spatial/ar-patterns.md +253 -0
  450. package/knowledge/spatial/comfort-and-accessibility.md +245 -0
  451. package/knowledge/spatial/spatial-design-fundamentals.md +346 -0
  452. package/knowledge/spatial/spatial-ui-elements.md +343 -0
  453. package/knowledge/spatial/vr-patterns.md +302 -0
  454. package/knowledge/typography/font-pairings.md +332 -0
  455. package/knowledge/typography/mui-type-scale.md +57 -0
  456. package/knowledge/typography/type-scale-fundamentals.md +105 -0
  457. package/knowledge/video/in-product-video.md +277 -0
  458. package/knowledge/video/korean-video-conventions.md +247 -0
  459. package/knowledge/video/marketing-video.md +258 -0
  460. package/knowledge/video/social-and-short-form.md +257 -0
  461. package/knowledge/video/video-fundamentals.md +296 -0
  462. package/package.json +106 -0
  463. package/skills/README.md +39 -0
  464. package/skills/color-palette/PLAYBOOK.md +175 -0
  465. package/skills/color-palette/SKILL.md +6 -0
  466. package/skills/color-palette/TEMPLATE.md +103 -0
  467. package/skills/component-spec-writer/PLAYBOOK.md +169 -0
  468. package/skills/component-spec-writer/SKILL.md +6 -0
  469. package/skills/component-spec-writer/TEMPLATE.md +115 -0
  470. package/skills/conversational-ui-designer/PLAYBOOK.md +231 -0
  471. package/skills/conversational-ui-designer/SKILL.md +6 -0
  472. package/skills/design-broadcast/PLAYBOOK.md +146 -0
  473. package/skills/design-broadcast/SKILL.md +6 -0
  474. package/skills/design-critique/PLAYBOOK.md +137 -0
  475. package/skills/design-critique/SKILL.md +6 -0
  476. package/skills/design-pr-review/PLAYBOOK.md +171 -0
  477. package/skills/design-pr-review/SKILL.md +6 -0
  478. package/skills/design-system-builder/PLAYBOOK.md +218 -0
  479. package/skills/design-system-builder/SKILL.md +6 -0
  480. package/skills/design-system-qa/PLAYBOOK.md +163 -0
  481. package/skills/design-system-qa/SKILL.md +6 -0
  482. package/skills/document-author/PLAYBOOK.md +167 -0
  483. package/skills/document-author/SKILL.md +6 -0
  484. package/skills/figma-token-sync/PLAYBOOK.md +149 -0
  485. package/skills/figma-token-sync/SKILL.md +6 -0
  486. package/skills/game-ui-designer/PLAYBOOK.md +209 -0
  487. package/skills/game-ui-designer/SKILL.md +6 -0
  488. package/skills/handoff-spec/PLAYBOOK.md +170 -0
  489. package/skills/handoff-spec/SKILL.md +6 -0
  490. package/skills/illustration-designer/PLAYBOOK.md +166 -0
  491. package/skills/illustration-designer/SKILL.md +6 -0
  492. package/skills/motion-designer/PLAYBOOK.md +223 -0
  493. package/skills/motion-designer/SKILL.md +6 -0
  494. package/skills/print-designer/PLAYBOOK.md +209 -0
  495. package/skills/print-designer/SKILL.md +6 -0
  496. package/skills/slide-deck-author/PLAYBOOK.md +198 -0
  497. package/skills/slide-deck-author/SKILL.md +6 -0
  498. package/skills/spatial-designer/PLAYBOOK.md +238 -0
  499. package/skills/spatial-designer/SKILL.md +6 -0
  500. package/skills/ux-audit/PLAYBOOK.md +142 -0
  501. package/skills/ux-audit/SKILL.md +6 -0
  502. package/skills/video-designer/PLAYBOOK.md +240 -0
  503. package/skills/video-designer/SKILL.md +6 -0
  504. package/skills/website-improvement/PLAYBOOK.md +118 -0
  505. package/skills/website-improvement/SKILL.md +6 -0
  506. package/skills/website-improvement/TEMPLATE.md +103 -0
  507. package/tools/audit/changelog-generate.py +176 -0
  508. package/tools/audit/check-coverage.py +483 -0
  509. package/tools/audit/doctor_assertions.py +256 -0
  510. package/tools/audit/example-qa.py +108 -0
  511. package/tools/audit/frontmatter-check.py +199 -0
  512. package/tools/audit/integration-check.py +95 -0
  513. package/tools/audit/korean-copy-check.py +161 -0
  514. package/tools/audit/link-check.py +146 -0
  515. package/tools/audit/local-ci.py +558 -0
  516. package/tools/audit/package-contents.py +723 -0
  517. package/tools/audit/package-smoke.py +22443 -0
  518. package/tools/audit/raw-hex-check.py +252 -0
  519. package/tools/audit/registry-smoke.py +8188 -0
  520. package/tools/audit/release-metadata.py +9832 -0
  521. package/tools/audit/run-all.py +351 -0
  522. package/tools/audit/smoke_assertions.py +12742 -0
  523. package/tools/audit/stability-review.py +332 -0
  524. package/tools/audit/stale-check.py +156 -0
  525. package/tools/migrations/add-version-frontmatter.py +132 -0
  526. package/tools/migrations/bump-last-updated.py +131 -0
  527. package/tools/migrations/promote-stability.py +172 -0
  528. package/tools/preview/README.md +58 -0
  529. package/tools/preview/render-tokens.py +454 -0
@@ -0,0 +1,408 @@
1
+ <!-- hand-written -->
2
+ # `VoiceInput` (custom — push-to-talk + transcript voice input) — spec
3
+
4
+ > Voice input button + listening state UI for chat interfaces, voice search, voice commands. Wraps Web Speech API (or platform STT) with visual feedback, transcript preview, error handling, and Korean voice conventions. Pairs with [`knowledge/conversational/voice-ui-patterns.md`](../knowledge/conversational/voice-ui-patterns.md).
5
+
6
+ ## Purpose
7
+
8
+ Voice input in apps requires:
9
+ 1. **Visible button** to start / stop listening.
10
+ 2. **Listening visual feedback** (waveform, pulse).
11
+ 3. **Transcript preview** (real-time as user speaks).
12
+ 4. **Error states** (mic permission denied, no speech detected, network).
13
+ 5. **Cancel** path (back, slide off).
14
+ 6. **Korean STT integration** (Clova, Web Speech, Whisper).
15
+ 7. **Reduced-motion respect**.
16
+ 8. **Accessibility alt** for non-voice users.
17
+
18
+ `VoiceInput` provides this as a standardized component.
19
+
20
+ ## Anatomy
21
+
22
+ ### Idle state
23
+
24
+ ```
25
+ ┌─────┐
26
+ │ 🎤 │ ← mic button (44pt minimum)
27
+ └─────┘
28
+ ```
29
+
30
+ ### Listening state (modal or inline)
31
+
32
+ ```
33
+ ┌──────────────────────────────────┐
34
+ │ ●●●●●●●●●● │ ← waveform / pulse
35
+ │ "배송 언제 와요?" │ ← transcript preview
36
+ │ │
37
+ │ [×] Cancel [✓] Send │
38
+ └──────────────────────────────────┘
39
+ ```
40
+
41
+ ### Processing (after stop)
42
+
43
+ ```
44
+ ┌──────────────────────────────────┐
45
+ │ 처리 중... │ ← spinner
46
+ └──────────────────────────────────┘
47
+ ```
48
+
49
+ ## API
50
+
51
+ ```tsx
52
+ <VoiceInput
53
+ onTranscript={(text, isFinal) => handle(text, isFinal)}
54
+ onCancel={handleCancel}
55
+ language="ko-KR"
56
+ variant="modal" // "inline" | "modal" | "button-only"
57
+ maxDuration={30000} // ms; auto-stop
58
+ autoStop // stop on silence
59
+ silenceTimeout={1500} // ms of silence before auto-stop
60
+ showTranscript
61
+ pushToTalk={false} // hold to talk vs tap-to-toggle
62
+ size="md"
63
+ />
64
+ ```
65
+
66
+ | Prop | Type | Default | Description |
67
+ | --- | --- | --- | --- |
68
+ | `onTranscript` | `(text: string, isFinal: boolean) => void` | — | Called with interim + final transcript |
69
+ | `onCancel` | `() => void` | — | User cancels |
70
+ | `onError` | `(error) => void` | — | STT or permission errors |
71
+ | `language` | `string` | `"ko-KR"` | BCP-47 language tag |
72
+ | `variant` | `"inline" \| "modal" \| "button-only"` | `"button-only"` | Layout |
73
+ | `maxDuration` | `number` | `30000` | Auto-stop after this many ms |
74
+ | `autoStop` | `boolean` | `true` | Stop on silence |
75
+ | `silenceTimeout` | `number` | `1500` | Ms of silence before auto-stop |
76
+ | `showTranscript` | `boolean` | `true` | Show interim transcript |
77
+ | `pushToTalk` | `boolean` | `false` | Hold (true) vs tap-to-toggle (false) |
78
+ | `size` | `"sm" \| "md" \| "lg"` | `"md"` | Button size |
79
+ | `provider` | `"web-speech" \| "clova" \| "whisper" \| "custom"` | `"web-speech"` | STT backend |
80
+ | `disabled` | `boolean` | `false` | Disable button |
81
+
82
+ ## Variants
83
+
84
+ ### `button-only`
85
+
86
+ Just the mic button. When tapped, opens whatever modal/inline UI is appropriate (configured externally).
87
+
88
+ ### `inline`
89
+
90
+ Mic button expands inline to listening UI within parent layout. Used in chat input bars.
91
+
92
+ ### `modal`
93
+
94
+ Full-screen / centered modal during listening. Used for voice search, primary voice features.
95
+
96
+ ## States
97
+
98
+ | State | Visual | Behavior |
99
+ | --- | --- | --- |
100
+ | `idle` | Mic icon, default | Tap / hold to start |
101
+ | `requesting-permission` | Spinner | Browser permission prompt |
102
+ | `listening` | Animated waveform + transcript | Capturing audio |
103
+ | `processing` | Spinner | STT processing final transcript |
104
+ | `error-permission` | "Mic access required" + Settings link | User denied mic |
105
+ | `error-no-speech` | "Didn't catch that. Try again?" | Silent recording |
106
+ | `error-network` | "Network error. Try again." | STT failed |
107
+ | `disabled` | Grayed out | When `disabled` prop |
108
+
109
+ ## Tokens consumed
110
+
111
+ ```
112
+ --voice-input-button-bg
113
+ --voice-input-button-fg
114
+ --voice-input-button-bg-active (during listening)
115
+ --voice-input-button-bg-error
116
+ --voice-input-waveform-color (brand color typically)
117
+ --voice-input-waveform-bg
118
+ --voice-input-transcript-fg
119
+ --voice-input-modal-bg (full-screen overlay if modal)
120
+ --motion-fast, --motion-medium
121
+ --ease-out
122
+ --space-md, --space-lg
123
+ --radius-full (mic button is circular)
124
+ ```
125
+
126
+ ## Visual feedback
127
+
128
+ ### Pulse animation (listening)
129
+
130
+ ```css
131
+ .voice-input__button[data-state="listening"] {
132
+ animation: pulse 1.5s ease-in-out infinite;
133
+ }
134
+
135
+ @keyframes pulse {
136
+ 0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 var(--voice-input-button-bg-active); }
137
+ 50% { transform: scale(1.05); box-shadow: 0 0 0 8px transparent; }
138
+ }
139
+
140
+ @media (prefers-reduced-motion: reduce) {
141
+ .voice-input__button[data-state="listening"] { animation: none; }
142
+ }
143
+ ```
144
+
145
+ ### Waveform
146
+
147
+ Visualize audio level real-time:
148
+
149
+ ```tsx
150
+ function Waveform({ analyser }: { analyser: AnalyserNode }) {
151
+ const canvasRef = useRef<HTMLCanvasElement>(null);
152
+
153
+ useEffect(() => {
154
+ const canvas = canvasRef.current!;
155
+ const ctx = canvas.getContext("2d")!;
156
+ const bufferLength = analyser.frequencyBinCount;
157
+ const data = new Uint8Array(bufferLength);
158
+
159
+ let rafId: number;
160
+ const draw = () => {
161
+ analyser.getByteFrequencyData(data);
162
+ // ...render bars
163
+ rafId = requestAnimationFrame(draw);
164
+ };
165
+ draw();
166
+
167
+ return () => cancelAnimationFrame(rafId);
168
+ }, [analyser]);
169
+
170
+ return <canvas ref={canvasRef} aria-hidden="true" />;
171
+ }
172
+ ```
173
+
174
+ For reduced motion: replace with simple "Listening..." text.
175
+
176
+ ## Interaction patterns
177
+
178
+ ### Tap-to-toggle (default)
179
+
180
+ 1. User taps mic.
181
+ 2. Listening starts.
182
+ 3. User speaks.
183
+ 4. User taps again to stop OR auto-stops on silence.
184
+ 5. Transcript sent.
185
+
186
+ ### Push-to-talk (PTT)
187
+
188
+ 1. User holds mic button.
189
+ 2. Listening starts immediately.
190
+ 3. User releases when done.
191
+ 4. Transcript sent.
192
+
193
+ PTT is preferred for:
194
+ - Walkie-talkie UX.
195
+ - Short utterances.
196
+ - Public spaces (no risk of accidental long recording).
197
+
198
+ Tap-to-toggle preferred for:
199
+ - Long-form input (dictation).
200
+ - Mobile (holding finger is tedious).
201
+
202
+ ## Implementation
203
+
204
+ ### Web Speech API (browser-native)
205
+
206
+ ```tsx
207
+ function VoiceInput({ onTranscript, language = "ko-KR", autoStop = true, silenceTimeout = 1500, ... }: Props) {
208
+ const recognitionRef = useRef<SpeechRecognition>();
209
+ const [state, setState] = useState<"idle" | "listening" | "processing" | "error">("idle");
210
+ const [transcript, setTranscript] = useState("");
211
+ const reduced = usePrefersReducedMotion();
212
+
213
+ const start = async () => {
214
+ try {
215
+ // Permission check (modern API)
216
+ await navigator.mediaDevices.getUserMedia({ audio: true });
217
+ } catch {
218
+ setState("error");
219
+ onError?.({ type: "permission" });
220
+ return;
221
+ }
222
+
223
+ const SpeechRecognition = window.SpeechRecognition || (window as any).webkitSpeechRecognition;
224
+ if (!SpeechRecognition) {
225
+ onError?.({ type: "unsupported" });
226
+ return;
227
+ }
228
+
229
+ const recognition = new SpeechRecognition();
230
+ recognition.lang = language;
231
+ recognition.interimResults = true;
232
+ recognition.continuous = autoStop ? false : true;
233
+
234
+ recognition.onresult = (event: SpeechRecognitionEvent) => {
235
+ let interim = "";
236
+ let final = "";
237
+ for (let i = event.resultIndex; i < event.results.length; i++) {
238
+ const result = event.results[i];
239
+ if (result.isFinal) final += result[0].transcript;
240
+ else interim += result[0].transcript;
241
+ }
242
+ const combined = final + interim;
243
+ setTranscript(combined);
244
+ onTranscript(combined, !!final);
245
+ };
246
+
247
+ recognition.onerror = (event: SpeechRecognitionErrorEvent) => {
248
+ setState("error");
249
+ onError?.({ type: event.error });
250
+ };
251
+
252
+ recognition.onend = () => {
253
+ setState("idle");
254
+ };
255
+
256
+ recognition.start();
257
+ recognitionRef.current = recognition;
258
+ setState("listening");
259
+ };
260
+
261
+ const stop = () => {
262
+ recognitionRef.current?.stop();
263
+ setState("processing");
264
+ };
265
+
266
+ return (
267
+ <button
268
+ className="voice-input__button"
269
+ data-state={state}
270
+ data-reduced={reduced}
271
+ onClick={state === "idle" ? start : stop}
272
+ aria-label={state === "idle" ? "음성으로 입력" : "녹음 중지"}
273
+ aria-pressed={state === "listening"}
274
+ >
275
+ {state === "idle" && <MicIcon />}
276
+ {state === "listening" && <StopIcon />}
277
+ {state === "processing" && <Spinner />}
278
+ {state === "error" && <ErrorIcon />}
279
+ </button>
280
+ );
281
+ }
282
+ ```
283
+
284
+ ### For Clova / Whisper / custom backend
285
+
286
+ Replace Web Speech with custom STT. Stream microphone audio (MediaRecorder) to backend; receive transcript via WebSocket or chunks.
287
+
288
+ ```tsx
289
+ // Pseudocode
290
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
291
+ const recorder = new MediaRecorder(stream);
292
+ recorder.ondataavailable = e => sendChunkToServer(e.data);
293
+ recorder.start(250); // emit every 250ms
294
+ ```
295
+
296
+ For Korean: Naver Clova STT API recommended for best Korean recognition; OpenAI Whisper API also strong.
297
+
298
+ ## Permission handling
299
+
300
+ First-time user must grant mic permission:
301
+
302
+ ```
303
+ ┌────────────────────────────────────┐
304
+ │ 음성 입력을 사용하려면 마이크 권한이│
305
+ │ 필요해요. │
306
+ │ │
307
+ │ [권한 요청] │
308
+ └────────────────────────────────────┘
309
+ ```
310
+
311
+ If denied:
312
+ ```
313
+ ┌────────────────────────────────────┐
314
+ │ 마이크 권한이 차단되어 있어요. │
315
+ │ 브라우저 설정에서 권한을 허용해 주세요.│
316
+ │ │
317
+ │ [브라우저 설정 열기] │
318
+ └────────────────────────────────────┘
319
+ ```
320
+
321
+ ## Error handling
322
+
323
+ | Error | UX |
324
+ | --- | --- |
325
+ | Permission denied | Modal with "Enable in settings" |
326
+ | No speech detected | "Didn't catch that. Try again?" with replay option |
327
+ | Network error (cloud STT) | "Connection error. Retry." |
328
+ | Browser unsupported | Hide voice button OR show "Use text input" hint |
329
+ | Timeout (no speech for N seconds) | Auto-stop with "Tap to try again" |
330
+ | STT confidence too low | "Not sure I caught that. Did you mean: [option1] [option2]?" |
331
+
332
+ ## Accessibility
333
+
334
+ - **Visual indicator** of listening state (waveform / pulse).
335
+ - **Transcript visible** to deaf users (so they see what's captured).
336
+ - **Text alt input** always available (don't make voice the only path).
337
+ - **ARIA labels**: button has descriptive label.
338
+ - **`aria-live`** for transcript updates.
339
+ - **Reduced motion**: pulse / waveform replaced with static "Listening..." text.
340
+ - **High contrast**: button has visible border, not just color.
341
+ - **Keyboard activation**: Space / Enter triggers start/stop.
342
+
343
+ ## Korean conventions
344
+
345
+ | Aspect | Default |
346
+ | --- | --- |
347
+ | Button label | "음성으로 입력" |
348
+ | Listening state | "듣고 있어요..." |
349
+ | Processing | "처리 중..." |
350
+ | No speech | "음성을 인식하지 못했어요. 다시 시도해 주세요." |
351
+ | Permission needed | "마이크 권한이 필요해요" |
352
+ | Cancel button | "취소" |
353
+ | Send button | "전송" |
354
+
355
+ For Korean STT: configure language as `ko-KR`. Web Speech API works for Korean in Chrome / Edge; Naver Clova preferred for production-grade.
356
+
357
+ ## Mobile considerations
358
+
359
+ - Touch target minimum 44pt.
360
+ - iOS Safari requires user gesture to start mic.
361
+ - Background tab paused; resume on focus.
362
+ - Battery drain — auto-stop on silence is critical.
363
+ - Bluetooth mic compatibility — test.
364
+
365
+ ## Performance
366
+
367
+ - Don't keep mic open when not needed (release stream on stop).
368
+ - For waveform: use `requestAnimationFrame`, not `setInterval`.
369
+ - Stream audio in chunks (don't accumulate full recording in memory).
370
+ - For long-form: chunked upload to STT (250ms chunks typical).
371
+
372
+ ## Edge cases
373
+
374
+ - **User taps mic while listening**: stops (toggle behavior).
375
+ - **User leaves page mid-recording**: cleanup; release mic.
376
+ - **Multiple mics on system**: use default; can add device picker.
377
+ - **External mic disconnects**: graceful fallback to internal.
378
+ - **Long pauses mid-utterance**: don't auto-stop too eagerly (user thinking).
379
+ - **STT mishears brand name**: provide post-edit option.
380
+ - **Korean dialect** (Busan, Jeju): test; Whisper handles best.
381
+ - **Code-switching** (Korean + English): STT may misrecognize; large LLMs handle better.
382
+
383
+ ## Don't
384
+
385
+ - Don't auto-record without explicit start gesture.
386
+ - Don't keep mic open after stop.
387
+ - Don't omit visual feedback. Listening must be visually obvious.
388
+ - Don't make voice the only input path.
389
+ - Don't ignore reduced-motion users.
390
+ - Don't auto-stop in 200ms if user pauses to think.
391
+ - Don't ship without permission denial UX.
392
+ - Don't ignore Korean STT specifics (language tag, dialect).
393
+
394
+ ## References
395
+
396
+ Built on:
397
+ - Web Speech API (`SpeechRecognition` / `webkitSpeechRecognition`)
398
+ - Naver Clova Speech API (Korean cloud STT)
399
+ - OpenAI Whisper API (cloud STT, multilingual)
400
+ - React patterns for permission handling
401
+
402
+ ## Cross-reference
403
+
404
+ - [`knowledge/conversational/voice-ui-patterns.md`](../knowledge/conversational/voice-ui-patterns.md) — voice patterns
405
+ - [`knowledge/conversational/conversational-ui-fundamentals.md`](../knowledge/conversational/conversational-ui-fundamentals.md) — fundamentals
406
+ - [`knowledge/conversational/korean-voice-conventions.md`](../knowledge/conversational/korean-voice-conventions.md) — KR
407
+ - [`examples/component-chat-interface.md`](component-chat-interface.md) — chat UI consumer
408
+ - [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md) — keyboard
@@ -0,0 +1,217 @@
1
+ # `Watermark` — spec
2
+
3
+ > Citing Ant Design `Watermark`, MUI (no built-in), shadcn-ui (no built-in)
4
+
5
+ ## Purpose
6
+
7
+ Adds a repeating watermark overlay (text or image) on top of content. Used for: confidential documents, leaked-photo deterrents in admin/fintech apps, screenshot tracing, "DRAFT" labels.
8
+
9
+ ## When Watermark vs alternatives
10
+
11
+ | Pattern | Use |
12
+ | --- | --- |
13
+ | **Watermark** | Repeating subtle pattern across the surface |
14
+ | **Banner** | One-time announcement at top |
15
+ | **Toast** | Transient feedback |
16
+ | **Status badge** | Attached to specific elements |
17
+
18
+ Watermarks are subtle by design — the user notices in screenshots, not while using the app.
19
+
20
+ ## Anatomy
21
+
22
+ ```
23
+ [Page content]
24
+ •︵• •︵•
25
+ [confidential] [confidential]
26
+ •︵• •︵•
27
+ [confidential] [confidential]
28
+ (rotated, semi-transparent)
29
+ ```
30
+
31
+ Watermark is a **layer** over the content, not a component within it.
32
+
33
+ ## API
34
+
35
+ ```tsx
36
+ <Watermark content="confidential">
37
+ <SensitiveDataPage />
38
+ </Watermark>
39
+
40
+ <Watermark
41
+ content={["민지", "2026.05.07"]} // multi-line
42
+ rotate={-30}
43
+ opacity={0.06}
44
+ spacing={[200, 100]}
45
+ >
46
+ {children}
47
+ </Watermark>
48
+
49
+ <Watermark image="/logo-watermark.svg" imageSize={120}>
50
+ {children}
51
+ </Watermark>
52
+ ```
53
+
54
+ | Prop | Type | Default | Description |
55
+ | --- | --- | --- | --- |
56
+ | `content` | `string \| string[]` | — | Text watermark (single or multi-line) |
57
+ | `image` | `string` | — | Image watermark (SVG or PNG) |
58
+ | `imageSize` | `number` | — | Image dimension |
59
+ | `rotate` | `number` | `-22` | Degrees |
60
+ | `opacity` | `number` | `0.06` | 0–1 |
61
+ | `color` | `string` | `--color-text-tertiary` | Text color |
62
+ | `fontSize` | `number` | `14` | |
63
+ | `spacing` | `[number, number]` | `[100, 100]` | Horizontal × vertical gap between marks |
64
+ | `zIndex` | `number` | `1` | Above content but below modals |
65
+ | `children` | `ReactNode` | — | Wrapped content |
66
+
67
+ ## Implementation strategy
68
+
69
+ Two approaches:
70
+
71
+ ### CSS pattern (lightweight)
72
+
73
+ Repeating background image generated as an SVG / canvas and tiled via CSS:
74
+
75
+ ```css
76
+ .watermark {
77
+ position: relative;
78
+ }
79
+ .watermark::after {
80
+ content: "";
81
+ position: absolute;
82
+ inset: 0;
83
+ background-image: url("data:image/svg+xml,..."); /* SVG with text */
84
+ background-size: 200px 100px;
85
+ pointer-events: none;
86
+ opacity: 0.06;
87
+ z-index: 1;
88
+ }
89
+ ```
90
+
91
+ Generate the SVG once with the watermark text + rotation. Embed as data URI for self-contained.
92
+
93
+ ### Canvas overlay (more flexible)
94
+
95
+ Render watermark on a canvas overlay:
96
+
97
+ ```js
98
+ const canvas = document.createElement("canvas");
99
+ canvas.width = window.innerWidth;
100
+ canvas.height = window.innerHeight;
101
+ const ctx = canvas.getContext("2d");
102
+ ctx.globalAlpha = 0.06;
103
+ ctx.font = "14px sans-serif";
104
+ ctx.fillStyle = "currentColor";
105
+
106
+ // Draw repeating rotated text
107
+ for (let x = 0; x < canvas.width; x += 200) {
108
+ for (let y = 0; y < canvas.height; y += 100) {
109
+ ctx.save();
110
+ ctx.translate(x, y);
111
+ ctx.rotate(-22 * Math.PI / 180);
112
+ ctx.fillText("confidential", 0, 0);
113
+ ctx.restore();
114
+ }
115
+ }
116
+ ```
117
+
118
+ Both work. CSS is simpler; canvas is more flexible (can include user-specific watermarks like usernames).
119
+
120
+ ## Common use cases
121
+
122
+ ### 1. Confidential admin pages
123
+
124
+ ```tsx
125
+ <Watermark content="confidential" rotate={-22}>
126
+ <AdminPage />
127
+ </Watermark>
128
+ ```
129
+
130
+ The screenshot taker leaves traces.
131
+
132
+ ### 2. Per-user tracing (Korean fintech sensitive screens)
133
+
134
+ ```tsx
135
+ <Watermark content={[user.name, user.email, today]}>
136
+ <SensitiveAccountInfo />
137
+ </Watermark>
138
+ ```
139
+
140
+ If a screenshot leaks, the source user is visible.
141
+
142
+ ### 3. "DRAFT" / "PREVIEW" / "SAMPLE"
143
+
144
+ ```tsx
145
+ <Watermark content="DRAFT" rotate={-30} opacity={0.08} fontSize={32}>
146
+ <DocumentPreview />
147
+ </Watermark>
148
+ ```
149
+
150
+ Strong indicator that content isn't final.
151
+
152
+ ### 4. Brand watermark on shared content
153
+
154
+ ```tsx
155
+ <Watermark image="/brand.svg" imageSize={200} opacity={0.1}>
156
+ <ShareableContent />
157
+ </Watermark>
158
+ ```
159
+
160
+ Marketing content that gets exported / screenshotted.
161
+
162
+ ## States
163
+
164
+ Watermark doesn't have states. It's purely decorative-with-a-purpose.
165
+
166
+ ## Tokens consumed
167
+
168
+ ```
169
+ --color-text-tertiary (default text color)
170
+ --color-text-secondary (alternative for higher visibility)
171
+ --space-md
172
+ --font-size-sm
173
+ ```
174
+
175
+ Opacity is the primary design lever — `0.04–0.10` is the sweet spot. Higher distracts; lower invisible.
176
+
177
+ ## Accessibility
178
+
179
+ - Watermarks are **decorative** — `aria-hidden="true"` on the watermark layer.
180
+ - Text content within the watermark is not announced.
181
+ - Watermark must NOT obscure interactive elements (`pointer-events: none` on the layer).
182
+ - For screen readers: watermark is invisible (it's purely a screenshot deterrent).
183
+
184
+ ## Performance
185
+
186
+ - For repeated watermarks: render once and tile via CSS (don't render each instance as a DOM element).
187
+ - For canvas: re-render on resize, throttled.
188
+ - For per-user watermarks: generate the SVG/canvas once on mount; cache.
189
+
190
+ ## Don't
191
+
192
+ - Don't make watermarks dark / high-contrast — defeats the "subtle" purpose.
193
+ - Don't watermark content the user expects to download cleanly (their own data exports).
194
+ - Don't watermark print pages with text that won't print legibly.
195
+ - Don't put watermarks **above** modals / overlays — `z-index: 1` is right; modals are z-index 1000+.
196
+ - Don't use watermarks for legal compliance alone — they deter, don't prevent. Leaks still happen.
197
+ - Don't omit `pointer-events: none` — clicks through must work.
198
+
199
+ ## Korean fintech context
200
+
201
+ For sensitive financial screens:
202
+ - Account balance details
203
+ - Transaction history (when shown to support / admin)
204
+ - Customer data in CRM tools
205
+ - Internal admin views
206
+
207
+ Watermark with the **viewer's name + date** discourages internal screenshot-leaks. KakaoBank, Toss, and major Korean banks use this pattern.
208
+
209
+ ## References
210
+
211
+ - Ant Design: [`refs/ant-design/components/watermark/`](../refs/ant-design/components/watermark/) — `Watermark`. Modern Ant addition with comprehensive options.
212
+ - MUI / shadcn-ui: no built-in. Compose with CSS or canvas.
213
+
214
+ ## Cross-reference
215
+
216
+ - [`knowledge/a11y/contrast.md`](../knowledge/a11y/contrast.md) — watermark text color considerations
217
+ - [`knowledge/i18n/korean-product-conventions.md`](../knowledge/i18n/korean-product-conventions.md) — Korean fintech screenshot-deterrent conventions