@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,266 @@
1
+ # `Carousel` — spec
2
+
3
+ > Citing Ant Design `Carousel`, MUI (no built-in — composition), shadcn-ui `carousel` (Embla)
4
+
5
+ ## Purpose
6
+
7
+ A horizontally rotating sequence of items. Used for: hero banners (marketing), product image galleries, onboarding screens, content highlights.
8
+
9
+ ## When NOT to use a carousel
10
+
11
+ This is the most-misused component on the web. Before reaching for a carousel, ask:
12
+ - **"Will users actually scroll past slide 1?"** — Most don't. Average click-through on slide 2+ is < 5%.
13
+ - **"Is the content equally important?"** — If slide 1 is the priority, kill the carousel; commit to one hero.
14
+ - **"Is this auto-playing?"** — Auto-play hurts a11y, distracts users, and is widely disliked.
15
+
16
+ Use a carousel when:
17
+ - It's a genuine gallery (e.g., product photos — user expects multiple).
18
+ - Content is browsable (testimonials, news highlights — equally weighted).
19
+ - Touch swipe is the intended interaction model (mobile native pattern).
20
+
21
+ Don't use for:
22
+ - Hero banner where one message is the goal (use a single hero).
23
+ - Long-form content (use a list or scroll).
24
+ - Critical conversion elements (most users miss them past slide 1).
25
+
26
+ ## Anatomy
27
+
28
+ ```
29
+ ◀ ┌──────────────────────────────────────┐ ▶
30
+ │ │
31
+ │ Slide 1 of 4 │
32
+ │ │
33
+ │ │
34
+ └──────────────────────────────────────┘
35
+ ● ○ ○ ○ ← dot indicators
36
+ ```
37
+
38
+ | Slot | Required | Notes |
39
+ | --- | --- | --- |
40
+ | Slide content | yes | The items |
41
+ | Previous arrow | usually (desktop) | Hidden on mobile (rely on swipe) |
42
+ | Next arrow | usually (desktop) | |
43
+ | Indicators (dots / numbers / thumbs) | yes for > 1 slide | Shows position + count |
44
+ | Auto-play controls | only if auto-playing | Pause/play button required |
45
+
46
+ ## API
47
+
48
+ ```tsx
49
+ <Carousel
50
+ autoplay={false}
51
+ loop
52
+ showArrows
53
+ showDots
54
+ onSlideChange={setActive}
55
+ >
56
+ <Carousel.Slide>{slide1}</Carousel.Slide>
57
+ <Carousel.Slide>{slide2}</Carousel.Slide>
58
+ <Carousel.Slide>{slide3}</Carousel.Slide>
59
+ </Carousel>
60
+ ```
61
+
62
+ | Prop | Type | Default | Description |
63
+ | --- | --- | --- | --- |
64
+ | `autoplay` | `boolean` | `false` | Auto-advance |
65
+ | `autoplayInterval` | `number` | `5000` | ms between slides |
66
+ | `loop` | `boolean` | `true` | Wrap from last to first |
67
+ | `showArrows` | `boolean` | `true` (desktop) / `false` (mobile) | Prev/next buttons |
68
+ | `showDots` | `boolean` | `true` | Dot indicators |
69
+ | `dotsPosition` | `"bottom" \| "top" \| "side"` | `"bottom"` | |
70
+ | `slidesPerView` | `number` | `1` | Multi-slide view (e.g., 3 product cards visible) |
71
+ | `slidesPerScroll` | `number` | `1` | How many to advance per click |
72
+ | `gap` | `number` | `0` | Space between slides (when slidesPerView > 1) |
73
+ | `swipeable` | `boolean` | `true` (touch) | Touch/drag swipe |
74
+ | `effect` | `"slide" \| "fade"` | `"slide"` | Transition |
75
+ | `value` | `number` | — | Controlled active index |
76
+ | `onSlideChange` | `(index) => void` | — | |
77
+
78
+ ## Behavior
79
+
80
+ ### Navigation
81
+
82
+ - **Arrows** (desktop): click to advance one slide.
83
+ - **Dots**: click any dot to jump to that slide.
84
+ - **Swipe** (touch): horizontal swipe past 50% of slide width advances.
85
+ - **Keyboard**: `←` / `→` when carousel is focused.
86
+ - **Auto-play** (if enabled): advances every `autoplayInterval` ms; pauses on hover or focus inside; resumes on leave.
87
+
88
+ ### Loop vs no loop
89
+
90
+ - `loop: true`: clicking next on last slide goes to first; previous on first goes to last.
91
+ - `loop: false`: arrows disabled at boundary. Last slide visually marks "end".
92
+
93
+ ### Multi-slide view
94
+
95
+ For browse-style carousels (product cards):
96
+
97
+ ```
98
+ slidesPerView: 3
99
+ [card 1] [card 2] [card 3] [card 4 (off-screen)] [card 5 (off-screen)]
100
+ ```
101
+
102
+ Click next: scrolls by `slidesPerScroll` (often 1 for incremental browsing, full = slidesPerView for "page" navigation).
103
+
104
+ ## Sizes
105
+
106
+ Carousel container takes its parent's dimensions. The slide aspect ratio depends on content:
107
+
108
+ | Use | Aspect ratio (desktop) |
109
+ | --- | --- |
110
+ | Hero banner | 16:9 or 21:9 wide |
111
+ | Product gallery | 1:1 (square) |
112
+ | Testimonial cards | 4:3 or 5:3 |
113
+ | Mobile portrait | 4:5 or 9:16 |
114
+
115
+ For responsive: `aspect-ratio: 16 / 9` and `width: 100%` lets it scale.
116
+
117
+ ## States
118
+
119
+ | State | Visual |
120
+ | --- | --- |
121
+ | Settled | Slide visible, indicator highlighted |
122
+ | Sliding | 250–400ms transition (slide or fade) |
123
+ | Auto-advance pause | When user hovers, focuses, or `prefers-reduced-motion` is set |
124
+ | Loading slides (lazy) | Skeleton in slide area until image loads |
125
+
126
+ ## Tokens consumed
127
+
128
+ ```
129
+ --color-bg-default
130
+ --color-text-primary
131
+ --color-text-on-image (text overlay on image carousels)
132
+ --color-bg-overlay (subtle overlay for text legibility)
133
+ --color-primary-default (active dot)
134
+ --color-text-tertiary (inactive dots)
135
+ --space-md
136
+ --radius-md, --radius-lg (rounded slide corners)
137
+ --motion-default, --motion-slow (slide transitions)
138
+ --easing-out
139
+ ```
140
+
141
+ ## Accessibility — high stakes
142
+
143
+ Carousels are notorious for a11y problems. Get these right.
144
+
145
+ ### ARIA
146
+
147
+ - `role="region" aria-roledescription="carousel" aria-label="..."` on the container.
148
+ - Each slide: `role="group" aria-roledescription="slide" aria-label="Slide N of M"`.
149
+ - Hidden slides should have `aria-hidden="true"` and `tabindex="-1"` on focusable elements (so tab doesn't reach off-screen content).
150
+ - Live region: `aria-live="polite"` on the slide container — but only when **not auto-playing** (auto-play would chatter). Set `aria-live="off"` while auto-playing.
151
+
152
+ ### Auto-play
153
+
154
+ - **Don't auto-play by default**. WCAG 2.2.2 requires controls for moving content > 5 seconds.
155
+ - If auto-playing: provide visible Pause/Play button.
156
+ - Pause on hover, focus, and **`prefers-reduced-motion`** — these are not optional.
157
+
158
+ ### Keyboard
159
+
160
+ | Key | Behavior |
161
+ | --- | --- |
162
+ | `Tab` | Reach carousel (arrows + dots are tab stops) |
163
+ | `←` / `→` | Move slide (when carousel is focused) |
164
+ | Inside slide: `Tab` reaches links/buttons in the visible slide only |
165
+
166
+ ### Touch
167
+
168
+ Swipe is a touch convention. For accessibility, ensure arrows are visible OR a clear alternative exists.
169
+
170
+ ## Code example
171
+
172
+ ```tsx
173
+ // Hero banner (no auto-play, single slide visible)
174
+ <Carousel showArrows showDots loop>
175
+ {banners.map(banner => (
176
+ <Carousel.Slide key={banner.id}>
177
+ <BannerSlide banner={banner} />
178
+ </Carousel.Slide>
179
+ ))}
180
+ </Carousel>
181
+
182
+ // Product gallery (multi-slide, no auto-play, no loop)
183
+ <Carousel
184
+ slidesPerView={4}
185
+ slidesPerScroll={1}
186
+ gap={16}
187
+ loop={false}
188
+ showArrows
189
+ showDots={false}
190
+ >
191
+ {products.map(product => (
192
+ <Carousel.Slide key={product.id}>
193
+ <ProductCard product={product} />
194
+ </Carousel.Slide>
195
+ ))}
196
+ </Carousel>
197
+
198
+ // Testimonials with auto-play (carefully)
199
+ <Carousel
200
+ autoplay
201
+ autoplayInterval={6000}
202
+ loop
203
+ showDots
204
+ showArrows
205
+ effect="fade"
206
+ >
207
+ {testimonials.map(t => (
208
+ <Carousel.Slide key={t.id}>
209
+ <TestimonialCard testimonial={t} />
210
+ </Carousel.Slide>
211
+ ))}
212
+ </Carousel>
213
+
214
+ // Image gallery on a product detail page
215
+ <Carousel slidesPerView={1} loop showDots>
216
+ {product.images.map(img => (
217
+ <Carousel.Slide key={img.id}>
218
+ <Image src={img.url} alt={img.alt} />
219
+ </Carousel.Slide>
220
+ ))}
221
+ </Carousel>
222
+ ```
223
+
224
+ ## Mobile-specific behaviors
225
+
226
+ - Arrows hidden by default (rely on swipe).
227
+ - Dots smaller (4–6px).
228
+ - Snap to slide (`scroll-snap-type: x mandatory`).
229
+ - Don't auto-play on mobile — wastes battery, reduces user agency.
230
+
231
+ ## Edge cases
232
+
233
+ - **Single slide**: don't render arrows/dots. Just the slide.
234
+ - **Loading slides** (async): render skeleton until image loads. Don't block carousel rendering.
235
+ - **Different slide heights**: cap with `align-items: center` or set fixed height. Inconsistent heights cause carousel to "jump".
236
+ - **Long text in slides** (testimonials): cap height and add `overflow: scroll` per slide if needed.
237
+ - **Auto-play with focus inside**: pause until focus leaves.
238
+ - **RTL**: arrow icons flip; swipe direction inverts.
239
+ - **No JS / SSR**: render as a horizontal scroll list with snap points. Carousel chrome is enhancement.
240
+
241
+ ## Don't
242
+
243
+ - Don't auto-play by default.
244
+ - Don't use carousel for primary CTAs (most users miss slide 2+).
245
+ - Don't combine fade and slide effects in the same carousel.
246
+ - Don't show 3+ rows of carousels on one page (visual chaos).
247
+ - Don't disable the user's swipe direction (force them to use arrows). Touch users expect swipe.
248
+ - Don't make dots invisible on dark slides — ensure 3:1 contrast.
249
+ - Don't put videos in auto-playing carousels — accessibility nightmare.
250
+
251
+ ## References
252
+
253
+ - Ant Design: [`refs/ant-design/components/carousel/`](../refs/ant-design/components/carousel/) — `Carousel`. Wraps `react-slick`. Has `autoplay`, `dots`, `effect`. Solid baseline.
254
+ - MUI: no dedicated component. Use `react-slick` or `swiper`.
255
+ - shadcn-ui: [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/carousel.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/carousel.tsx) — wraps **Embla** carousel. Modern, framework-agnostic, excellent accessibility. **Default for new projects.**
256
+
257
+ API choices made:
258
+ - **`autoplay: false` default**: matches a11y best practice. Most carousels don't need it.
259
+ - **`slidesPerView` exposed**: covers product gallery use case without separate component.
260
+ - **`effect`**: fade for hero (each slide is the message), slide for sequential browsing.
261
+
262
+ ## Cross-reference
263
+
264
+ - [`knowledge/motion/principles.md`](../knowledge/motion/principles.md) — auto-play + reduced motion
265
+ - [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md) — carousel keyboard contract
266
+ - [WAI-ARIA Carousel Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/)
@@ -0,0 +1,135 @@
1
+ # `Cascader` — spec
2
+
3
+ > Citing Ant Design `Cascader`, MUI (no built-in — composition), shadcn-ui (no built-in)
4
+
5
+ ## Purpose
6
+
7
+ Multi-level select. User picks a leaf value by drilling through hierarchical levels. Used for: address (state → city → district), category trees (electronics → phones → models), org structure.
8
+
9
+ ## When Cascader vs alternatives
10
+
11
+ | Pattern | Use |
12
+ | --- | --- |
13
+ | **Cascader** | Hierarchical with 2–4 fixed levels; user picks ONE leaf |
14
+ | **Tree (with select)** | Variable depth, user might pick any node |
15
+ | **Cascader → drill-in screens** | Mobile, when each level needs more space |
16
+ | **Three Selects in a row** | When levels are independent (e.g., size, color, material — pick all three) |
17
+
18
+ ## Anatomy
19
+
20
+ ```
21
+ Trigger: Open (3-level cascade):
22
+ ┌──────────────────────┐ ┌──────┬──────┬──────┐
23
+ │ 서울 / 강남구 / 역삼동 ▾│ │ 서울 │ 강남구│ 역삼동│
24
+ └──────────────────────┘ │ 부산 │ 서초구│ 청담동│
25
+ │ 인천 │ 송파구│ 삼성동│
26
+ └──────┴──────┴──────┘
27
+ ```
28
+
29
+ | Slot | Required | Notes |
30
+ | --- | --- | --- |
31
+ | Trigger | yes | Shows full path or placeholder |
32
+ | Per-level panel | yes | Each level renders its options |
33
+ | Hover/click expand | yes | Hovering a parent expands its children |
34
+ | Search input | optional | Searches across all levels |
35
+
36
+ ## API
37
+
38
+ ```tsx
39
+ <Cascader
40
+ value={["seoul", "gangnam", "yeoksam"]}
41
+ onValueChange={setValue}
42
+ options={addressTree}
43
+ separator=" / "
44
+ searchable
45
+ />
46
+
47
+ // where addressTree is:
48
+ type CascaderOption = {
49
+ value: string;
50
+ label: string;
51
+ children?: CascaderOption[];
52
+ disabled?: boolean;
53
+ isLeaf?: boolean;
54
+ };
55
+ ```
56
+
57
+ | Prop | Type | Default | Description |
58
+ | --- | --- | --- | --- |
59
+ | `value` | `string[]` | — | Path to selected leaf (level values in order) |
60
+ | `onValueChange` | `(value: string[], path: CascaderOption[]) => void` | — | |
61
+ | `options` | `CascaderOption[]` | — | Hierarchical data |
62
+ | `separator` | `string` | `" / "` | Display separator in trigger |
63
+ | `placeholder` | `string` | — | When empty |
64
+ | `searchable` | `boolean` | `false` | Cross-level search |
65
+ | `expandTrigger` | `"click" \| "hover"` | `"click"` | How to expand levels |
66
+ | `changeOnSelect` | `boolean` | `false` | Allow selection at non-leaf levels |
67
+ | `showFullPath` | `boolean` | `true` | In trigger: full path vs leaf-only |
68
+ | `loadData` | `(option) => Promise<CascaderOption[]>` | — | Async lazy-load children |
69
+ | `disabled` | `boolean` | `false` | |
70
+ | `error` / `errorText` | — | — | |
71
+
72
+ ## Behavior
73
+
74
+ - **Click a parent**: expands children to its right.
75
+ - **Click a leaf**: selects, closes popover.
76
+ - **`changeOnSelect`**: allows selecting at any level. Triggers `onValueChange` on every click.
77
+ - **Search mode**: input at top of popover; results show full paths matching query, flattened.
78
+
79
+ ## States
80
+
81
+ | State | Visual |
82
+ | --- | --- |
83
+ | Default trigger | Placeholder or value path |
84
+ | Open | Popover with N panels visible |
85
+ | Hover row | Highlighted; if has children, panel to right opens |
86
+ | Selected leaf | Filled bg, checkmark |
87
+ | Loading (async) | Spinner in current panel |
88
+
89
+ ## Accessibility
90
+
91
+ - Trigger: `role="combobox"`, `aria-expanded`, `aria-haspopup="tree"`, `aria-controls`.
92
+ - Each panel: `role="listbox"` (or "tree" for accessibility tools).
93
+ - Each option: `role="option"`, `aria-selected`, `aria-haspopup="listbox"` if has children.
94
+
95
+ ### Keyboard
96
+
97
+ | Key | Behavior |
98
+ | --- | --- |
99
+ | `Tab` | Reach trigger |
100
+ | `Enter` / `Space` | Open popover |
101
+ | `↑` / `↓` | Move within current panel |
102
+ | `→` | Expand to next panel (if has children) |
103
+ | `←` | Back to previous panel |
104
+ | `Enter` (on leaf) | Select |
105
+ | `Esc` | Close |
106
+
107
+ ## Mobile pattern
108
+
109
+ Cascader's horizontal panel UI breaks on mobile. Switch to a **drill-in screen pattern**:
110
+
111
+ ```
112
+ [Tap trigger] → [Level 1 list screen] → [Level 2 list] → [Level 3 list] → [back to form]
113
+ ```
114
+
115
+ Each level is a full-screen list with a back button. Visual breadcrumb at top: "서울 > 강남구 > ..."
116
+
117
+ For Korean address: combine with Daum Postcode (more user-friendly for actual addresses) — see [`component-address-input.md`](component-address-input.md).
118
+
119
+ ## Don't
120
+
121
+ - Don't use Cascader for non-hierarchical multi-select. Use a Tree.
122
+ - Don't use for 5+ levels — too deep; user gets lost.
123
+ - Don't use for hierarchies that change frequently (categories that move). Tree handles dynamic shape better.
124
+ - Don't combine `changeOnSelect` with deep hierarchies — user accidentally selects at level 1.
125
+
126
+ ## References
127
+
128
+ - Ant Design: [`refs/ant-design/components/cascader/`](../refs/ant-design/components/cascader/) — `Cascader` with full feature set. Most exhaustive.
129
+ - MUI / shadcn-ui: no built-in. Compose from Select-like primitives.
130
+
131
+ ## Cross-reference
132
+
133
+ - [`examples/component-tree.md`](component-tree.md) — when hierarchy is variable depth
134
+ - [`examples/component-select.md`](component-select.md) — flat alternative
135
+ - [`examples/component-address-input.md`](component-address-input.md) — Korean address pattern using Daum Postcode
@@ -0,0 +1,271 @@
1
+ # `CategoryPicker` (custom — Korean fintech / 가계부) — spec
2
+
3
+ > Custom component pattern. Universal in Korean 가계부 (personal finance / expense tracker) apps. Not in any upstream design system.
4
+
5
+ ## Purpose
6
+
7
+ Lets the user pick a category for a transaction (식비 / 교통 / 쇼핑 / etc.). Uses **emoji + Korean label** as the category visual identity — distinctive Korean app convention.
8
+
9
+ ## Anatomy
10
+
11
+ ```
12
+ Horizontal scrollable pills (default):
13
+ ┌───────────────────────────────────────────────────────┐
14
+ │ [🍽 식비] [🚌 교통] [🛍 쇼핑] [🏠 주거] [💊 건강] │
15
+ └───────────────────────────────────────────────────────┘
16
+ ↑ active (filled bg)
17
+
18
+ Grid (alternative for many categories):
19
+ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
20
+ │ 🍽 │ │ 🚌 │ │ 🛍 │ │ 🏠 │
21
+ │ 식비 │ │ 교통 │ │ 쇼핑 │ │ 주거 │
22
+ └────────┘ └────────┘ └────────┘ └────────┘
23
+ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
24
+ │ 💊 │ │ 🎬 │ │ ✈ │ │ + │
25
+ │ 건강 │ │ 엔터 │ │ 여행 │ │ 추가 │
26
+ └────────┘ └────────┘ └────────┘ └────────┘
27
+ ```
28
+
29
+ | Slot | Required | Notes |
30
+ | --- | --- | --- |
31
+ | Category icon | yes | Emoji or pictogram (Korean 가계부 apps overwhelmingly use emoji) |
32
+ | Category label | yes | Korean term |
33
+ | "Add custom" affordance | optional | Lets user create their own category |
34
+ | Search / filter | optional | For 30+ categories |
35
+
36
+ ## API
37
+
38
+ ```tsx
39
+ <CategoryPicker
40
+ value={categoryId}
41
+ onValueChange={setCategoryId}
42
+ categories={[
43
+ { id: "food", icon: "🍽", label: "식비" },
44
+ { id: "transport", icon: "🚌", label: "교통" },
45
+ { id: "shopping", icon: "🛍", label: "쇼핑" },
46
+ // ...
47
+ ]}
48
+ layout="horizontal"
49
+ allowCustom
50
+ onCustomAdd={(name, icon) => addCategory({ name, icon })}
51
+ />
52
+ ```
53
+
54
+ | Prop | Type | Default | Description |
55
+ | --- | --- | --- | --- |
56
+ | `value` | `string \| null` | — | Selected category id |
57
+ | `onValueChange` | `(id: string \| null) => void` | — | |
58
+ | `categories` | `Category[]` | — | List of categories |
59
+ | `layout` | `"horizontal" \| "grid" \| "list"` | `"horizontal"` | |
60
+ | `allowCustom` | `boolean` | `false` | Show "+ 추가" button |
61
+ | `onCustomAdd` | `(name: string, icon: string) => void` | — | Open modal to create new |
62
+ | `searchable` | `boolean` | `false` | Search input above |
63
+ | `disabled` | `boolean` | `false` | |
64
+ | `size` | `"sm" \| "md" \| "lg"` | `"md"` | |
65
+
66
+ ```ts
67
+ type Category = {
68
+ id: string;
69
+ icon: string; // Emoji or icon name
70
+ label: string; // Korean
71
+ color?: string; // Optional bg tint
72
+ isCustom?: boolean; // User-created
73
+ };
74
+ ```
75
+
76
+ ## Default categories (Korean 가계부 standard)
77
+
78
+ Korean apps converge on this categorization. Use as a starting point:
79
+
80
+ | ID | Emoji | Korean | English |
81
+ | --- | --- | --- | --- |
82
+ | `food` | 🍽 | 식비 | Food |
83
+ | `cafe` | ☕ | 카페 / 간식 | Cafe / Snack |
84
+ | `transport` | 🚌 | 교통 | Transport |
85
+ | `shopping` | 🛍 | 쇼핑 | Shopping |
86
+ | `housing` | 🏠 | 주거 | Housing |
87
+ | `utilities` | 💡 | 공과금 | Utilities |
88
+ | `health` | 💊 | 건강 / 의료 | Health |
89
+ | `entertainment` | 🎬 | 엔터테인먼트 | Entertainment |
90
+ | `education` | 📚 | 교육 | Education |
91
+ | `travel` | ✈ | 여행 | Travel |
92
+ | `gift` | 🎁 | 선물 / 경조사 | Gift / Ceremony |
93
+ | `subscription` | 📺 | 구독 | Subscription |
94
+ | `salary` | 💰 | 급여 | Income — salary |
95
+ | `bonus` | 💵 | 부수입 | Income — side |
96
+ | `investment` | 📈 | 투자 | Investment |
97
+ | `other` | ✨ | 기타 | Other |
98
+
99
+ Income vs expense: usually two separate `CategoryPicker` instances OR a single picker with type filter.
100
+
101
+ ## Layouts
102
+
103
+ ### Horizontal scrollable pills (default for mobile)
104
+
105
+ Best for 6–12 categories. User swipes horizontally to see more.
106
+
107
+ ```
108
+ [🍽 식비] [🚌 교통] [🛍 쇼핑] ...→
109
+ ```
110
+
111
+ ### Grid (4-column on mobile, 6-column on tablet+)
112
+
113
+ Best for 12+ categories. All visible at once.
114
+
115
+ ### List (vertical)
116
+
117
+ Best for accessibility / dense desktop forms.
118
+
119
+ ## States
120
+
121
+ | State | Visual |
122
+ | --- | --- |
123
+ | Default (unselected) | Outline border, neutral bg |
124
+ | Hover | Slight bg shift |
125
+ | Selected | Filled bg `--color-primary-subtle-bg`, border `--color-primary-default`, text `--color-primary-default` |
126
+ | Custom (user-added) | Same as default but with subtle "edit" icon on hover |
127
+ | Disabled | Muted, no events |
128
+
129
+ ## Tokens consumed
130
+
131
+ ```
132
+ --color-bg-default
133
+ --color-bg-subtle
134
+ --color-primary-subtle-bg (selected bg)
135
+ --color-primary-default (selected border + text)
136
+ --color-text-primary
137
+ --color-text-secondary
138
+ --color-border-default
139
+ --color-focus-ring
140
+ --space-xs, --space-sm, --space-md
141
+ --radius-md, --radius-full (pill style for horizontal)
142
+ --font-size-sm
143
+ ```
144
+
145
+ ## Sizes
146
+
147
+ | Size | Pill height | Icon | Font |
148
+ | --- | --- | --- | --- |
149
+ | `sm` | 32px | 16px | 12px |
150
+ | `md` (default) | 40px | 20px | 14px |
151
+ | `lg` | 48px | 24px | 16px |
152
+
153
+ For grid layout: each cell is square (e.g., 80×80 for `md`), with icon on top + label below.
154
+
155
+ ## Accessibility
156
+
157
+ - Container: `role="radiogroup"`, `aria-label="카테고리 선택"`.
158
+ - Each category: `role="radio"`, `aria-checked={value === id}`.
159
+ - Emoji icons: `aria-hidden="true"` (the label carries meaning for screen readers).
160
+ - "+ 추가" button: standard `<button>` with `aria-label="새 카테고리 추가"`.
161
+
162
+ ### Keyboard
163
+
164
+ | Key | Behavior |
165
+ | --- | --- |
166
+ | `Tab` | Reach the active category (single tab stop) |
167
+ | `←` / `→` (horizontal) or `↑` / `↓` (grid) | Move + select next |
168
+ | `Home` / `End` | First / last |
169
+ | `Space` / `Enter` | Activate (or auto-activate on focus, configurable) |
170
+
171
+ ## Korean conventions
172
+
173
+ - **Emoji is mandatory**, not decorative. Korean users associate emoji with categories — text-only feels sterile.
174
+ - **Label is short** — 1-3 syllables typically. "식비", "교통", "쇼핑".
175
+ - **Income categories use 💰 / 💵 / 📈 family**; expense uses everything else.
176
+ - **Subscription** (구독) is a major Korean fintech category — Netflix, YouTube Premium, music services.
177
+ - **경조사** (special-occasion gifts: weddings, funerals, holidays) is a uniquely Korean expense category — not in Western 가계부 apps.
178
+
179
+ ## Custom category creation
180
+
181
+ When user clicks "+ 추가":
182
+
183
+ ```
184
+ ┌──────────────────────────────────┐
185
+ │ 새 카테고리 │
186
+ │ │
187
+ │ 이름: [____________] │
188
+ │ 아이콘: [😀] (tap to change) │
189
+ │ │
190
+ │ 색상: ● ● ● ● ● │
191
+ │ │
192
+ │ [취소] [추가] │
193
+ └──────────────────────────────────┘
194
+ ```
195
+
196
+ - Name (required): Korean, 1-10 chars.
197
+ - Icon (emoji picker — use system emoji picker or grid of common ones).
198
+ - Color (optional): bg tint for visual distinction.
199
+
200
+ Save to user-scoped storage (server-side typically, with sync).
201
+
202
+ ## Code example
203
+
204
+ ```tsx
205
+ function TransactionForm() {
206
+ const [categoryId, setCategoryId] = useState<string | null>(null);
207
+ const categories = useCategories();
208
+ const [createOpen, setCreateOpen] = useState(false);
209
+
210
+ return (
211
+ <Form>
212
+ <Form.Field name="amount">
213
+ <AmountInput value={amount} onValueChange={setAmount} />
214
+ </Form.Field>
215
+
216
+ <Form.Field name="category">
217
+ <Form.Label>카테고리</Form.Label>
218
+ <CategoryPicker
219
+ value={categoryId}
220
+ onValueChange={setCategoryId}
221
+ categories={categories}
222
+ layout="horizontal"
223
+ allowCustom
224
+ onCustomAdd={() => setCreateOpen(true)}
225
+ />
226
+ <Form.ErrorText />
227
+ </Form.Field>
228
+
229
+ <CreateCategoryModal
230
+ open={createOpen}
231
+ onOpenChange={setCreateOpen}
232
+ onSave={(c) => {
233
+ createCategory(c);
234
+ setCategoryId(c.id);
235
+ }}
236
+ />
237
+ </Form>
238
+ );
239
+ }
240
+ ```
241
+
242
+ ## Edge cases
243
+
244
+ - **Many custom categories** (50+): switch to grid layout + search.
245
+ - **No selection allowed** (clear): show null state, `value={null}`.
246
+ - **Income vs expense**: filter list based on transaction type. Don't show `food` for income.
247
+ - **Emoji rendering inconsistency** (Apple vs Android vs Web): emoji are rendered by OS; minor visual differences across platforms are acceptable.
248
+ - **Korean accessibility**: aria-checked state needs Korean translation if assistive tech localized.
249
+
250
+ ## Don't
251
+
252
+ - Don't use category icons without labels — Korean users want to see "식비" written out.
253
+ - Don't omit emoji — text-only categorization feels lifeless to Korean users.
254
+ - Don't use Western category emoji standards (🍔 for food). Use 🍽 for "Korean meal" feel.
255
+ - Don't pre-select a default category. Let the user pick — wrong default is annoying.
256
+ - Don't allow > 30 categories without search. Cognitive overload.
257
+
258
+ ## References
259
+
260
+ No upstream component is exactly this. Closest analogs:
261
+ - Ant Design: `Tag` checkable mode (but no emoji-first design)
262
+ - MUI: `Chip` with avatar (similar idea)
263
+
264
+ This is a **Korean-market-specific custom pattern**.
265
+
266
+ ## Cross-reference
267
+
268
+ - [`knowledge/i18n/korean-product-conventions.md`](../knowledge/i18n/korean-product-conventions.md) — Korean app conventions
269
+ - [`examples/component-amount-input.md`](component-amount-input.md) — paired in transaction forms
270
+ - [`examples/component-form.md`](component-form.md) — form orchestration
271
+ - [`knowledge/patterns/form-design.md`](../knowledge/patterns/form-design.md)