@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,253 @@
1
+ # `EmailLayout` — spec
2
+
3
+ > The standard responsive email layout. Wraps content in the table-based scaffolding required for cross-client compatibility.
4
+
5
+ ## Purpose
6
+
7
+ Provides the canonical email body structure: centered 600px container, table-based layout, inline CSS, mobile-responsive media queries. Use for both transactional and marketing emails.
8
+
9
+ ## Anatomy
10
+
11
+ ```
12
+ ┌────────────────────────────────────────────────┐
13
+ │ outer wrapper (full-width, bg color) │
14
+ │ ┌──────────────────────────────────────────┐ │
15
+ │ │ inner wrapper (600px max, centered) │ │
16
+ │ │ ┌────────────────────────────────────┐ │ │
17
+ │ │ │ Header (logo) │ │ │
18
+ │ │ ├────────────────────────────────────┤ │ │
19
+ │ │ │ │ │ │
20
+ │ │ │ Body content │ │ │
21
+ │ │ │ │ │ │
22
+ │ │ ├────────────────────────────────────┤ │ │
23
+ │ │ │ Footer (legal, unsubscribe) │ │ │
24
+ │ │ └────────────────────────────────────┘ │ │
25
+ │ └──────────────────────────────────────────┘ │
26
+ └────────────────────────────────────────────────┘
27
+ ```
28
+
29
+ ## API (React Email-flavored)
30
+
31
+ ```tsx
32
+ <EmailLayout
33
+ preheader="Your tracking number is FX12345..."
34
+ brandColor="#7C3AED"
35
+ >
36
+ <EmailLayout.Header>
37
+ <Logo />
38
+ </EmailLayout.Header>
39
+
40
+ <EmailLayout.Body>
41
+ <Heading>주문이 발송되었습니다</Heading>
42
+ <Paragraph>안녕하세요, 김민지 님.</Paragraph>
43
+ <Paragraph>주문번호 #1234가 방금 발송되었습니다.</Paragraph>
44
+ <Button href="https://...">배송 조회</Button>
45
+ </EmailLayout.Body>
46
+
47
+ <EmailLayout.Footer>
48
+ <UnsubscribeLink />
49
+ <CompanyInfo />
50
+ </EmailLayout.Footer>
51
+ </EmailLayout>
52
+ ```
53
+
54
+ | Prop | Type | Default | Description |
55
+ | --- | --- | --- | --- |
56
+ | `preheader` | `string` | — | Preview text shown in inbox; hidden in body |
57
+ | `brandColor` | `string` | system | Used for buttons, links |
58
+ | `bgColor` | `string` | `"#FAFAFA"` | Outer wrapper bg |
59
+ | `width` | `number` | `600` | Inner container width |
60
+ | `subject` | `string` | — | Used for `<title>` (read by some clients) |
61
+ | `lang` | `string` | `"ko"` | HTML `lang` attribute |
62
+ | `dir` | `"ltr" \| "rtl"` | `"ltr"` | |
63
+ | `children` | `ReactNode` | — | Body |
64
+
65
+ ## Generated HTML structure
66
+
67
+ ```html
68
+ <!doctype html>
69
+ <html lang="ko">
70
+ <head>
71
+ <meta charset="utf-8">
72
+ <meta name="viewport" content="width=device-width, initial-scale=1">
73
+ <meta name="x-apple-disable-message-reformatting">
74
+ <title>{subject}</title>
75
+ <style>
76
+ @media (max-width: 480px) {
77
+ .container { width: 100% !important; }
78
+ }
79
+ </style>
80
+ </head>
81
+ <body style="margin:0;padding:0;background:#FAFAFA;">
82
+
83
+ <!-- Preheader (hidden) -->
84
+ <div style="display:none;max-height:0;overflow:hidden;">{preheader}</div>
85
+
86
+ <!-- Outer table -->
87
+ <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
88
+ <tr>
89
+ <td align="center" style="padding: 24px 0;">
90
+ <!-- Inner container -->
91
+ <table role="presentation" cellpadding="0" cellspacing="0" border="0" class="container" width="600" style="max-width: 600px;">
92
+ <tr><td>{header}</td></tr>
93
+ <tr><td>{body}</td></tr>
94
+ <tr><td>{footer}</td></tr>
95
+ </table>
96
+ </td>
97
+ </tr>
98
+ </table>
99
+
100
+ </body>
101
+ </html>
102
+ ```
103
+
104
+ ## Sub-components
105
+
106
+ ### `<EmailLayout.Header>`
107
+
108
+ Top of email — logo. Padding 24px around.
109
+
110
+ ```tsx
111
+ <EmailLayout.Header>
112
+ <Img src="/logo.png" alt="Brand" width="120" height="40" />
113
+ </EmailLayout.Header>
114
+ ```
115
+
116
+ ### `<EmailLayout.Body>`
117
+
118
+ Main content. Padding 24px. White bg by default.
119
+
120
+ Composition: `<Heading>`, `<Paragraph>`, `<Button>`, `<Hr>` etc.
121
+
122
+ ### `<EmailLayout.Footer>`
123
+
124
+ Legal info, unsubscribe. Smaller text.
125
+
126
+ For Korean: must include sender's company info per Korean spam law:
127
+
128
+ ```
129
+ [회사명] · 사업자등록번호 123-45-67890
130
+ [서울시 강남구 테헤란로 123] · 대표 [이름]
131
+ 문의: support@example.com
132
+
133
+ 수신거부: [unsubscribe link]
134
+ ```
135
+
136
+ ## Inline CSS
137
+
138
+ All styles must be inline. Frameworks (react-email, mjml) do this automatically.
139
+
140
+ For hand-written: use a tool like `juice` or `inline-css` to inline `<style>` rules.
141
+
142
+ ## Tokens consumed
143
+
144
+ Email tokens are a **subset** of the broader design system — limited to email-safe values:
145
+
146
+ ```
147
+ brand color, brand-on-color, neutral-bg, neutral-bg-elevated,
148
+ text-primary, text-secondary, text-on-brand,
149
+ border-default, link-color
150
+ ```
151
+
152
+ Plus typography:
153
+ - font-family-stack (with system fallback)
154
+ - font-size-xs through font-size-2xl
155
+
156
+ Don't reference tokens via CSS variables — inline only.
157
+
158
+ ## Buttons (bulletproof)
159
+
160
+ The "Track order" button uses the bulletproof button pattern (table cell + styled `<a>`):
161
+
162
+ ```html
163
+ <table role="presentation" cellpadding="0" cellspacing="0" border="0">
164
+ <tr>
165
+ <td bgcolor="#7C3AED" style="border-radius: 8px;">
166
+ <a href="..." style="display: inline-block; padding: 14px 32px; color: #FFFFFF; text-decoration: none; font-family: sans-serif; font-size: 16px; font-weight: 600; border-radius: 8px;">
167
+ Track order
168
+ </a>
169
+ </td>
170
+ </tr>
171
+ </table>
172
+ ```
173
+
174
+ Wrap as a sub-component:
175
+
176
+ ```tsx
177
+ <Button href="..." style={{ background: "#7C3AED", color: "#FFFFFF" }}>
178
+ Track order
179
+ </Button>
180
+ ```
181
+
182
+ ## Korean transactional template
183
+
184
+ ```tsx
185
+ <EmailLayout preheader="주문번호 #1234가 발송되었습니다" lang="ko">
186
+ <EmailLayout.Header>
187
+ <Img src="/logo.png" alt="회사명" width="120" height="40" />
188
+ </EmailLayout.Header>
189
+
190
+ <EmailLayout.Body>
191
+ <Heading style={{ fontSize: 24, fontWeight: 700 }}>
192
+ 주문이 발송되었습니다
193
+ </Heading>
194
+
195
+ <Paragraph>안녕하세요, {{first_name}} 님.</Paragraph>
196
+ <Paragraph>
197
+ 주문번호 <strong>#1234</strong>가 방금 발송되었습니다.
198
+ 예상 도착일은 {{delivery_date}}입니다.
199
+ </Paragraph>
200
+
201
+ <Button href="https://...">배송 조회</Button>
202
+
203
+ <Paragraph style={{ color: "#64748B", fontSize: 14, marginTop: 32 }}>
204
+ 문의사항이 있으시면 언제든 답장해 주세요.
205
+ </Paragraph>
206
+ </EmailLayout.Body>
207
+
208
+ <EmailLayout.Footer>
209
+ <Paragraph style={{ fontSize: 12, color: "#94A3B8" }}>
210
+ [회사명] · 사업자등록번호 123-45-67890<br />
211
+ 서울시 강남구 테헤란로 123<br />
212
+ 문의: <Link href="mailto:support@example.com">support@example.com</Link>
213
+ </Paragraph>
214
+ <Paragraph style={{ fontSize: 12, color: "#94A3B8" }}>
215
+ <Link href="...">수신거부</Link>
216
+ </Paragraph>
217
+ </EmailLayout.Footer>
218
+ </EmailLayout>
219
+ ```
220
+
221
+ ## Mobile responsive
222
+
223
+ The `@media (max-width: 480px)` rules in the inline `<style>` block:
224
+ - `.container { width: 100% !important; }`
225
+ - Reduce padding (24px → 16px).
226
+ - Stack horizontal items vertically.
227
+
228
+ For multi-column layouts: wrap each column in a `class="stack"` and have the media query unset float / inline-block.
229
+
230
+ ## Don't
231
+
232
+ - Don't put critical info only in images (image-load-blocked clients see nothing).
233
+ - Don't use `<button>` — Outlook ignores styles.
234
+ - Don't use SVG (Outlook breaks it; use PNG).
235
+ - Don't use flexbox / grid (Outlook breaks).
236
+ - Don't use web fonts as the only font (Outlook desktop falls back).
237
+ - Don't omit preheader text.
238
+ - Don't omit unsubscribe (legal in many jurisdictions including Korea).
239
+ - Don't omit `[광고]` prefix on Korean marketing emails (legal requirement).
240
+
241
+ ## References
242
+
243
+ - React Email: [react.email](https://react.email/) — modern React-based authoring.
244
+ - MJML: [mjml.io](https://mjml.io/) — markup language for emails.
245
+ - Litmus: [litmus.com](https://www.litmus.com/) — preview across clients.
246
+ - Korean spam law (정보통신망 이용촉진 및 정보보호 등에 관한 법률) — see [`knowledge/i18n/korean-publishing.md`](../knowledge/i18n/korean-publishing.md).
247
+
248
+ ## Cross-reference
249
+
250
+ - [`knowledge/patterns/email-design.md`](../knowledge/patterns/email-design.md) — broader email design rules
251
+ - [`knowledge/patterns/document-typography.md`](../knowledge/patterns/document-typography.md) — body type rules
252
+ - [`knowledge/i18n/korean-product-conventions.md`](../knowledge/i18n/korean-product-conventions.md) — Korean voice
253
+ - [`knowledge/i18n/korean-publishing.md`](../knowledge/i18n/korean-publishing.md) — Korean spam law
@@ -0,0 +1,269 @@
1
+ <!-- hand-written -->
2
+ # `EmptyState` (custom — no-data + filtered-empty + first-run shell) — spec
3
+
4
+ > One component for every "nothing here" surface in the product. Pairs with [`knowledge/illustration/spot-illustrations.md`](../knowledge/illustration/spot-illustrations.md).
5
+
6
+ ## Purpose
7
+
8
+ Most apps have 5-15 empty surfaces (no projects yet, no search results, no notifications, filter shows nothing, error reduced to empty). Without a single component, each team hand-rolls one and they drift.
9
+
10
+ `EmptyState` enforces:
11
+ 1. **One layout** — illustration + headline + description + CTA stack.
12
+ 2. **One illustration source** — pulls from the system's spot-illustration set.
13
+ 3. **Voice consistency** — encouraging, not pitying.
14
+ 4. **Accessibility** — illustration is decorative; meaning lives in text.
15
+
16
+ ## Anatomy
17
+
18
+ ```
19
+ ┌────────────────────────────────────────┐
20
+ │ │
21
+ │ [illustration] │ ← optional; 120-200px
22
+ │ │
23
+ │ 찾으시는 결과가 없어요 │ ← headline
24
+ │ 다른 키워드로 검색해 보세요 │ ← description
25
+ │ │
26
+ │ [Primary CTA] │ ← optional
27
+ │ [Secondary link] │ ← optional
28
+ └────────────────────────────────────────┘
29
+ ```
30
+
31
+ ## API
32
+
33
+ ```tsx
34
+ <EmptyState
35
+ illustration="search-empty"
36
+ title="찾으시는 결과가 없어요"
37
+ description="다른 키워드로 검색해 보세요."
38
+ primaryAction={{ label: "검색 초기화", onClick: clearFilters }}
39
+ secondaryAction={{ label: "도움말 보기", href: "/help" }}
40
+ />
41
+ ```
42
+
43
+ | Prop | Type | Default | Description |
44
+ | --- | --- | --- | --- |
45
+ | `illustration` | `string \| ReactNode` | `undefined` | Name from illustration registry (e.g., `"search-empty"`) OR custom node. Omit for compact variant. |
46
+ | `title` | `string` | — | Headline. Required. |
47
+ | `description` | `string \| ReactNode` | — | One-sentence explanation. Optional. |
48
+ | `primaryAction` | `{ label: string; onClick?: () => void; href?: string; loading?: boolean }` | — | Main CTA. Optional. |
49
+ | `secondaryAction` | `{ label: string; onClick?: () => void; href?: string }` | — | Secondary link / button. Optional. |
50
+ | `size` | `"sm" \| "md" \| "lg"` | `"md"` | Visual scale; affects illustration + spacing |
51
+ | `align` | `"center" \| "start"` | `"center"` | Center for full-page; start for inline-in-card |
52
+ | `variant` | `"default" \| "subtle" \| "card"` | `"default"` | Visual treatment |
53
+
54
+ ## Variants
55
+
56
+ ### `default`
57
+
58
+ Full vertical stack with illustration. Used for primary empty surfaces.
59
+
60
+ ### `subtle` (no illustration)
61
+
62
+ Compact — title + description + actions only. For inline empty (within a panel, drawer, or small card).
63
+
64
+ ### `card`
65
+
66
+ Wrapped in a bordered card. Used when the empty state sits next to populated cards (visual consistency).
67
+
68
+ ## Sizes
69
+
70
+ | size | Illustration | Title | Padding |
71
+ | --- | --- | --- | --- |
72
+ | `sm` | 80px (or none) | 16px / 600 | `--space-md` |
73
+ | `md` (default) | 120-160px | 20px / 600 | `--space-lg` |
74
+ | `lg` | 200-240px | 24px / 600 | `--space-xl` |
75
+
76
+ Choose by surface size, not importance:
77
+ - Inline within a small card: `sm`
78
+ - Standard empty page: `md`
79
+ - Onboarding / splash / first-run: `lg`
80
+
81
+ ## States
82
+
83
+ | State | Visual |
84
+ | --- | --- |
85
+ | Default | Illustration + title + description + actions |
86
+ | Loading (CTA loading) | Primary CTA shows spinner; rest unchanged |
87
+ | Compact (inline) | `subtle` variant; no illustration |
88
+ | Truly empty (no actions, no description) | Title only — rare; means user can't act anyway |
89
+
90
+ ## Illustration registry
91
+
92
+ `EmptyState` doesn't render arbitrary SVG. It pulls from a registry keyed by name:
93
+
94
+ ```ts
95
+ // illustrations/empty-state-registry.ts
96
+ export const emptyStateIllustrations = {
97
+ "search-empty": SearchEmptyIllustration,
98
+ "filter-empty": FilterEmptyIllustration,
99
+ "no-projects": NoProjectsIllustration,
100
+ "no-notifications": NoNotificationsIllustration,
101
+ "no-transactions": NoTransactionsIllustration,
102
+ "no-bookmarks": NoBookmarksIllustration,
103
+ } as const;
104
+
105
+ export type EmptyStateIllustration = keyof typeof emptyStateIllustrations;
106
+ ```
107
+
108
+ This forces the team to add an illustration intentionally (TypeScript catches typos) and keeps the registry as a single source of truth.
109
+
110
+ For one-off custom illustrations, pass a node directly:
111
+
112
+ ```tsx
113
+ <EmptyState illustration={<MyCustomSVG />} title="..." />
114
+ ```
115
+
116
+ But prefer extending the registry over passing custom nodes ad-hoc.
117
+
118
+ ## Voice rules
119
+
120
+ | Tone | ✓ | ✗ |
121
+ | --- | --- | --- |
122
+ | Encouraging | "첫 거래를 시작해 보세요" | "거래 내역이 없습니다" |
123
+ | Specific | "다른 키워드로 검색해 보세요" | "결과가 없습니다" |
124
+ | Honest about state | "아직 알림이 없어요" | "받은 알림이 없습니다 (0개)" |
125
+ | Action-oriented | CTA: "프로젝트 만들기" | CTA: "확인" |
126
+
127
+ For Korean fintech: 해요체 (~해요) is friendlier, 합쇼체 (~합니다) is formal. Toss leans 해요체; KakaoBank mixes; banks lean 합쇼체. Default to 해요체 for empty / encouraging moments.
128
+
129
+ ## Tokens consumed
130
+
131
+ ```
132
+ --color-text-primary (title)
133
+ --color-text-secondary (description)
134
+ --color-fg-muted (illustration accent — via currentColor)
135
+ --color-bg-default (default variant bg)
136
+ --color-bg-subtle (subtle / card variant bg)
137
+ --space-md, --space-lg, --space-xl
138
+ --radius-md (card variant)
139
+ --font-size-base, --font-size-lg, --font-size-xl
140
+ --font-weight-semibold (title)
141
+ --max-width-prose (description max-width for readability)
142
+ ```
143
+
144
+ ## Accessibility
145
+
146
+ - Illustration is **decorative** by default: rendered with `aria-hidden="true"`. The title + description carry meaning.
147
+ - If illustration is the only conveyance (rare; only when no text accompanies): pass `illustrationLabel` prop to set `role="img" aria-label="..."`.
148
+ - Title is `<h2>` by default; configurable via `as="h3"` for nested contexts.
149
+ - Empty state should NOT use `role="alert"` or `aria-live` — it's not an alert, just a layout.
150
+ - Primary action gets focus on initial render in modal contexts (matches focus management of the parent modal).
151
+ - Touch targets ≥ 44pt for action buttons.
152
+
153
+ ## Code example
154
+
155
+ ```tsx
156
+ function ProjectsScreen() {
157
+ const { data: projects, isLoading, isError, error } = useProjects();
158
+ const [filters, setFilters] = useFilters();
159
+
160
+ if (isLoading) return <ProjectsSkeleton />;
161
+ if (isError) return <ErrorState error={error} />;
162
+
163
+ if (projects.length === 0 && filters.isEmpty) {
164
+ // First-run empty
165
+ return (
166
+ <EmptyState
167
+ size="lg"
168
+ illustration="no-projects"
169
+ title="첫 프로젝트를 시작해 보세요"
170
+ description="프로젝트를 만들면 팀과 함께 작업할 수 있어요."
171
+ primaryAction={{ label: "프로젝트 만들기", onClick: openCreateProject }}
172
+ secondaryAction={{ label: "예제 살펴보기", href: "/examples" }}
173
+ />
174
+ );
175
+ }
176
+
177
+ if (projects.length === 0) {
178
+ // Filter-induced empty
179
+ return (
180
+ <EmptyState
181
+ illustration="filter-empty"
182
+ title="필터에 맞는 프로젝트가 없어요"
183
+ description="필터 조건을 바꾸거나 초기화해 보세요."
184
+ primaryAction={{ label: "필터 초기화", onClick: () => setFilters({}) }}
185
+ />
186
+ );
187
+ }
188
+
189
+ return <ProjectsList projects={projects} />;
190
+ }
191
+ ```
192
+
193
+ ## Layout (CSS)
194
+
195
+ ```css
196
+ .empty-state {
197
+ display: flex;
198
+ flex-direction: column;
199
+ align-items: center;
200
+ text-align: center;
201
+ padding: var(--space-lg);
202
+ gap: var(--space-md);
203
+ }
204
+
205
+ .empty-state[data-align="start"] {
206
+ align-items: flex-start;
207
+ text-align: left;
208
+ }
209
+
210
+ .empty-state[data-variant="card"] {
211
+ background: var(--color-bg-default);
212
+ border: 1px solid var(--color-border-default);
213
+ border-radius: var(--radius-md);
214
+ }
215
+
216
+ .empty-state[data-variant="subtle"] {
217
+ background: var(--color-bg-subtle);
218
+ border-radius: var(--radius-md);
219
+ }
220
+
221
+ .empty-state__illustration { color: var(--color-brand-default); }
222
+ .empty-state__title { font-size: var(--font-size-lg); font-weight: 600; }
223
+ .empty-state__description {
224
+ font-size: var(--font-size-base);
225
+ color: var(--color-text-secondary);
226
+ max-width: var(--max-width-prose);
227
+ }
228
+ .empty-state__actions {
229
+ display: flex;
230
+ gap: var(--space-sm);
231
+ margin-top: var(--space-sm);
232
+ }
233
+ ```
234
+
235
+ ## Edge cases
236
+
237
+ - **Description longer than 2 lines**: truncate or break into 2 sentences. EmptyState is not a long-form explanation. If you need that, link to docs / help.
238
+ - **Both primary + secondary actions**: layout horizontally on desktop, stacked on mobile.
239
+ - **No illustration registered**: fall back to a generic neutral illustration (`generic-empty`). Don't render the wrapper at illustration size 0.
240
+ - **Loading state inside CTA**: pass `loading: true` to action; button shows spinner; rest of EmptyState is unchanged.
241
+ - **RTL**: layout mirrors automatically via `text-align: start`. Illustrations should be flippable or center-symmetric.
242
+ - **Dark mode**: illustrations theme via `currentColor` + CSS variables. Test all illustrations in dark.
243
+ - **Reduced motion**: if illustration is animated (Lottie), show static frame. See [`examples/component-lottie-player.md`](component-lottie-player.md).
244
+
245
+ ## Don't
246
+
247
+ - Don't use `EmptyState` for errors. That's `ErrorState`. Different voice, different illustration.
248
+ - Don't put 3+ CTAs. Primary + secondary max. More choices = paralysis.
249
+ - Don't write descriptions longer than one sentence.
250
+ - Don't omit the title. "Empty" is unhelpful; "First time? Try X" is helpful.
251
+ - Don't put a mascot doing the same pose in every empty state. Vary the illustration.
252
+ - Don't over-celebrate. "Welcome! No projects yet 🎉" is wrong. The user has nothing yet — guide them.
253
+
254
+ ## References
255
+
256
+ Patterns drawn from:
257
+ - shadcn/ui — no built-in EmptyState, but recipe in docs
258
+ - Mantine `Center + Stack + Text + Button` pattern
259
+ - Ant Design `Empty` component (close upstream match)
260
+ - Toss / KakaoBank empty-state patterns
261
+
262
+ ## Cross-reference
263
+
264
+ - [`knowledge/illustration/spot-illustrations.md`](../knowledge/illustration/spot-illustrations.md) — illustration rules
265
+ - [`knowledge/illustration/illustration-systems.md`](../knowledge/illustration/illustration-systems.md) — system foundation
266
+ - [`examples/component-illustration.md`](component-illustration.md) — generic illustration display
267
+ - [`examples/component-result.md`](component-result.md) — success / error variants (different concern)
268
+ - [`examples/component-lottie-player.md`](component-lottie-player.md) — animated empty illustrations
269
+ - [`knowledge/i18n/korean-document-style.md`](../knowledge/i18n/korean-document-style.md) — 해요체 vs 합쇼체
@@ -0,0 +1,172 @@
1
+ # `Empty` — spec
2
+
3
+ > Synthesized from Ant Design `Empty` and shadcn-ui `empty`. The canonical "no data" placeholder. A simpler primitive than [`EmptyState`](component-empty-state.md) — no illustration registry, no required title/description structure. Use as a building block.
4
+
5
+ ## Empty vs EmptyState
6
+
7
+ | | `Empty` (this spec) | `EmptyState` |
8
+ | --- | --- | --- |
9
+ | Origin | Ant + shadcn primitive | design-ai custom (Korean fintech-aware) |
10
+ | Illustration | Optional, free-form | Registry-backed, typesafe names |
11
+ | Voice rules | None enforced | KR voice + 해요체 default |
12
+ | Use | Inline within a component (table empty, dropdown empty) | Full-page or section-level surfaces |
13
+
14
+ For most pages: use `EmptyState`. For inline empty within a component: use `Empty`.
15
+
16
+ ## Anatomy
17
+
18
+ ```
19
+ [optional image / icon]
20
+
21
+ No data found
22
+
23
+ Try a different search.
24
+ ```
25
+
26
+ ## API
27
+
28
+ ```tsx
29
+ <Empty>
30
+ No items
31
+ </Empty>
32
+
33
+ <Empty
34
+ image={<SearchIcon className="text-muted size-12" />}
35
+ description="No results match your search."
36
+ >
37
+ <Button onClick={clearFilters}>Clear filters</Button>
38
+ </Empty>
39
+
40
+ <Empty image="default">
41
+ No projects yet
42
+ </Empty>
43
+ ```
44
+
45
+ | Prop | Type | Default | Description |
46
+ | --- | --- | --- | --- |
47
+ | `image` | `ReactNode \| "default" \| "presented"` | `"default"` | Visual; `"default"` = generic empty graphic, `"presented"` = simpler, custom node = override |
48
+ | `description` | `ReactNode` | — | Text explanation |
49
+ | `children` | `ReactNode` | — | Action(s) — typically buttons |
50
+ | `imageStyle` | `CSSProperties` | — | Style override on image |
51
+
52
+ ## Variants
53
+
54
+ ### Default (with image)
55
+
56
+ Generic empty illustration above text. Suitable for page-level empty.
57
+
58
+ ### Image-only
59
+
60
+ `image="presented"` shows simpler graphic (often just an icon). Use inline / in dense surfaces.
61
+
62
+ ### No image
63
+
64
+ `image={null}` shows just text. Use for very dense contexts (table cell empty, dropdown "no results").
65
+
66
+ ## States
67
+
68
+ Stateless. Empty is purely presentational.
69
+
70
+ ## Tokens consumed
71
+
72
+ ```
73
+ --color-fg-default (description)
74
+ --color-fg-muted (default image / icon)
75
+ --space-md, --space-lg
76
+ --font-size-sm, --font-size-base
77
+ ```
78
+
79
+ ## Accessibility
80
+
81
+ - Container: `role="status"` so screen reader announces "Empty" content.
82
+ - Image: `aria-hidden="true"` if decorative; `alt` text only if conveying additional meaning.
83
+ - Don't use `role="alert"` — empty isn't an error.
84
+
85
+ ## Use cases
86
+
87
+ ### Inside a Table
88
+
89
+ ```tsx
90
+ <Table>
91
+ <TableBody>
92
+ {rows.length === 0 ? (
93
+ <TableRow>
94
+ <TableCell colSpan={columns.length}>
95
+ <Empty description="No data" />
96
+ </TableCell>
97
+ </TableRow>
98
+ ) : rows.map(...)}
99
+ </TableBody>
100
+ </Table>
101
+ ```
102
+
103
+ ### Inside a Combobox / Dropdown
104
+
105
+ ```tsx
106
+ <Combobox.Empty>
107
+ <Empty image={null} description="No matches" />
108
+ </Combobox.Empty>
109
+ ```
110
+
111
+ ### Inside a List / feed
112
+
113
+ ```tsx
114
+ {notifications.length === 0 && (
115
+ <Empty
116
+ image={<BellIcon className="text-muted size-10" />}
117
+ description="No notifications yet."
118
+ />
119
+ )}
120
+ ```
121
+
122
+ ### Page-level — prefer EmptyState
123
+
124
+ ```tsx
125
+ {/* For full pages, use EmptyState — registry-backed illustrations + Korean voice */}
126
+ <EmptyState
127
+ size="lg"
128
+ illustration="no-projects"
129
+ title="첫 프로젝트를 시작해 보세요"
130
+ description="프로젝트를 만들면 팀과 함께 작업할 수 있어요."
131
+ primaryAction={{ label: "프로젝트 만들기", onClick: createProject }}
132
+ />
133
+ ```
134
+
135
+ See [`component-empty-state.md`](component-empty-state.md).
136
+
137
+ ## Korean conventions
138
+
139
+ For inline `Empty`:
140
+ - "데이터가 없어요" (해요체) / "데이터가 없습니다" (합쇼체)
141
+ - "결과가 없어요" / "결과가 없습니다"
142
+ - "해당하는 항목이 없어요"
143
+
144
+ Match the surrounding component's voice level.
145
+
146
+ ## Edge cases
147
+
148
+ - **Inside a scrollable list**: Empty shouldn't fill the entire scroll viewport (looks broken). Cap at ~200px tall; align to top.
149
+ - **Loading state**: don't show Empty while data is loading — show Skeleton or Spinner instead. Empty is for "loaded with zero results", not "still loading".
150
+ - **Empty in a dropdown / command palette**: keep it brief, no image (single-line is fine).
151
+ - **Action button inside Empty**: works, but consider whether the user can act from this surface OR they need to navigate away. If "Create" works inline → button. If user needs to go to /create → link.
152
+ - **Reduced motion**: not applicable — Empty is static.
153
+ - **Dark mode**: tokens cascade; verify default image SVG visible against dark bg.
154
+
155
+ ## Don't
156
+
157
+ - Don't use Empty for errors. Use Result with status="error" or an error pattern.
158
+ - Don't show Empty before data has loaded. Show loading state first.
159
+ - Don't make inline Empty as large as a full-page EmptyState. Match scale.
160
+ - Don't omit description for non-obvious empty states. Tell users why.
161
+ - Don't put long copy in inline Empty. Keep it < 1 sentence.
162
+
163
+ ## References
164
+
165
+ - Ant: [`Empty`](../refs/ant-design/components/empty)
166
+ - shadcn-ui: [`empty`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/empty.tsx)
167
+
168
+ ## Cross-reference
169
+
170
+ - [`examples/component-empty-state.md`](component-empty-state.md) — full-page custom variant with KR voice + illustration registry
171
+ - [`examples/component-result.md`](component-result.md) — for error / success full-page surfaces
172
+ - [`examples/component-table.md`](component-table.md) — common consumer of inline Empty