@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,145 @@
1
+ # `OutlinedInput` — spec
2
+
3
+ > Synthesized from MUI `OutlinedInput`. The outlined-border input variant — clearer affordance than filled or underline. Default for most product UIs.
4
+
5
+ ## When to use
6
+
7
+ - Default form input for product UIs.
8
+ - When users need a clear "this is a field" affordance (vs filled which can blend into card backgrounds).
9
+ - For dense forms with many fields, consider `FilledInput` (less visual noise) — but accessibility default is outlined.
10
+
11
+ ## Anatomy
12
+
13
+ ```
14
+ ┌── Label ─────────────┐
15
+ │ Input value │ ← label notches the border on focus
16
+ └──────────────────────┘
17
+ ```
18
+
19
+ ## API
20
+
21
+ ```tsx
22
+ <FormControl variant="outlined" fullWidth>
23
+ <FormLabel htmlFor="email">이메일</FormLabel>
24
+ <OutlinedInput
25
+ id="email"
26
+ type="email"
27
+ value={email}
28
+ onChange={(e) => setEmail(e.target.value)}
29
+ placeholder="hong@example.com"
30
+ startAdornment={<InputAdornment position="start"><EmailIcon /></InputAdornment>}
31
+ />
32
+ </FormControl>
33
+ ```
34
+
35
+ | Prop | Type | Default | Description |
36
+ | --- | --- | --- | --- |
37
+ | `value` / `defaultValue` | `string` | — | Controlled / uncontrolled |
38
+ | `onChange` | `(e) => void` | — | Change handler |
39
+ | `type` | `string` | `'text'` | HTML input type |
40
+ | `placeholder` | `string` | — | Placeholder (NOT a substitute for label) |
41
+ | `startAdornment` | `ReactNode` | — | Leading content (icon, prefix) |
42
+ | `endAdornment` | `ReactNode` | — | Trailing content (clear button, unit) |
43
+ | `multiline` | `boolean` | `false` | Render as textarea |
44
+ | `rows` | `number` | — | Multi-line height |
45
+ | `maxRows` / `minRows` | `number` | — | Auto-resize bounds |
46
+ | `disabled` | `boolean` | `false` | |
47
+ | `error` | `boolean` | inherited | From parent FormControl |
48
+ | `fullWidth` | `boolean` | inherited | |
49
+ | `inputProps` | `InputHTMLAttributes` | — | Pass-through to native input (autoComplete, inputMode, pattern) |
50
+ | `inputRef` | `Ref` | — | Ref to native input |
51
+ | `notched` | `boolean` | derived | Notch label-cutout (auto when label is visible) |
52
+
53
+ ## States
54
+
55
+ | State | Visual |
56
+ | --- | --- |
57
+ | Default | 1px border-default |
58
+ | Hover | border-strong |
59
+ | Focus | 2px brand border, label fg-primary |
60
+ | Error | 2px error border, label fg-error |
61
+ | Disabled | muted border, muted fg |
62
+ | Read-only | same as default but no caret |
63
+
64
+ ## Tokens consumed
65
+
66
+ ```
67
+ --input-border-default
68
+ --input-border-hover
69
+ --input-border-focus /* brand */
70
+ --input-border-error
71
+ --input-bg /* surface */
72
+ --input-radius
73
+ --input-padding-x
74
+ --input-min-height-40 /* touch-friendly */
75
+ --input-min-height-32 /* small */
76
+ --font-size-body
77
+ --space-sm /* gap to adornment */
78
+ ```
79
+
80
+ ## Accessibility
81
+
82
+ - Pair with `FormLabel` via `id` ↔ `htmlFor`.
83
+ - For required: `aria-required="true"` (in addition to FormControl `required` for the visual asterisk).
84
+ - For error: `aria-invalid="true"` + `aria-describedby` matching FormHelperText `id`.
85
+ - Touch target: 40px min (default `medium` size). For dense forms `small` (32px) — desktop only.
86
+ - `inputProps={{ autoComplete: '...' }}` — set semantically (`email`, `name`, `tel`, `address-line1`, etc.) so password managers and autofill work.
87
+
88
+ ## Edge cases
89
+
90
+ - **Korean IME composition** — `onChange` fires on each keystroke including IME composition characters. For "search-as-you-type" scenarios that should wait for committed input, use `onCompositionEnd`. Cite [`knowledge/i18n/korean-typography.md`](../knowledge/i18n/korean-typography.md).
91
+ - **Long values** — input scrolls horizontally inside the field. For multi-line, set `multiline maxRows={4}`.
92
+ - **Clear button** — not built-in. Add via `endAdornment` with a small IconButton; show only when `value.length > 0`.
93
+ - **Password visibility toggle** — same pattern: `endAdornment` IconButton that toggles `type` between `password` and `text`.
94
+
95
+ ## Code example
96
+
97
+ ```tsx
98
+ function PasswordField({ value, onChange, error }) {
99
+ const [show, setShow] = useState(false);
100
+
101
+ return (
102
+ <FormControl error={!!error} fullWidth>
103
+ <FormLabel htmlFor="pw">비밀번호</FormLabel>
104
+ <OutlinedInput
105
+ id="pw"
106
+ type={show ? 'text' : 'password'}
107
+ value={value}
108
+ onChange={(e) => onChange(e.target.value)}
109
+ inputProps={{ autoComplete: 'current-password', minLength: 8 }}
110
+ endAdornment={
111
+ <InputAdornment position="end">
112
+ <IconButton
113
+ aria-label={show ? '비밀번호 숨기기' : '비밀번호 보기'}
114
+ onClick={() => setShow(!show)}
115
+ edge="end"
116
+ >
117
+ {show ? <VisibilityOffIcon /> : <VisibilityIcon />}
118
+ </IconButton>
119
+ </InputAdornment>
120
+ }
121
+ />
122
+ <FormHelperText>{error ?? '8자 이상, 영문 + 숫자 + 특수문자'}</FormHelperText>
123
+ </FormControl>
124
+ );
125
+ }
126
+ ```
127
+
128
+ ## Don't
129
+
130
+ - Don't use `placeholder` as the only label — disappears on focus, accessibility issue.
131
+ - Don't omit `autoComplete` — autofill won't work, slowing user-friction in onboarding.
132
+ - Don't toggle `disabled` based on transient state without restoring focus on re-enable.
133
+
134
+ ## References
135
+
136
+ - MUI: [`OutlinedInput`](../refs/mui/packages/mui-material/src/OutlinedInput/) + [`InputBase`](../refs/mui/packages/mui-material/src/InputBase/)
137
+
138
+ ## Cross-reference
139
+
140
+ - [`component-input.md`](component-input.md)
141
+ - [`component-input-base.md`](component-input-base.md)
142
+ - [`component-filled-input.md`](component-filled-input.md)
143
+ - [`component-input-adornment.md`](component-input-adornment.md)
144
+ - [`component-form-control.md`](component-form-control.md)
145
+ - [`knowledge/patterns/form-design.md`](../knowledge/patterns/form-design.md)
@@ -0,0 +1,281 @@
1
+ <!-- hand-written -->
2
+ # `PageTransition` (custom — route-level animation wrapper) — spec
3
+
4
+ > Wraps the route outlet of an SPA to animate transitions between pages. One component handles cross-fade, slide-in, and shared-element variants. Pairs with [`knowledge/motion/app-loading-sequences.md`](../knowledge/motion/app-loading-sequences.md) and [`knowledge/motion/choreography-depth.md`](../knowledge/motion/choreography-depth.md).
5
+
6
+ ## Purpose
7
+
8
+ - Smooth transitions between routes without per-page boilerplate.
9
+ - One opinion per app (cross-fade vs slide vs hero), not per-screen ad-hoc choices.
10
+ - Reduced-motion safe.
11
+ - Compatible with React Router, TanStack Router, Next.js App Router.
12
+
13
+ Without this: route change is an instant DOM swap. Reads as a page reload, breaks spatial sense.
14
+
15
+ ## Anatomy
16
+
17
+ ```
18
+ <RootLayout>
19
+ <Header />
20
+ <PageTransition variant="fade">
21
+ {/* current route */}
22
+ <Outlet />
23
+ </PageTransition>
24
+ <Footer />
25
+ </RootLayout>
26
+ ```
27
+
28
+ Or for slide-style native iOS feel:
29
+
30
+ ```
31
+ <PageTransition variant="slide" direction={navDirection}>
32
+ <Outlet />
33
+ </PageTransition>
34
+ ```
35
+
36
+ ## API
37
+
38
+ ```tsx
39
+ <PageTransition
40
+ variant="fade" // "fade" | "slide" | "hero"
41
+ routeKey={pathname} // change → trigger transition
42
+ direction="forward" // for slide variant
43
+ duration={200}
44
+ reducedMotionFallback="instant" // "instant" | "fade-only"
45
+ >
46
+ {children}
47
+ </PageTransition>
48
+ ```
49
+
50
+ | Prop | Type | Default | Description |
51
+ | --- | --- | --- | --- |
52
+ | `variant` | `"fade" \| "slide" \| "hero"` | `"fade"` | Transition style |
53
+ | `routeKey` | `string` | — | Unique key per route (typically pathname); change = transition |
54
+ | `direction` | `"forward" \| "back"` | `"forward"` | Slide direction (slide variant only) |
55
+ | `duration` | `number` | `200` | Ms; capped at 300 even if higher passed |
56
+ | `easing` | `string` | `"ease-out"` | CSS easing (typically `var(--ease-out)`) |
57
+ | `reducedMotionFallback` | `"instant" \| "fade-only"` | `"fade-only"` | What to do when user prefers reduced motion |
58
+ | `onTransitionEnd` | `() => void` | — | Fires after exit + enter complete |
59
+ | `children` | `ReactNode` | — | Current route content |
60
+
61
+ ## Variants
62
+
63
+ ### `fade` (default)
64
+
65
+ 200ms cross-fade. Calm, content-led. Default for content apps (docs, dashboards, forms).
66
+
67
+ ```css
68
+ .page--enter { opacity: 0; transform: translateY(8px); }
69
+ .page--enter-active { opacity: 1; transform: translateY(0); transition: 200ms ease-out; }
70
+ .page--exit { opacity: 1; }
71
+ .page--exit-active { opacity: 0; transition: 150ms ease-out; }
72
+ ```
73
+
74
+ ### `slide` (native iOS feel)
75
+
76
+ New page slides in from right (forward) or left (back). Old page slides off the opposite side.
77
+
78
+ ```
79
+ forward: [old]────► offscreen left [new]◄──── from right
80
+ back: [old]────► offscreen right [new]◄──── from left
81
+ ```
82
+
83
+ For slide direction tracking, expose it via router state (e.g. `useNavigationDirection()` hook returning `"forward" | "back"`).
84
+
85
+ ### `hero` (shared element)
86
+
87
+ Uses View Transitions API or Framer Motion `layoutId`. An element on outgoing page morphs into an element on incoming page.
88
+
89
+ ```tsx
90
+ // On screen A:
91
+ <motion.img layoutId="user-avatar-42" src={avatar} />
92
+
93
+ // On screen B (detail view):
94
+ <motion.img layoutId="user-avatar-42" src={avatar} />
95
+ // Same id = morph between positions
96
+ ```
97
+
98
+ For browser-native (Chrome / Edge / Safari TP):
99
+
100
+ ```css
101
+ .user-avatar { view-transition-name: user-avatar-42; }
102
+ ```
103
+
104
+ ```js
105
+ document.startViewTransition(() => {
106
+ navigate("/users/42");
107
+ });
108
+ ```
109
+
110
+ ## States
111
+
112
+ | State | Visual |
113
+ | --- | --- |
114
+ | `idle` | Current route fully visible |
115
+ | `exiting` | Outgoing page transitioning out (opacity fade or x-translate) |
116
+ | `entering` | Incoming page transitioning in |
117
+ | `done` | New route fully visible; `onTransitionEnd` fires |
118
+
119
+ `exiting` and `entering` overlap during cross-fade; for slide they sequence.
120
+
121
+ ## Tokens consumed
122
+
123
+ ```
124
+ --motion-fast (150ms exit)
125
+ --motion-medium (200ms enter)
126
+ --motion-slow (300ms slide)
127
+ --ease-out (default)
128
+ --ease-in-out (slide)
129
+ --space-sm (translate-Y for fade)
130
+ ```
131
+
132
+ ## Behavior rules
133
+
134
+ - **Don't transition on initial mount** — first render is not a navigation. Watch for `routeKey` change after mount only.
135
+ - **Don't transition between hash changes** on same path (`/page#a` → `/page#b`).
136
+ - **Cancel previous transition** if route changes mid-transition (rapid back-tap during animation). Snap to new route.
137
+ - **Maintain scroll position**: page-transition wrapper does NOT manage scroll; router does. But the wrapper must not interfere (e.g., `overflow: hidden` on root breaks scroll-restoration).
138
+
139
+ ## Reduced motion
140
+
141
+ ```tsx
142
+ const reduced = useReducedMotion();
143
+ const effectiveVariant = reduced
144
+ ? (reducedMotionFallback === "instant" ? null : "fade")
145
+ : variant;
146
+ ```
147
+
148
+ | Setting | Behavior |
149
+ | --- | --- |
150
+ | `instant` | No transition; instant DOM swap |
151
+ | `fade-only` (default) | Cross-fade at duration 100ms regardless of variant; no translate / slide |
152
+
153
+ Slide and hero variants both downgrade to fade-only — translation triggers vestibular issues.
154
+
155
+ ## Implementation — Framer Motion
156
+
157
+ ```tsx
158
+ import { AnimatePresence, motion } from "framer-motion";
159
+
160
+ function PageTransition({ children, routeKey, variant = "fade", duration = 200 }: Props) {
161
+ const reduced = useReducedMotion();
162
+
163
+ const variants = reduced
164
+ ? { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 } }
165
+ : variantsByName[variant];
166
+
167
+ return (
168
+ <AnimatePresence mode="wait" initial={false}>
169
+ <motion.div
170
+ key={routeKey}
171
+ initial={variants.initial}
172
+ animate={variants.animate}
173
+ exit={variants.exit}
174
+ transition={{ duration: duration / 1000, ease: "easeOut" }}
175
+ >
176
+ {children}
177
+ </motion.div>
178
+ </AnimatePresence>
179
+ );
180
+ }
181
+
182
+ const variantsByName = {
183
+ fade: {
184
+ initial: { opacity: 0, y: 8 },
185
+ animate: { opacity: 1, y: 0 },
186
+ exit: { opacity: 0, y: -8 },
187
+ },
188
+ slide: {
189
+ initial: { opacity: 0, x: 24 },
190
+ animate: { opacity: 1, x: 0 },
191
+ exit: { opacity: 0, x: -24 },
192
+ },
193
+ // hero handled via layoutId on individual elements; this wrapper just cross-fades the rest
194
+ hero: {
195
+ initial: { opacity: 0 },
196
+ animate: { opacity: 1 },
197
+ exit: { opacity: 0 },
198
+ },
199
+ };
200
+ ```
201
+
202
+ ## Implementation — View Transitions API (modern web)
203
+
204
+ ```tsx
205
+ function PageTransition({ children, routeKey }: Props) {
206
+ const previousKey = useRef(routeKey);
207
+
208
+ useLayoutEffect(() => {
209
+ if (previousKey.current === routeKey) return;
210
+ if (!document.startViewTransition) {
211
+ previousKey.current = routeKey;
212
+ return;
213
+ }
214
+ document.startViewTransition(() => {
215
+ previousKey.current = routeKey;
216
+ // React already updated; this just signals the browser to capture before/after
217
+ });
218
+ }, [routeKey]);
219
+
220
+ return <>{children}</>;
221
+ }
222
+ ```
223
+
224
+ ```css
225
+ ::view-transition-old(root),
226
+ ::view-transition-new(root) {
227
+ animation-duration: 200ms;
228
+ animation-timing-function: var(--ease-out);
229
+ }
230
+
231
+ @media (prefers-reduced-motion: reduce) {
232
+ ::view-transition-old(root),
233
+ ::view-transition-new(root) {
234
+ animation: none;
235
+ }
236
+ }
237
+ ```
238
+
239
+ ## Korean app convention
240
+
241
+ - **Mobile webview / hybrid app**: prefer `slide` variant — matches native iOS / Android feel users expect from Toss / KakaoBank.
242
+ - **Desktop web (toss.im, naver.com)**: `fade` is standard.
243
+ - **Marketing landing pages**: skip PageTransition entirely; full reload feel is fine.
244
+
245
+ ## Accessibility
246
+
247
+ - `aria-live="polite"` on the page region so screen readers announce route change. (Don't use `assertive`; that interrupts.)
248
+ - After transition: focus moves to `<h1>` of new page (router-level concern, not PageTransition's).
249
+ - `prefers-reduced-motion`: enforce via the variant downgrade above.
250
+ - For long transitions (>250ms), risk of focus loss; keep transitions short.
251
+
252
+ ## Edge cases
253
+
254
+ - **Modal-on-route**: don't apply page transition when the route change is just opening a modal (use `<Outlet />` only on actual page changes; modals stack above).
255
+ - **Tab-style navigation**: tabs that swap content within the same route should NOT trigger PageTransition. Use a separate `<Tabs>` animation.
256
+ - **Programmatic navigation during transition**: cancel current transition; new one wins. Framer Motion's `mode="wait"` handles this.
257
+ - **Server-rendered first paint**: first hydration must not trigger transition. Use `initial={false}` (Framer Motion) or check `previousKey.current` (View Transitions).
258
+ - **Memory of scroll position**: each route should restore its scroll. PageTransition itself doesn't scroll; do this via router scroll-restoration.
259
+
260
+ ## Don't
261
+
262
+ - Don't use slide variant on desktop wide screens — large translation feels heavy.
263
+ - Don't transition every route — landing → app, login → dashboard, payment success — sometimes reset feels right.
264
+ - Don't apply PageTransition twice (e.g., wrapping both layout + page). Pick one level.
265
+ - Don't run more than 300ms — feels slow on rapid-tap navigation.
266
+ - Don't animate `width`/`height` of the wrapper — causes layout thrash.
267
+
268
+ ## References
269
+
270
+ Patterns drawn from:
271
+ - React Router v6 + Framer Motion AnimatePresence patterns
272
+ - Next.js 14 App Router + View Transitions API
273
+ - React Native Stack Navigator transition presets
274
+
275
+ ## Cross-reference
276
+
277
+ - [`knowledge/motion/app-loading-sequences.md`](../knowledge/motion/app-loading-sequences.md) — when to use which variant
278
+ - [`knowledge/motion/choreography-depth.md`](../knowledge/motion/choreography-depth.md) — shared-element / hero patterns
279
+ - [`knowledge/motion/principles.md`](../knowledge/motion/principles.md) — duration tiers
280
+ - [`examples/component-loading-sequence.md`](component-loading-sequence.md) — splash before first route
281
+ - [`examples/component-scroll-reveal.md`](component-scroll-reveal.md) — within-page motion
@@ -0,0 +1,226 @@
1
+ # `Pagination` — spec
2
+
3
+ > Citing Ant Design `Pagination`, MUI `Pagination`, shadcn-ui `pagination`
4
+
5
+ ## Purpose
6
+
7
+ Lets users navigate large result sets in chunks. Three modes — pick the right one for context:
8
+
9
+ | Mode | Use |
10
+ | --- | --- |
11
+ | **Numbered pagination** | Tables, search results, content where users want to know position. |
12
+ | **Cursor-based "Load more"** | Feeds, social timelines, infinite content. |
13
+ | **Infinite scroll** | Engagement-driven feeds (Instagram, TikTok). See [knowledge/patterns/list-and-feed.md](../knowledge/patterns/list-and-feed.md). |
14
+
15
+ This spec covers numbered pagination + Load more. Infinite scroll is a list pattern, not a "Pagination component".
16
+
17
+ ## Anatomy — numbered
18
+
19
+ ```
20
+ [‹] [1] [2] [3] 4 [5] ... [12] [›] 총 142개
21
+ ↑ active Page size: [20 ▾] (1–20 of 142)
22
+ ```
23
+
24
+ | Slot | Required | Notes |
25
+ | --- | --- | --- |
26
+ | Previous (‹) | yes | Disabled on page 1 |
27
+ | Page numbers | yes | Subset shown with ellipsis for many pages |
28
+ | Next (›) | yes | Disabled on last page |
29
+ | Page size selector | optional | Common in tables, rare in mobile |
30
+ | Total count display | optional | "총 142개" / "1–20 of 142" |
31
+ | Jump to page | optional | Input field to type a page number (desktop only) |
32
+
33
+ ## API
34
+
35
+ ```tsx
36
+ <Pagination
37
+ page={currentPage}
38
+ pageSize={20}
39
+ total={142}
40
+ onPageChange={setPage}
41
+ onPageSizeChange={setPageSize}
42
+ pageSizeOptions={[10, 20, 50, 100]}
43
+ showTotal
44
+ showJumper
45
+ siblingCount={1}
46
+ boundaryCount={1}
47
+ />
48
+ ```
49
+
50
+ | Prop | Type | Default | Description |
51
+ | --- | --- | --- | --- |
52
+ | `page` | `number` | — | Current page (1-indexed) |
53
+ | `pageSize` | `number` | `20` | Items per page |
54
+ | `total` | `number` | — | Total item count (server-provided) |
55
+ | `onPageChange` | `(page: number) => void` | — | Fires on navigation |
56
+ | `onPageSizeChange` | `(size: number) => void` | — | Fires on size change |
57
+ | `pageSizeOptions` | `number[]` | `[10, 20, 50, 100]` | Options in size selector |
58
+ | `showSizeChanger` | `boolean` | `true` | Show page size dropdown |
59
+ | `showTotal` | `boolean` | `true` | Show total count |
60
+ | `showJumper` | `boolean` | `false` | Show "go to page X" input (desktop only) |
61
+ | `siblingCount` | `number` | `1` | Pages shown on each side of current (e.g., 4 [5] 6) |
62
+ | `boundaryCount` | `number` | `1` | Pages always shown at start/end (e.g., [1] ... [12]) |
63
+ | `simple` | `boolean` | `false` | Compact mobile mode: just `< 5/12 >` |
64
+
65
+ ## Numbered display algorithm
66
+
67
+ For `total=142, pageSize=20, currentPage=5, siblingCount=1, boundaryCount=1`:
68
+
69
+ ```
70
+ [‹] [1] ... [4] [5] [6] ... [8] [›]
71
+ ↑boundary ↑siblings ↑boundary
72
+ ```
73
+
74
+ Pages: `1, ..., 4, 5, 6, ..., 8`.
75
+
76
+ When near the start: `[1] [2] [3] [4] ... [8]`.
77
+ When near the end: `[1] ... [5] [6] [7] [8]`.
78
+ When few pages (≤ 7): show all without ellipsis.
79
+
80
+ ## Variants
81
+
82
+ ### `simple` mode (mobile)
83
+
84
+ ```
85
+ [‹] 5 / 12 [›]
86
+ ```
87
+
88
+ Just prev/next + position display. Avoids cramped numbered buttons on mobile.
89
+
90
+ ### Compact (no size changer, no total)
91
+
92
+ ```
93
+ [‹] [1] [2] [3] ... [12] [›]
94
+ ```
95
+
96
+ For minimal UIs where the count and page size are not user-relevant.
97
+
98
+ ### Load more variant
99
+
100
+ ```
101
+ ... existing items ...
102
+ [Load more (122 remaining)]
103
+ ```
104
+
105
+ Single button at the bottom of the list. Replaces numbered pagination for feed-like content.
106
+
107
+ ## States
108
+
109
+ | State | Visual |
110
+ | --- | --- |
111
+ | Default page button | Border `--color-border-default`, text `--color-text-primary` |
112
+ | Hover | Border `--color-border-strong`, bg `--color-bg-subtle` |
113
+ | Active (current page) | Background `--color-primary-default`, text `--color-on-primary` |
114
+ | Disabled (prev on page 1, next on last) | Opacity 0.4, no events |
115
+ | Focus-visible | 2px ring |
116
+
117
+ ## Sizes
118
+
119
+ | Size | Button height | Font |
120
+ | --- | --- | --- |
121
+ | `sm` | 28px | 13px |
122
+ | `md` (default) | 32px | 14px |
123
+ | `lg` | 40px | 16px |
124
+
125
+ ## Tokens consumed
126
+
127
+ ```
128
+ --color-bg-default
129
+ --color-bg-subtle (hover)
130
+ --color-primary-default (active page bg)
131
+ --color-on-primary (active page text)
132
+ --color-text-primary
133
+ --color-text-secondary (disabled)
134
+ --color-border-default
135
+ --color-border-strong
136
+ --color-focus-ring
137
+ --space-xs, --space-sm
138
+ --radius-md (button corners) or radius-full (pill style)
139
+ --font-size-sm
140
+ ```
141
+
142
+ ## Accessibility
143
+
144
+ - `<nav role="navigation" aria-label="Pagination">` wraps the controls.
145
+ - Each page button is a `<button>` (or `<a href="?page=N">` for crawlable pages).
146
+ - Current page: `aria-current="page"` on the button. Don't use `disabled` on the current page — the user might want to click it (no-op, but accessible).
147
+ - Previous/Next buttons:
148
+ - `aria-label="이전 페이지"` / `"다음 페이지"`
149
+ - `disabled` when at boundary
150
+ - Page size selector: standard Select with `aria-label="페이지당 항목 수"`.
151
+ - Total count: live region `aria-live="polite"` so screen reader announces when it changes (e.g., after filtering).
152
+
153
+ ### Keyboard
154
+
155
+ | Key | Behavior |
156
+ | --- | --- |
157
+ | `Tab` | Reach individual buttons in order |
158
+ | `Enter` / `Space` | Activate focused button |
159
+ | Arrow keys | NOT used — user tabs through |
160
+
161
+ ## URL sync (highly recommended)
162
+
163
+ Pagination should sync to URL:
164
+
165
+ ```
166
+ /transactions?page=5&size=20
167
+ ```
168
+
169
+ Benefits:
170
+ - Browser back/forward works.
171
+ - Shareable links to specific pages.
172
+ - Refresh preserves position.
173
+ - SEO: search crawlers see all pages.
174
+
175
+ Implementation: read from `useSearchParams` in React Router / Next.js. Update query on `onPageChange`.
176
+
177
+ ## Korean copy
178
+
179
+ | English | Korean |
180
+ | --- | --- |
181
+ | Previous | 이전 |
182
+ | Next | 다음 |
183
+ | First | 처음 |
184
+ | Last | 마지막 |
185
+ | Page X of Y | X 페이지 / 총 Y 페이지 |
186
+ | Go to page | 페이지로 이동 |
187
+ | 1–20 of 142 | 142개 중 1–20 |
188
+ | Items per page | 페이지당 항목 수 |
189
+ | Show N | N개씩 보기 |
190
+
191
+ ## Edge cases
192
+
193
+ - **Only 1 page**: hide pagination entirely. Don't render an empty navigation.
194
+ - **Empty results**: render the empty state instead of page 1 with no items.
195
+ - **Invalid page in URL**: clamp to valid range (`?page=999` with 12 pages → page 12). Surface to user with a toast: "페이지 999는 존재하지 않아 마지막 페이지로 이동했습니다".
196
+ - **Page size change reset**: when user changes page size, reset to page 1 (otherwise, current page might no longer exist).
197
+ - **Filter change reset**: when filters change, reset to page 1.
198
+ - **Server returns total=null** (cursor pagination, unknown total): use Load More variant instead.
199
+ - **Very large totals (10,000+ pages)**: jumper input is essential. Numbered pagination becomes unwieldy past ~100 pages.
200
+ - **Fast-clicking through pages**: debounce 100ms or cancel previous request on new click. Don't blast 5 requests.
201
+
202
+ ## Don't
203
+
204
+ - Don't show "Page 1 of 1" — hide the component.
205
+ - Don't disable the active page button. Use `aria-current` instead.
206
+ - Don't put pagination ABOVE the list. Always below (and optionally also above for very long pages, like > 50 items per page).
207
+ - Don't auto-scroll to top on page change. Let the user choose. (Exception: if pagination is far below the fold, auto-scroll **into view** is OK.)
208
+ - Don't combine numbered pagination + infinite scroll.
209
+ - Don't lose scroll position on page change for inline tables (where pagination is at the table footer).
210
+
211
+ ## References
212
+
213
+ - Ant Design: [`refs/ant-design/components/pagination/`](../refs/ant-design/components/pagination/) — most exhaustive: `simple`, `total`, `showSizeChanger`, `showJumper`, `itemRender`, `disabled`, `responsive`. Common in admin tables.
214
+ - MUI: [`refs/mui/packages/mui-material/src/Pagination/`](../refs/mui/packages/mui-material/src/Pagination/) — `Pagination` + `PaginationItem`. Cleaner API, fewer features.
215
+ - shadcn-ui: [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/pagination.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/pagination.tsx) — primitive only (`Pagination`, `PaginationContent`, `PaginationItem`, `PaginationLink`, `PaginationPrevious`, `PaginationNext`, `PaginationEllipsis`). Compose for behavior. **No built-in pagination logic** — pair with TanStack Table or your own state.
216
+
217
+ API choices made:
218
+ - **`siblingCount` and `boundaryCount` exposed**: lets the consumer tune the numbered display algorithm without overriding rendering.
219
+ - **`simple` mode** for mobile: separate concept, not just CSS — different ARIA semantics (a single button group with status text vs. a list of page buttons).
220
+ - **`showJumper` opt-in, off by default**: useful for power users (admin, analytics), noise for consumers.
221
+ - **No `itemRender` prop** (Ant has it): too much surface area. If you need custom rendering, compose `PaginationItem` manually.
222
+
223
+ ## Cross-reference
224
+
225
+ - [examples/component-table.md](component-table.md) — pagination at the table footer
226
+ - [knowledge/patterns/list-and-feed.md](../knowledge/patterns/list-and-feed.md) — Load More vs infinite scroll vs pagination