@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,198 @@
1
+ # `List` — spec
2
+
3
+ > Synthesized from Ant Design `List` and MUI `List` + `ListItem`. The semantic + styled wrapper around a list of `Item` rows. Distinct from `Item` (single row) and `Table` (tabular data).
4
+
5
+ ## When to use
6
+
7
+ - Vertical stack of similar entities (notifications, files, contacts).
8
+ - With pagination, infinite scroll, or filtering.
9
+ - When `<ul>` + items need consistent styling + a11y.
10
+
11
+ When NOT to use:
12
+ - Tabular data (use `Table`).
13
+ - Single row of actions (use `Toolbar` / `Flex`).
14
+ - Heterogeneous content (use composition of `Card`s).
15
+
16
+ ## Anatomy
17
+
18
+ ```
19
+ [List header (optional)]
20
+ ─────────────────────────
21
+ [Item 1]
22
+ [Item 2]
23
+ [Item 3]
24
+ ─────────────────────────
25
+ [List footer (optional, e.g., Load more)]
26
+ ```
27
+
28
+ ## API
29
+
30
+ ```tsx
31
+ <List
32
+ header={<h3>Recent activity</h3>}
33
+ footer={<Button onClick={loadMore}>Load more</Button>}
34
+ loading={loading}
35
+ empty={<Empty description="No activity yet" />}
36
+ >
37
+ {activities.map(a => (
38
+ <Item key={a.id}>
39
+ <ItemMedia>
40
+ <Avatar src={a.user.avatar} />
41
+ </ItemMedia>
42
+ <ItemContent>
43
+ <ItemTitle>{a.user.name}</ItemTitle>
44
+ <ItemDescription>{a.action}</ItemDescription>
45
+ </ItemContent>
46
+ </Item>
47
+ ))}
48
+ </List>
49
+ ```
50
+
51
+ | Prop | Type | Default | Description |
52
+ | --- | --- | --- | --- |
53
+ | `header` | `ReactNode` | — | Sticky header above items |
54
+ | `footer` | `ReactNode` | — | Below items (Load more, totals) |
55
+ | `loading` | `boolean` | `false` | Show Skeleton instead of items |
56
+ | `empty` | `ReactNode` | — | Shown when 0 items |
57
+ | `dividers` | `boolean` | `true` | Show separators between items |
58
+ | `density` | `"compact" \| "comfortable" \| "relaxed"` | `"comfortable"` | Item padding |
59
+ | `as` | `"ul" \| "ol" \| "div"` | `"ul"` | Underlying element |
60
+
61
+ ## States
62
+
63
+ | State | Visual |
64
+ | --- | --- |
65
+ | Loading | Skeleton items |
66
+ | Empty | `empty` prop content |
67
+ | With items | Standard render |
68
+ | Error | (handled externally; pass error UI in children) |
69
+
70
+ ## Variants
71
+
72
+ ### With dividers (default)
73
+
74
+ ```
75
+ [Item 1]
76
+ ─────
77
+ [Item 2]
78
+ ─────
79
+ [Item 3]
80
+ ```
81
+
82
+ ### Without dividers (cards spaced)
83
+
84
+ ```
85
+ [Item 1]
86
+
87
+ [Item 2]
88
+
89
+ [Item 3]
90
+ ```
91
+
92
+ Use when items are full Cards with their own boundaries.
93
+
94
+ ### With sections (grouped)
95
+
96
+ ```
97
+ Yesterday
98
+ ─────
99
+ [Item 1]
100
+ [Item 2]
101
+
102
+ Last week
103
+ ─────
104
+ [Item 3]
105
+ ```
106
+
107
+ Group via wrapping headings + smaller sub-lists.
108
+
109
+ ## Tokens consumed
110
+
111
+ ```
112
+ --list-bg
113
+ --list-divider
114
+ --list-header-bg (sticky header bg)
115
+ --list-empty-fg
116
+ --space-md, --space-lg
117
+ --font-size-sm (header)
118
+ ```
119
+
120
+ ## Accessibility
121
+
122
+ - Use `<ul>` (default) or `<ol>` if order matters.
123
+ - Each `<Item>` is `<li>` semantically.
124
+ - Header outside `<ul>` (separate element).
125
+ - For load-more: announce new items via `aria-live="polite"`.
126
+ - Empty state: `role="status"`.
127
+
128
+ ## Pagination + infinite scroll
129
+
130
+ ```tsx
131
+ {/* Pagination at bottom */}
132
+ <List footer={<Pagination ... />}>...</List>
133
+
134
+ {/* Infinite scroll (trigger near bottom) */}
135
+ <List footer={<InfiniteTrigger onTrigger={loadMore} loading={loadingMore} />}>
136
+ ...
137
+ </List>
138
+ ```
139
+
140
+ For long lists (1000+ items): virtualize. Use react-virtual or react-virtuoso.
141
+
142
+ ## Code example
143
+
144
+ ```tsx
145
+ function NotificationList() {
146
+ const { data, isLoading, error } = useNotifications();
147
+
148
+ if (error) return <ErrorState error={error} />;
149
+
150
+ return (
151
+ <List
152
+ header={<h2>알림</h2>}
153
+ loading={isLoading}
154
+ empty={
155
+ <EmptyState
156
+ illustration="no-notifications"
157
+ title="알림이 없어요"
158
+ description="새 활동이 있을 때 여기에 표시돼요."
159
+ />
160
+ }
161
+ >
162
+ {data?.map(n => (
163
+ <Item key={n.id} interactive onClick={() => markRead(n.id)}>
164
+ <ItemMedia><n.icon /></ItemMedia>
165
+ <ItemContent>
166
+ <ItemTitle>{n.title}</ItemTitle>
167
+ <ItemDescription>{n.message}</ItemDescription>
168
+ </ItemContent>
169
+ <ItemActions>
170
+ <time>{formatRelative(n.timestamp)}</time>
171
+ {!n.read && <UnreadDot />}
172
+ </ItemActions>
173
+ </Item>
174
+ ))}
175
+ </List>
176
+ );
177
+ }
178
+ ```
179
+
180
+ ## Don't
181
+
182
+ - Don't use List for tabular data. Use Table.
183
+ - Don't omit empty state. Empty list = unclear if loading or really empty.
184
+ - Don't render 10,000 items unvirtualized. Performance dies.
185
+ - Don't use raw `<ul>` for item-style data. Use List + Item primitives.
186
+
187
+ ## References
188
+
189
+ - Ant: [`List`](../refs/ant-design/components/list)
190
+ - MUI: [`List`](../refs/mui/packages/mui-material/src/List) + [`ListItem`](../refs/mui/packages/mui-material/src/ListItem)
191
+ - HTML5 `<ul>` / `<ol>` / `<li>`
192
+
193
+ ## Cross-reference
194
+
195
+ - [`examples/component-item.md`](component-item.md) — single row
196
+ - [`examples/component-table.md`](component-table.md) — tabular alternative
197
+ - [`examples/component-empty-state.md`](component-empty-state.md) — full-page empty
198
+ - [`knowledge/patterns/list-and-feed.md`](../knowledge/patterns/list-and-feed.md)
@@ -0,0 +1,125 @@
1
+ # `LoadingButton` (pattern) — spec
2
+
3
+ > **Pattern, not a separate component.** As of MUI v6, `LoadingButton` was merged into `Button` (`<Button loading>`); shadcn / Ant don't ship a separate "loading button" either. This spec documents the **loading-state pattern** that any `Button` should support — applied to `Button` props in your design system.
4
+
5
+ ## When to use
6
+
7
+ - Any button that triggers an async operation (form submit, API call, file upload).
8
+ - Especially destructive actions (delete, leave, transfer) — without a loading state, users double-click and trigger duplicate operations.
9
+
10
+ ## Anatomy
11
+
12
+ ```
13
+ Default state Loading state
14
+ ┌─────────────────┐ ┌─────────────────┐
15
+ │ [icon] Label │ → │ ⠋ Loading │
16
+ └─────────────────┘ └─────────────────┘
17
+ ```
18
+
19
+ The label may stay or change ("저장하기" → "저장 중..."). The leading icon is replaced with a spinner. The button stays the same width (loading shouldn't reflow the layout).
20
+
21
+ ## API
22
+
23
+ Add these props to `Button`:
24
+
25
+ | Prop | Type | Default | Description |
26
+ | --- | --- | --- | --- |
27
+ | `loading` | `boolean` | `false` | Show spinner; disable click |
28
+ | `loadingPosition` | `'start' \| 'end' \| 'center'` | `'center'` | Spinner position; `start`/`end` keeps the label visible |
29
+ | `loadingIndicator` | `ReactNode` | `<CircularProgress size={16} />` | Custom indicator |
30
+ | `loadingText` | `string` | — | Optional label override during loading (e.g., "저장 중...") |
31
+
32
+ ## States
33
+
34
+ | State | Visual | Interaction |
35
+ | --- | --- | --- |
36
+ | Default | Standard button | Clickable |
37
+ | Hover | bg-hover | Clickable |
38
+ | Loading | Spinner + label/loadingText; bg + fg muted slightly | **NOT clickable**; cursor remains pointer (signals "we got your click, working on it") |
39
+ | Disabled | reduced opacity | Not clickable |
40
+ | Loading + disabled | Same as loading | (functionally equivalent) |
41
+
42
+ ## Tokens consumed
43
+
44
+ ```
45
+ --button-bg-default
46
+ --button-bg-hover
47
+ --button-fg-default
48
+ --spinner-size-16 /* default loading indicator */
49
+ --space-sm /* gap between spinner and label */
50
+ --button-min-width /* width-locked during loading */
51
+ ```
52
+
53
+ ## Accessibility
54
+
55
+ - `aria-busy="true"` while loading. Screen readers announce "busy" status.
56
+ - `aria-disabled="true"` while loading (NOT the `disabled` HTML attribute — that removes the button from the tab order, breaks Esc/screen reader recovery).
57
+ - Focus stays on the button during loading. After completion, focus management depends on outcome:
58
+ - Success: move focus to next logical step OR a success toast.
59
+ - Error: announce the error via `aria-live="polite"` toast; keep focus on the button so user can retry.
60
+ - Cite [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md).
61
+
62
+ ## Edge cases
63
+
64
+ - **Long async operation (>10s)** — show progress percentage if known, or supplement with a toast "잠시만 기다려 주세요". 10s+ silent loading reads as broken.
65
+ - **Network failure** — exit loading, restore label, surface error inline or via toast. Don't leave the button in loading state on error.
66
+ - **Korean labels** — "저장하기" → "저장 중..." (3 dots, not "..." typography). The 중 character signals progress; pair with spinner for redundancy.
67
+ - **Optimistic UI** — for cheap operations (toggle a switch), prefer optimistic update over loading button.
68
+
69
+ ## Code example
70
+
71
+ ```tsx
72
+ import { Button, CircularProgress } from "@mui/material";
73
+
74
+ function SaveButton({ onSave }: { onSave: () => Promise<void> }) {
75
+ const [loading, setLoading] = useState(false);
76
+ const [error, setError] = useState<string | null>(null);
77
+
78
+ async function handleClick() {
79
+ setLoading(true);
80
+ setError(null);
81
+ try {
82
+ await onSave();
83
+ } catch (e) {
84
+ setError(e instanceof Error ? e.message : "알 수 없는 오류");
85
+ } finally {
86
+ setLoading(false);
87
+ }
88
+ }
89
+
90
+ return (
91
+ <>
92
+ <Button
93
+ variant="contained"
94
+ onClick={handleClick}
95
+ loading={loading}
96
+ loadingPosition="start"
97
+ startIcon={<SaveIcon />}
98
+ aria-busy={loading}
99
+ >
100
+ {loading ? "저장 중..." : "저장하기"}
101
+ </Button>
102
+ {error && (
103
+ <Alert severity="error" sx={{ mt: 1 }} role="alert">
104
+ {error}
105
+ </Alert>
106
+ )}
107
+ </>
108
+ );
109
+ }
110
+ ```
111
+
112
+ ## Don't
113
+
114
+ - Don't disable the button without showing a loading indicator — users think it's broken.
115
+ - Don't move focus away during loading; users may want to cancel (Esc, navigate back).
116
+ - Don't reset the form on click before the async resolves — if it fails, you've lost the user's input.
117
+ - Don't show "Loading..." with no spinner. Spinner is the universal "we're working" signal.
118
+ - Don't allow double-click during loading. Set `loading={true}` synchronously before the async starts.
119
+
120
+ ## Cross-reference
121
+
122
+ - [`knowledge/components/INDEX.md`](../knowledge/components/INDEX.md)
123
+ - [`component-button.md`](component-button.md)
124
+ - [`knowledge/patterns/empty-states.md`](../knowledge/patterns/empty-states.md) — what to show during long loads
125
+ - [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md)
@@ -0,0 +1,254 @@
1
+ <!-- hand-written -->
2
+ # `LoadingSequence` (custom — splash + first-screen coordination) — spec
3
+
4
+ > Coordinates the cold-launch experience: brand splash → biometric / auth gate (optional) → first screen reveal. Wraps the moments after process start and before the user sees real content. Pairs with [`knowledge/motion/app-loading-sequences.md`](../knowledge/motion/app-loading-sequences.md).
5
+
6
+ ## Purpose
7
+
8
+ Make cold launch feel **intentional** instead of like a stall:
9
+
10
+ 1. Show brand-led splash that matches the first screen's background (no flash).
11
+ 2. Optionally chain a biometric gate (Korean fintech default).
12
+ 3. Cross-fade into the real app content as soon as it's ready.
13
+ 4. Respect `prefers-reduced-motion`.
14
+
15
+ Without this: blank screen → flash of unstyled content → spinner → app. Reads as broken.
16
+
17
+ ## Anatomy
18
+
19
+ ```
20
+ ┌──────────────────────────────────────┐
21
+ │ │
22
+ │ │
23
+ │ │
24
+ │ [logo / wordmark] │ ← splash (brand bg)
25
+ │ │
26
+ │ │
27
+ │ │
28
+ └──────────────────────────────────────┘
29
+ ↓ (optional)
30
+ ┌──────────────────────────────────────┐
31
+ │ 🔒 Face ID │
32
+ │ 본인 확인이 필요합니다 │ ← biometric gate
33
+ │ [지문으로 잠금 해제] │
34
+ └──────────────────────────────────────┘
35
+
36
+ ┌──────────────────────────────────────┐
37
+ │ Header │
38
+ │ [content cross-fades in] │ ← first screen
39
+ │ ... │
40
+ └──────────────────────────────────────┘
41
+ ```
42
+
43
+ ## API
44
+
45
+ ```tsx
46
+ <LoadingSequence
47
+ brand={{ logo: <Logo />, backgroundColor: "var(--color-brand-bg)" }}
48
+ minDurationMs={600}
49
+ gate={biometricEnabled ? <BiometricGate onUnlock={resolve} /> : null}
50
+ onReady={() => setAppReady(true)}
51
+ >
52
+ <App />
53
+ </LoadingSequence>
54
+ ```
55
+
56
+ | Prop | Type | Default | Description |
57
+ | --- | --- | --- | --- |
58
+ | `brand` | `{ logo: ReactNode; backgroundColor: string }` | — | Splash content + bg color (must match first screen) |
59
+ | `minDurationMs` | `number` | `600` | Floor on splash duration to avoid flash if app boots in 80ms |
60
+ | `gate` | `ReactNode \| null` | `null` | Optional auth gate (biometric, PIN). When present, splash → gate → content. |
61
+ | `onReady` | `() => void` | — | Fires when content is fully visible |
62
+ | `children` | `ReactNode` | — | Real app content; rendered behind splash, revealed on transition |
63
+ | `disableAnimation` | `boolean` | auto via `prefers-reduced-motion` | Skip cross-fade |
64
+
65
+ ## Behavior
66
+
67
+ ### State machine
68
+
69
+ ```
70
+ ┌─────────┐
71
+ │ booting │ ← process started; splash fully opaque
72
+ └────┬────┘
73
+ │ minDurationMs reached AND app ready
74
+
75
+ ┌─────────┐
76
+ │ gate? │ ← if `gate` prop, render it (splash bg stays)
77
+ └────┬────┘
78
+ │ gate resolves (or no gate)
79
+
80
+ ┌─────────────┐
81
+ │ revealing │ ← 200ms cross-fade splash → content
82
+ └──────┬──────┘
83
+
84
+
85
+ ┌────────┐
86
+ │ ready │ ← onReady fires; LoadingSequence unmounts splash
87
+ └────────┘
88
+ ```
89
+
90
+ ### Timing budget
91
+
92
+ | Phase | Duration | Notes |
93
+ | --- | --- | --- |
94
+ | Splash visible | `max(minDurationMs, timeToAppReady)` | Floor prevents flash; ceiling is real boot time |
95
+ | Gate (if present) | User-driven | Typically 1–3s for biometric; can be longer |
96
+ | Cross-fade | 200ms | Cross-fade splash out + content in simultaneously |
97
+ | Total cold launch | 0.6–3s typical | Korean fintech: 1.5–3s with biometric |
98
+
99
+ ### Cross-fade
100
+
101
+ ```css
102
+ .splash {
103
+ opacity: 1;
104
+ transition: opacity var(--motion-medium) var(--ease-out);
105
+ }
106
+ .splash[data-state="revealing"] { opacity: 0; }
107
+
108
+ .content {
109
+ opacity: 0;
110
+ transition: opacity var(--motion-medium) var(--ease-out);
111
+ }
112
+ .content[data-state="revealing"],
113
+ .content[data-state="ready"] { opacity: 1; }
114
+ ```
115
+
116
+ Both run together — true cross-fade, not sequential.
117
+
118
+ ## States
119
+
120
+ | State | Splash | Gate | Content |
121
+ | --- | --- | --- | --- |
122
+ | `booting` | Visible (opacity 1) | hidden | Hidden behind splash |
123
+ | `gating` | Hidden | Visible | Behind gate |
124
+ | `revealing` | Fading out | Hidden | Fading in |
125
+ | `ready` | Unmounted | Unmounted | Visible |
126
+
127
+ ## Tokens consumed
128
+
129
+ ```
130
+ --color-brand-bg (splash + first screen background — MUST match)
131
+ --color-brand-fg (logo color on splash)
132
+ --motion-medium (200ms cross-fade)
133
+ --ease-out (cross-fade easing)
134
+ --z-splash (above all app chrome)
135
+ ```
136
+
137
+ ## Korean fintech convention
138
+
139
+ Toss / KakaoBank pattern:
140
+
141
+ ```tsx
142
+ <LoadingSequence
143
+ brand={{ logo: <TossLogo />, backgroundColor: "#0064FF" }}
144
+ minDurationMs={400}
145
+ gate={
146
+ user.biometricEnrolled ? (
147
+ <BiometricGate
148
+ prompt="Face ID로 잠금 해제"
149
+ fallback={<PINGate />}
150
+ />
151
+ ) : null
152
+ }
153
+ >
154
+ <Dashboard />
155
+ </LoadingSequence>
156
+ ```
157
+
158
+ - Brand color splash (full bleed)
159
+ - Biometric gate appears almost immediately (within minDurationMs floor)
160
+ - Gate dominates the cold-launch experience; actual app boot hides underneath
161
+ - After unlock: 200ms cross-fade to dashboard
162
+
163
+ See [`examples/component-biometric-gate.md`](component-biometric-gate.md).
164
+
165
+ ## Accessibility
166
+
167
+ - Splash: `role="presentation"` (decorative). Logo gets `alt="[brand name]"` if `<img>`, or `aria-label` if `<svg>`.
168
+ - Gate: standard a11y from gate component.
169
+ - During splash: focus is trapped on splash root with `tabindex="-1"` so screen readers don't read app behind it prematurely.
170
+ - Content reveal: announce via `<div role="status" aria-live="polite">앱 준비 완료</div>` only if minDurationMs is hit and reveal is delayed beyond 1s. Otherwise silent.
171
+ - `prefers-reduced-motion`: skip cross-fade; instant swap. Splash still shows for `minDurationMs`.
172
+
173
+ ## Implementation hints
174
+
175
+ ```tsx
176
+ function LoadingSequence({ brand, minDurationMs = 600, gate, onReady, children }: Props) {
177
+ const [phase, setPhase] = useState<"booting" | "gating" | "revealing" | "ready">("booting");
178
+ const mountedAt = useRef(Date.now());
179
+ const [appReady, setAppReady] = useState(false);
180
+ const reduced = usePrefersReducedMotion();
181
+
182
+ // Wait for app content to render at least once
183
+ useEffect(() => {
184
+ requestIdleCallback(() => setAppReady(true));
185
+ }, []);
186
+
187
+ // Transition booting → gating/revealing once minDuration + appReady
188
+ useEffect(() => {
189
+ if (!appReady) return;
190
+ const elapsed = Date.now() - mountedAt.current;
191
+ const wait = Math.max(0, minDurationMs - elapsed);
192
+ const id = setTimeout(() => {
193
+ setPhase(gate ? "gating" : "revealing");
194
+ }, wait);
195
+ return () => clearTimeout(id);
196
+ }, [appReady, gate, minDurationMs]);
197
+
198
+ // Reveal → ready
199
+ useEffect(() => {
200
+ if (phase !== "revealing") return;
201
+ const id = setTimeout(() => {
202
+ setPhase("ready");
203
+ onReady?.();
204
+ }, reduced ? 0 : 200);
205
+ return () => clearTimeout(id);
206
+ }, [phase, onReady, reduced]);
207
+
208
+ return (
209
+ <>
210
+ {phase !== "ready" && (
211
+ <div
212
+ className="splash"
213
+ data-state={phase}
214
+ style={{ background: brand.backgroundColor }}
215
+ role="presentation"
216
+ >
217
+ {phase === "gating" ? gate : brand.logo}
218
+ </div>
219
+ )}
220
+ <div className="content" data-state={phase}>
221
+ {children}
222
+ </div>
223
+ </>
224
+ );
225
+ }
226
+ ```
227
+
228
+ ## Edge cases
229
+
230
+ - **App boots faster than `minDurationMs`**: splash still shown until floor. Prevents 80ms flash.
231
+ - **App boots slower than splash floor**: splash stays until app is ready. No premature reveal.
232
+ - **Gate fails (biometric denied 3×)**: bubble up to gate's `onFallback`; LoadingSequence stays in `gating` until resolved.
233
+ - **App backgrounded during splash**: pause timers via `visibilitychange` listener; resume on focus.
234
+ - **Hot reload in dev**: `LoadingSequence` should NOT re-trigger on every HMR — only on real cold mount.
235
+ - **Server-side rendering**: render content directly without splash on SSR; client-side mount triggers splash only if `document.readyState !== "complete"` at mount.
236
+
237
+ ## Don't
238
+
239
+ - Don't put a spinner on the splash. Static logo only. Looping spinner reads as stuck.
240
+ - Don't animate the logo with bounce / pulse on every cold launch — once the user has seen it, animation feels precious.
241
+ - Don't mismatch `brand.backgroundColor` with the first screen's bg. The whole point is seamless transition.
242
+ - Don't keep splash up longer than 3 seconds without a gate. User thinks the app froze.
243
+ - Don't tie `onReady` to data fetching — fires when first paint completes, not when feed is loaded.
244
+
245
+ ## References
246
+
247
+ No upstream component matches. This composes splash + gate + cross-fade in a single shell.
248
+
249
+ ## Cross-reference
250
+
251
+ - [`knowledge/motion/app-loading-sequences.md`](../knowledge/motion/app-loading-sequences.md) — strategy
252
+ - [`knowledge/motion/principles.md`](../knowledge/motion/principles.md) — duration / easing
253
+ - [`examples/component-biometric-gate.md`](component-biometric-gate.md) — gate component
254
+ - [`examples/component-page-transition.md`](component-page-transition.md) — route-level transitions (after splash)