@design-ai/cli 4.56.0 → 4.58.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 (271) hide show
  1. package/.claude-plugin/plugin.json +109 -25
  2. package/CHANGELOG.md +68 -0
  3. package/README.ko.md +11 -28
  4. package/README.md +12 -25
  5. package/cli/bin/design-ai.mjs +1 -0
  6. package/cli/commands/help.mjs +7 -4
  7. package/cli/commands/index.mjs +292 -0
  8. package/cli/commands/learn-help.mjs +149 -0
  9. package/cli/commands/learn-print-profile.mjs +373 -0
  10. package/cli/commands/learn-print-restore.mjs +349 -0
  11. package/cli/commands/learn-print-signals.mjs +453 -0
  12. package/cli/commands/learn.mjs +60 -1281
  13. package/cli/commands/pack.mjs +7 -3
  14. package/cli/commands/prompt.mjs +7 -3
  15. package/cli/commands/route.mjs +13 -1
  16. package/cli/commands/search.mjs +94 -1
  17. package/cli/lib/dispatch.mjs +3 -0
  18. package/cli/lib/embedding-index.mjs +199 -0
  19. package/cli/lib/embedding-provider.mjs +121 -0
  20. package/cli/lib/embedding-rerank.mjs +52 -0
  21. package/cli/lib/learn-args.mjs +490 -0
  22. package/cli/lib/learn-backup.mjs +748 -0
  23. package/cli/lib/learn-curation.mjs +612 -0
  24. package/cli/lib/learn-eval.mjs +459 -0
  25. package/cli/lib/learn-profile.mjs +763 -0
  26. package/cli/lib/learn-select.mjs +223 -0
  27. package/cli/lib/learn-shared.mjs +158 -0
  28. package/cli/lib/learn-test-support.mjs +218 -0
  29. package/cli/lib/learn-usage.mjs +360 -0
  30. package/cli/lib/learn.mjs +83 -3694
  31. package/cli/lib/lexical.mjs +137 -0
  32. package/cli/lib/local-config.mjs +110 -0
  33. package/cli/lib/mcp-server.mjs +13 -3
  34. package/cli/lib/pack.mjs +31 -4
  35. package/cli/lib/prompt.mjs +42 -4
  36. package/cli/lib/recall.mjs +193 -0
  37. package/cli/lib/retrieval-index.mjs +0 -0
  38. package/cli/lib/route.mjs +62 -5
  39. package/cli/lib/search-ranked.mjs +202 -0
  40. package/cli/lib/search.mjs +11 -1
  41. package/cli/lib/signals-backlog-commands.mjs +673 -0
  42. package/cli/lib/signals-backlog.mjs +361 -0
  43. package/cli/lib/signals-eval.mjs +176 -0
  44. package/cli/lib/signals-readiness.mjs +247 -0
  45. package/cli/lib/signals-registry.mjs +377 -0
  46. package/cli/lib/signals-render.mjs +478 -0
  47. package/cli/lib/signals-shared.mjs +75 -0
  48. package/cli/lib/signals.mjs +16 -2337
  49. package/cli/lib/site-bundle-handoff-expected.mjs +173 -0
  50. package/cli/lib/site-bundle-handoff-runbook-action-summary.mjs +332 -0
  51. package/cli/lib/site-bundle-handoff-runbook-human-lines.mjs +167 -0
  52. package/cli/lib/site-bundle-handoff-runbook-maps.mjs +238 -0
  53. package/cli/lib/site-bundle-handoff-runbook-next-step.mjs +278 -0
  54. package/cli/lib/site-bundle-handoff-runbook.mjs +44 -931
  55. package/cli/lib/site-test-support.mjs +68 -0
  56. package/cli/lib/skill-proposals-apply-commands.mjs +135 -0
  57. package/cli/lib/skill-proposals-apply-contract.mjs +750 -0
  58. package/cli/lib/skill-proposals-apply-plan.mjs +118 -0
  59. package/cli/lib/skill-proposals-generate.mjs +298 -0
  60. package/cli/lib/skill-proposals-render.mjs +532 -0
  61. package/cli/lib/skill-proposals-review.mjs +262 -0
  62. package/cli/lib/skill-proposals.mjs +15 -2046
  63. package/cli/lib/workspace-args.mjs +83 -0
  64. package/cli/lib/workspace-git.mjs +169 -0
  65. package/cli/lib/workspace-learning.mjs +483 -0
  66. package/cli/lib/workspace-repo.mjs +139 -0
  67. package/cli/lib/workspace-report.mjs +283 -0
  68. package/cli/lib/workspace-test-support.mjs +99 -0
  69. package/cli/lib/workspace.mjs +30 -1056
  70. package/docs/AI-LEARNING-PHASE2.md +215 -0
  71. package/docs/DISTRIBUTION.ko.md +2 -2
  72. package/docs/DISTRIBUTION.md +2 -2
  73. package/docs/NEXT-SURFACE-DECISION.md +125 -0
  74. package/docs/PRODUCT-READINESS.md +3 -3
  75. package/docs/RELEASE-GATES.ko.md +35 -0
  76. package/docs/RELEASE-GATES.md +234 -0
  77. package/docs/ROADMAP.md +82 -8
  78. package/docs/external-status.md +9 -11
  79. package/docs/inspection-20260630.md +169 -0
  80. package/docs/integrations/design-ai-mcp-server.md +4 -4
  81. package/docs/reference/ant-design.md +413 -0
  82. package/docs/reference/awesome-design-md.md +439 -0
  83. package/docs/reference/mui.md +783 -0
  84. package/docs/reference/shadcn-ui.md +298 -0
  85. package/examples/component-accordion-actions.md +5 -5
  86. package/examples/component-accordion-details.md +5 -5
  87. package/examples/component-accordion-summary.md +5 -5
  88. package/examples/component-accordion.md +3 -3
  89. package/examples/component-affix.md +1 -1
  90. package/examples/component-alert-dialog.md +1 -1
  91. package/examples/component-alert-title.md +1 -1
  92. package/examples/component-alert.md +3 -3
  93. package/examples/component-anchor.md +1 -1
  94. package/examples/component-app-bar.md +1 -1
  95. package/examples/component-aspect-ratio.md +1 -1
  96. package/examples/component-auto-complete.md +2 -2
  97. package/examples/component-avatar-group.md +5 -5
  98. package/examples/component-avatar.md +3 -3
  99. package/examples/component-back-top.md +1 -1
  100. package/examples/component-backdrop.md +1 -1
  101. package/examples/component-badge.md +3 -3
  102. package/examples/component-border-beam.md +3 -3
  103. package/examples/component-bottom-navigation.md +1 -1
  104. package/examples/component-box.md +1 -1
  105. package/examples/component-breadcrumb.md +3 -3
  106. package/examples/component-button-base.md +3 -3
  107. package/examples/component-button-group.md +2 -2
  108. package/examples/component-button.md +3 -3
  109. package/examples/component-calendar.md +2 -2
  110. package/examples/component-card-actions.md +1 -1
  111. package/examples/component-card-content.md +1 -1
  112. package/examples/component-card-header.md +1 -1
  113. package/examples/component-card-media.md +1 -1
  114. package/examples/component-card.md +3 -3
  115. package/examples/component-carousel.md +2 -2
  116. package/examples/component-cascader.md +1 -1
  117. package/examples/component-chart.md +1 -1
  118. package/examples/component-checkbox.md +3 -3
  119. package/examples/component-click-away-listener.md +1 -1
  120. package/examples/component-code.md +1 -1
  121. package/examples/component-collapsible.md +1 -1
  122. package/examples/component-color-picker.md +1 -1
  123. package/examples/component-combobox.md +1 -1
  124. package/examples/component-command.md +1 -1
  125. package/examples/component-config-provider.md +3 -3
  126. package/examples/component-context-menu.md +1 -1
  127. package/examples/component-css-baseline.md +3 -3
  128. package/examples/component-date-picker.md +2 -2
  129. package/examples/component-descriptions.md +1 -1
  130. package/examples/component-dialog-actions.md +1 -1
  131. package/examples/component-dialog-content-text.md +1 -1
  132. package/examples/component-dialog-content.md +1 -1
  133. package/examples/component-dialog-title.md +1 -1
  134. package/examples/component-dialog.md +2 -2
  135. package/examples/component-divider.md +3 -3
  136. package/examples/component-drawer.md +3 -3
  137. package/examples/component-dropdown.md +3 -3
  138. package/examples/component-empty.md +2 -2
  139. package/examples/component-fade.md +1 -1
  140. package/examples/component-field.md +1 -1
  141. package/examples/component-filled-input.md +1 -1
  142. package/examples/component-flex.md +1 -1
  143. package/examples/component-float-button.md +2 -2
  144. package/examples/component-form-control-label.md +1 -1
  145. package/examples/component-form-control.md +1 -1
  146. package/examples/component-form-controls.md +1 -1
  147. package/examples/component-form-group.md +1 -1
  148. package/examples/component-form-helper-text.md +1 -1
  149. package/examples/component-form-label.md +1 -1
  150. package/examples/component-form.md +2 -2
  151. package/examples/component-grid.md +2 -2
  152. package/examples/component-grow.md +1 -1
  153. package/examples/component-hover-card.md +1 -1
  154. package/examples/component-icon-button.md +1 -1
  155. package/examples/component-icon.md +1 -1
  156. package/examples/component-image-list.md +1 -1
  157. package/examples/component-image.md +1 -1
  158. package/examples/component-input-adornment.md +1 -1
  159. package/examples/component-input-base.md +1 -1
  160. package/examples/component-input-number.md +1 -1
  161. package/examples/component-input-otp.md +2 -2
  162. package/examples/component-input.md +3 -3
  163. package/examples/component-item.md +1 -1
  164. package/examples/component-label.md +1 -1
  165. package/examples/component-layout.md +1 -1
  166. package/examples/component-link.md +1 -1
  167. package/examples/component-list-item-avatar.md +1 -1
  168. package/examples/component-list-item-button.md +1 -1
  169. package/examples/component-list-item-icon.md +1 -1
  170. package/examples/component-list-item-text.md +1 -1
  171. package/examples/component-list-item.md +1 -1
  172. package/examples/component-list-subheader.md +1 -1
  173. package/examples/component-list.md +2 -2
  174. package/examples/component-masonry.md +1 -1
  175. package/examples/component-mentions.md +1 -1
  176. package/examples/component-menu-item.md +1 -1
  177. package/examples/component-menu-list.md +1 -1
  178. package/examples/component-menu.md +1 -1
  179. package/examples/component-menubar.md +1 -1
  180. package/examples/component-message.md +1 -1
  181. package/examples/component-mobile-stepper.md +1 -1
  182. package/examples/component-modal.md +5 -5
  183. package/examples/component-navigation-menu.md +1 -1
  184. package/examples/component-notification.md +1 -1
  185. package/examples/component-outlined-input.md +1 -1
  186. package/examples/component-pagination.md +3 -3
  187. package/examples/component-paper.md +1 -1
  188. package/examples/component-popconfirm.md +1 -1
  189. package/examples/component-popover.md +3 -3
  190. package/examples/component-popper.md +1 -1
  191. package/examples/component-progress.md +2 -2
  192. package/examples/component-qr-code.md +1 -1
  193. package/examples/component-radio.md +3 -3
  194. package/examples/component-rate.md +2 -2
  195. package/examples/component-resizable.md +1 -1
  196. package/examples/component-result.md +1 -1
  197. package/examples/component-scroll-area.md +1 -1
  198. package/examples/component-segmented.md +3 -3
  199. package/examples/component-select.md +3 -3
  200. package/examples/component-separator.md +1 -1
  201. package/examples/component-sheet.md +1 -1
  202. package/examples/component-sidebar.md +1 -1
  203. package/examples/component-skeleton.md +3 -3
  204. package/examples/component-slide.md +1 -1
  205. package/examples/component-slider.md +3 -3
  206. package/examples/component-snackbar-content.md +1 -1
  207. package/examples/component-snackbar.md +1 -1
  208. package/examples/component-sonner.md +1 -1
  209. package/examples/component-space.md +1 -1
  210. package/examples/component-speed-dial-action.md +1 -1
  211. package/examples/component-speed-dial.md +1 -1
  212. package/examples/component-spin.md +2 -2
  213. package/examples/component-spinner.md +1 -1
  214. package/examples/component-splitter.md +2 -2
  215. package/examples/component-stack.md +1 -1
  216. package/examples/component-statistic.md +1 -1
  217. package/examples/component-step-button.md +4 -4
  218. package/examples/component-step-connector.md +4 -4
  219. package/examples/component-step-content.md +1 -1
  220. package/examples/component-step-icon.md +1 -1
  221. package/examples/component-step-label.md +1 -1
  222. package/examples/component-step.md +2 -2
  223. package/examples/component-steps.md +2 -2
  224. package/examples/component-swipeable-drawer.md +1 -1
  225. package/examples/component-switch.md +3 -3
  226. package/examples/component-tab-scroll-button.md +5 -5
  227. package/examples/component-tab.md +1 -1
  228. package/examples/component-table-body.md +1 -1
  229. package/examples/component-table-cell.md +1 -1
  230. package/examples/component-table-container.md +1 -1
  231. package/examples/component-table-footer.md +1 -1
  232. package/examples/component-table-head.md +1 -1
  233. package/examples/component-table-pagination.md +1 -1
  234. package/examples/component-table-row.md +1 -1
  235. package/examples/component-table-sort-label.md +1 -1
  236. package/examples/component-table.md +2 -2
  237. package/examples/component-tabs.md +3 -3
  238. package/examples/component-tag-badge.md +2 -2
  239. package/examples/component-tag.md +1 -1
  240. package/examples/component-textarea-autosize.md +1 -1
  241. package/examples/component-textarea.md +1 -1
  242. package/examples/component-time-picker.md +1 -1
  243. package/examples/component-timeline.md +1 -1
  244. package/examples/component-toast.md +4 -4
  245. package/examples/component-toggle-button.md +1 -1
  246. package/examples/component-toggle.md +1 -1
  247. package/examples/component-toolbar.md +1 -1
  248. package/examples/component-tooltip.md +3 -3
  249. package/examples/component-tour.md +1 -1
  250. package/examples/component-transfer.md +1 -1
  251. package/examples/component-tree-select.md +1 -1
  252. package/examples/component-tree.md +1 -1
  253. package/examples/component-typography.md +2 -2
  254. package/examples/component-upload.md +1 -1
  255. package/examples/component-watermark.md +1 -1
  256. package/examples/component-zoom.md +1 -1
  257. package/knowledge/COVERAGE.md +12 -9
  258. package/knowledge/components/INDEX.md +202 -202
  259. package/knowledge/i18n/korean-density-conventions.md +108 -0
  260. package/knowledge/i18n/korean-product-conventions.md +2 -0
  261. package/knowledge/patterns/async-control.md +233 -0
  262. package/knowledge/patterns/brand-references.md +72 -72
  263. package/knowledge/patterns/error-states.md +1 -0
  264. package/knowledge/patterns/form-design.md +2 -0
  265. package/package.json +1 -1
  266. package/tools/audit/local-ci.py +16 -1
  267. package/tools/audit/package-smoke.py +611 -9
  268. package/tools/audit/registry-smoke.py +537 -3
  269. package/tools/audit/release-metadata.py +47 -1
  270. package/tools/audit/smoke_assertions.py +918 -13
  271. package/tools/migrations/refs-links-to-reference-pages.py +179 -0
@@ -0,0 +1,108 @@
1
+ <!-- hand-written -->
2
+ ---
3
+ title: Korean B2B density conventions
4
+ applies_to: [web, mobile, all-ui, korean]
5
+ version: 1.0.0
6
+ last_updated: 2026-07
7
+ stability: stable
8
+ ---
9
+
10
+ # Korean B2B density conventions
11
+
12
+ Korean enterprise software — ERP, HR, groupware, admin consoles, financial back-office — is visibly denser than its Western counterpart, and denser again than Korean *consumer* apps. A Western enterprise layout ported unchanged into a Korean B2B product reads as sparse, slow, and "not serious." This file is the density half of the Korean playbook; for consumer density and the broader Korean conventions, see [`knowledge/i18n/korean-product-conventions.md`](korean-product-conventions.md).
13
+
14
+ ## Why Korean B2B is denser
15
+
16
+ - **Information-per-screen is a value, not a cost.** Power users (accountants, HR admins, operators) work the same screens all day and want everything in view — more rows, more columns, fewer clicks to the next field. Scrolling and pagination read as friction, not breathing room.
17
+ - **The reference points are dense.** 더존, 영림원, SAP-Korea deployments, government e-gov portals, and bank back-office tools set the expectation. Naver Works / Kakao Work admin, Toss Business, and 뱅크샐러드 business consoles are the modern-but-still-dense benchmark.
18
+ - **Hangul carries more meaning per character.** A Korean label is often shorter than its English equivalent for the same content, so the same row holds more without feeling cramped.
19
+
20
+ This is a deliberate register, not clutter. The craft is being dense **and** legible — not dense **and** broken.
21
+
22
+ ## The density ladder
23
+
24
+ Pick a mode per surface and hold it. Do not mix comfortable and compact rows in one table.
25
+
26
+ | Mode | Row height (approx) | Use for |
27
+ | --- | --- | --- |
28
+ | **Comfortable** | 48–56px | Consumer-facing, onboarding, marketing-in-product, low-frequency admin |
29
+ | **Cozy** (default KR B2B) | 36–44px | Most enterprise tables, forms, lists — the Korean B2B baseline |
30
+ | **Compact** | 28–32px | Data grids for power users, financial ledgers, high-row-count monitoring |
31
+
32
+ Western enterprise defaults to Comfortable; **Korean B2B defaults to Cozy.** Porting in usually means dropping one rung: reduce vertical padding ~15–25% and expect 30–50% more rows per fold. Offer a density toggle (Comfortable / Cozy / Compact) on heavy data surfaces so individual operators can go denser; persist the choice per user.
33
+
34
+ ## Tables are the center of gravity
35
+
36
+ Korean B2B UIs are table-first. Most screens are a filter bar plus a table.
37
+
38
+ - **Many columns are normal.** 8–15 columns is routine; horizontal scroll with a **frozen first column** (and often a frozen header row) beats hiding columns behind a menu.
39
+ - **Compact rows, aligned numerals.** Right-align numbers and currency, use tabular figures, and keep row height in the Cozy/Compact band. See [`knowledge/patterns/money-and-amount.md`](../patterns/money-and-amount.md) for amount formatting.
40
+ - **Inline row actions.** Put edit / delete / detail as compact icon buttons or a trailing action cell, not behind a per-row overflow menu that costs an extra click.
41
+ - **Sticky context.** Freeze the header and the key identity column (사번, 거래처, 전표번호) so the operator never loses the row's identity while scrolling wide.
42
+ - **Totals and subtotals in view.** A pinned footer row with sums/counts is expected on financial and inventory tables — operators reconcile against it constantly.
43
+ - **Zebra or hairline rules, not heavy borders.** At Cozy/Compact density, 1px hairline separators or subtle zebra striping keep rows scannable without adding visual weight.
44
+
45
+ ## Forms at density
46
+
47
+ - **Label-left (horizontal) layout** is the Korean B2B default for data-entry forms — it packs more fields per vertical space than label-top and matches the ledger-like mental model. Label-top is for consumer/onboarding.
48
+ - **Multi-column forms.** Two or three field columns per row are normal for registration and master-data screens. Group by section with thin dividers, not big gaps.
49
+ - **Tight field spacing.** Reduce inter-field vertical rhythm versus consumer forms; keep it consistent so the grid reads cleanly. See [`knowledge/patterns/form-design.md`](../patterns/form-design.md).
50
+ - **Required/optional density.** Mark required with a compact indicator (asterisk or a small "필수" chip); don't spend a whole helper-text line per field unless the rule is non-obvious.
51
+ - **Keyboard-first.** Power users tab through fields fast. Preserve a logical tab order, support Enter-to-next where appropriate, and don't trap focus in date/select popovers.
52
+
53
+ ## Lists, trees, and navigation
54
+
55
+ - **Dense list rows** with secondary metadata inline (status chip, date, owner on one line) rather than stacked. See [`knowledge/patterns/list-and-feed.md`](../patterns/list-and-feed.md).
56
+ - **Tree navigation** (조직도, 계정과목, 메뉴 권한) is common and should stay compact — small row height, clear expand affordances, many levels visible at once.
57
+ - **Persistent side navigation** with dense, possibly two-level menus is expected over hamburger-hidden nav; enterprise users want the whole map visible. This is the opposite of the consumer preference noted in [`korean-product-conventions.md`](korean-product-conventions.md).
58
+
59
+ ## Typography at density
60
+
61
+ - **Base size can drop, but not below legibility.** 13–14px body is common in KR B2B tables (vs 16px consumer). Do not go below ~12px for Hangul primary content — Hangul syllable blocks lose legibility faster than Latin at small sizes.
62
+ - **Line-height stays generous relative to size.** Even dense Korean text needs ~1.4–1.5 line-height for the syllable blocks to breathe; do not crush leading to save space. See [`knowledge/i18n/korean-typography.md`](korean-typography.md).
63
+ - **Numerals: tabular, aligned.** Financial density depends on figures lining up.
64
+ - **Truncate with intent.** Ellipsize long values with a tooltip/title for the full string rather than wrapping and breaking row rhythm.
65
+
66
+ ## Density must not break accessibility
67
+
68
+ Density is the constraint; accessibility is the floor. When they conflict, accessibility wins.
69
+
70
+ - **Touch targets.** On touch/hybrid B2B (tablets on the floor, POS, hospital carts), keep interactive targets ≥ 44×44px *hit area* even when the visual row is compact — expand the clickable area beyond the visible cell rather than shrinking the target.
71
+ - **Contrast holds at every density.** Hairline separators and secondary text must still meet WCAG contrast; dense does not mean low-contrast gray-on-gray. See [`knowledge/a11y/contrast.md`](../a11y/contrast.md).
72
+ - **Focus visibility.** A visible focus ring is non-negotiable for keyboard-driven data entry; ensure it is not clipped by tight row borders. See [`knowledge/a11y/keyboard-and-focus.md`](../a11y/keyboard-and-focus.md).
73
+ - **Density toggle as an a11y affordance.** Offering Comfortable mode is itself an accessibility accommodation for users who need larger targets and text.
74
+
75
+ ## Tokens consumed
76
+
77
+ ```
78
+ --space-2xs, --space-xs (dense row padding, inter-field gaps)
79
+ --space-sm (section spacing at density)
80
+ --row-height-compact (or --space-based row sizing)
81
+ --font-size-sm (13–14px dense body)
82
+ --line-height-normal (~1.4–1.5 for Hangul)
83
+ --color-border-subtle (hairline separators)
84
+ --color-bg-subtle (zebra striping)
85
+ --color-text-secondary (inline metadata)
86
+ --color-text-tabular (aligned numerals)
87
+ ```
88
+
89
+ Define a **density scale** as tokens (comfortable / cozy / compact row heights + padding) so the toggle flips a token set, not ad-hoc per-component values.
90
+
91
+ ## Don't
92
+
93
+ - Don't ship Western enterprise comfortable-density defaults unchanged into a Korean B2B product — it reads as sparse and unserious.
94
+ - Don't hide columns behind menus to avoid width — Korean power users prefer horizontal scroll with frozen columns.
95
+ - Don't mix row-height modes within one table.
96
+ - Don't crush Hangul below ~12px or crush line-height to gain rows — legibility breaks before the space saved is worth it.
97
+ - Don't let density erode contrast, focus rings, or touch-target hit areas.
98
+ - Don't bury per-row actions behind an overflow menu on high-frequency screens — inline them.
99
+ - Don't apply consumer nav patterns (hamburger, hidden tabs) to enterprise — surface the full dense menu.
100
+
101
+ ## Cross-reference
102
+
103
+ - [`knowledge/i18n/korean-product-conventions.md`](korean-product-conventions.md) — consumer density and the broader Korean conventions this file specializes from
104
+ - [`knowledge/i18n/korean-typography.md`](korean-typography.md) — Hangul sizing and line-height at density
105
+ - [`knowledge/patterns/form-design.md`](../patterns/form-design.md) — label-left, multi-column, dense forms
106
+ - [`knowledge/patterns/list-and-feed.md`](../patterns/list-and-feed.md) — dense list rows and data grids
107
+ - [`knowledge/patterns/money-and-amount.md`](../patterns/money-and-amount.md) — tabular numerals and aligned amounts
108
+ - [`knowledge/a11y/contrast.md`](../a11y/contrast.md), [`knowledge/a11y/keyboard-and-focus.md`](../a11y/keyboard-and-focus.md) — the accessibility floor density must respect
@@ -58,6 +58,8 @@ This is not "cluttered design" — it matches reading pace and screen-time habit
58
58
 
59
59
  Reference: see how Coupang, Naver, KakaoTalk, Toss differ from Amazon, Google, WhatsApp, Robinhood.
60
60
 
61
+ For enterprise / B2B density (denser again — ERP, HR, groupware, admin, financial back-office), see [`knowledge/i18n/korean-density-conventions.md`](korean-density-conventions.md).
62
+
61
63
  ## Color associations
62
64
 
63
65
  Different from Western color symbolism:
@@ -0,0 +1,233 @@
1
+ <!-- hand-written -->
2
+ ---
3
+ title: Async control patterns
4
+ applies_to: [web, mobile, all-ui]
5
+ version: 1.0.0
6
+ last_updated: 2026-07
7
+ stability: stable
8
+ ---
9
+
10
+ # Async control patterns
11
+
12
+ Every action that talks to a server has an in-flight life. This file is about that life — the moment between the tap and the answer — not about the error screen at the end (see [`patterns/error-states.md`](error-states.md) for that). Get the in-flight state wrong and you get the two most common async bugs in product UIs: double submits and stuck spinners.
13
+
14
+ ## The async action lifecycle
15
+
16
+ Every async action moves through the same four states. Model them explicitly; do not infer "loading" from the absence of data.
17
+
18
+ ```
19
+ idle ──trigger──▶ pending ──┬──▶ success ──▶ idle
20
+ ▲ │
21
+ └─────────────────────────┴──▶ error ────▶ idle (retryable)
22
+ ```
23
+
24
+ | State | The control shows | The user can |
25
+ | --- | --- | --- |
26
+ | **idle** | Its normal, enabled label | Trigger the action |
27
+ | **pending** | Busy affordance + disabled | Wait, or cancel (if cancellable) |
28
+ | **success** | Brief confirmation, then idle | Continue |
29
+ | **error** | Recovery affordance | Retry or recover — see `error-states.md` |
30
+
31
+ Rule: a control never sits in `pending` forever. Every request has a timeout that forces it to `error`.
32
+
33
+ ## Action controls during pending
34
+
35
+ The trigger control (button, menu item, toggle) is where most async bugs live.
36
+
37
+ | Do | Don't |
38
+ | --- | --- |
39
+ | Disable the control while its own action is in flight | Leave it clickable and hope |
40
+ | Show a busy affordance **inside or beside** the control | Replace the whole screen with a spinner for a single button |
41
+ | Keep the label readable — swap to a present-progressive verb | Blank the label to just a spinner (the user forgets what they clicked) |
42
+ | Restore the control on success **and** error | Leave it disabled after a failed request |
43
+
44
+ Label swap, Korean and English:
45
+
46
+ | Idle | Pending | Done |
47
+ | --- | --- | --- |
48
+ | 저장 | 저장 중… | 저장됨 |
49
+ | 불러오기 | 불러오는 중… | — |
50
+ | 결제하기 | 결제 처리 중… | 결제 완료 |
51
+ | 제출 | 제출 중… | — |
52
+
53
+ ```
54
+ ┌─────────────────┐ ┌─────────────────┐
55
+ │ 저장 │ → │ ◌ 저장 중… │ (disabled, spinner leads label)
56
+ └─────────────────┘ └─────────────────┘
57
+ ```
58
+
59
+ ## Double-submit prevention
60
+
61
+ The single most important async rule: **a control that started an action cannot start it again until that action resolves.** Disabling on `pending` handles the fast double-tap. Also guard the handler itself, because disabled is a UI state that a determined tap (or a slow render) can beat.
62
+
63
+ ```tsx
64
+ function SubmitButton({ onSubmit }) {
65
+ const [status, setStatus] = useState("idle"); // idle | pending | error
66
+
67
+ async function handleClick() {
68
+ if (status === "pending") return; // guard: not just the disabled attr
69
+ setStatus("pending");
70
+ try {
71
+ await onSubmit();
72
+ setStatus("idle");
73
+ } catch (err) {
74
+ setStatus("error"); // hand off to error-states.md
75
+ }
76
+ }
77
+
78
+ return (
79
+ <Button onClick={handleClick} disabled={status === "pending"} aria-busy={status === "pending"}>
80
+ {status === "pending" ? "저장 중…" : "저장"}
81
+ </Button>
82
+ );
83
+ }
84
+ ```
85
+
86
+ For money and irreversible actions (payment, transfer, delete), double-submit guarding is a correctness requirement, not a nicety. Pair the client guard with a server-side idempotency key — cite [`patterns/money-and-amount.md`](money-and-amount.md).
87
+
88
+ ## Choosing a loading affordance by duration
89
+
90
+ Match the indicator to how long the wait actually is. Guessing wrong is worse than no indicator.
91
+
92
+ | Expected wait | Affordance | Why |
93
+ | --- | --- | --- |
94
+ | < 100ms | **Nothing** | Faster than perception; a flashed spinner reads as a glitch |
95
+ | 100ms – 1s | **In-place busy** (button spinner, subtle) | Confirms the tap registered |
96
+ | 1s – 10s | **Skeleton** (for content) or **progress** (for known-length work) | Shows shape/position; feels faster than a spinner |
97
+ | > 10s | **Progress + cancel + background option** | Let the user leave and be notified |
98
+ | Unknown length | **Indeterminate spinner with a timeout** | Never an infinite bar |
99
+
100
+ Spinner vs skeleton: a spinner says "something is happening"; a skeleton says "*this* is what's coming and where." Prefer skeletons for content regions (lists, cards, detail panes) — see [`patterns/list-and-feed.md`](list-and-feed.md). Reserve spinners for actions and small inline waits.
101
+
102
+ Anti-flicker: if you show a delayed spinner (only after 100–300ms), also hold it for a minimum (~300ms) once shown, so a request that resolves at 310ms doesn't flash. Delay-in, min-hold-out.
103
+
104
+ ## Optimistic updates
105
+
106
+ Apply the change in the UI immediately, before the server confirms, then reconcile.
107
+
108
+ Use optimistic when: the action almost always succeeds, is cheap to reverse, and the wait would break flow — likes, toggles, reordering, adding a to-do, marking read.
109
+
110
+ Do **not** use optimistic when: the action is money, irreversible, or the server is the source of truth for the result (payment, booking a seat, submitting an exam). There, show real `pending` and wait.
111
+
112
+ ```
113
+ tap ─▶ update UI now ─▶ fire request ─┬─ ok: keep, drop the "syncing" mark
114
+ └─ fail: roll back to prior value + show why
115
+ ```
116
+
117
+ Rules:
118
+ - Keep the pre-action value so you can roll back exactly.
119
+ - Mark optimistic items as unconfirmed (subtle) until the server agrees, so a rollback isn't a jarring surprise.
120
+ - On rollback, tell the user what reverted and why — a silent snap-back looks like a bug.
121
+
122
+ ## Debounce and throttle for async-triggering input
123
+
124
+ Input that fires requests as the user types or drags must be rate-limited, or it floods the server and races itself.
125
+
126
+ | Technique | Fires | Use for |
127
+ | --- | --- | --- |
128
+ | **Debounce** (wait for a pause) | Once, after input stops for N ms | Search-as-you-type (250–350ms), autosave (500ms–2s) |
129
+ | **Throttle** (at most every N ms) | On a steady cadence | Drag/scroll-driven fetches, live position updates |
130
+ | **Leading + trailing** | Immediately, then once more at the end | Feels responsive but still settles |
131
+
132
+ Debounce is about *when to fire*; cancellation (next section) is about *what to do with requests already in flight*. You need both.
133
+
134
+ ## Cancellation and out-of-order responses
135
+
136
+ Two requests fired in order can return out of order. Without cancellation, an older, slower response overwrites a newer one — the classic "I typed 서울, it shows 서" bug.
137
+
138
+ - Cancel the previous in-flight request when a new one supersedes it (`AbortController` on the web).
139
+ - Cancel in-flight requests when the component unmounts or the user navigates away.
140
+ - If you cannot cancel, **guard on apply**: tag each request and ignore any response that isn't the latest.
141
+
142
+ ```tsx
143
+ useEffect(() => {
144
+ const controller = new AbortController();
145
+ fetchResults(query, { signal: controller.signal })
146
+ .then(setResults)
147
+ .catch(ignoreAbort);
148
+ return () => controller.abort(); // supersede on new query / unmount
149
+ }, [query]);
150
+ ```
151
+
152
+ ## Concurrency policy
153
+
154
+ When the same action can be triggered while one is running, decide the policy on purpose:
155
+
156
+ | Policy | Behavior | Use for |
157
+ | --- | --- | --- |
158
+ | **Block** | Ignore new triggers until the current resolves | Submits, payments (with double-submit guard) |
159
+ | **Latest-wins** | Cancel the running one, keep only the newest | Search, filters, autosave |
160
+ | **Queue** | Run in order, one at a time | Ordered writes that must all land |
161
+ | **Parallel** | Let all run | Independent reads |
162
+
163
+ Default to **block** for writes and **latest-wins** for reads unless you have a reason otherwise.
164
+
165
+ ## Timeouts and the stuck-spinner failure
166
+
167
+ A spinner with no timeout is a trap: on a dropped connection it spins forever and the user is stuck.
168
+
169
+ - Give every request a client timeout (e.g. 10–30s by operation).
170
+ - On timeout, transition to `error` with a retry — hand off to [`patterns/error-states.md`](error-states.md) (network/server section, retry with backoff).
171
+ - For genuinely long work (video processing, exports), don't hold a spinner — move to a **background job** pattern: acknowledge, let the user leave, notify on completion.
172
+
173
+ ## Perceived performance
174
+
175
+ The felt speed of an async UI is mostly about what you show during the wait:
176
+
177
+ - **Optimistic UI** — instant for reversible actions (above).
178
+ - **Skeletons** — for content; show structure, not a void.
179
+ - **Stale-while-revalidate** — show the last known data immediately, refresh in the background, swap in quietly. Mark it subtly as refreshing so a change isn't startling.
180
+ - **Progressive reveal** — render what's ready (shell, then data) instead of blocking on the slowest piece.
181
+
182
+ ## Tokens consumed
183
+
184
+ ```
185
+ --color-accent (spinner, progress fill)
186
+ --color-text-secondary (pending label, "저장 중…")
187
+ --color-text-tertiary (unconfirmed / optimistic mark, "동기화 중")
188
+ --color-bg-subtle (skeleton base)
189
+ --color-bg-elevated (skeleton shimmer highlight)
190
+ --radius-md
191
+ --space-xs, --space-sm
192
+ --duration-fast (spinner delay-in / min-hold)
193
+ --easing-standard
194
+ ```
195
+
196
+ ## Accessibility
197
+
198
+ - Set `aria-busy="true"` on a control or region while its action is pending; clear it when resolved.
199
+ - Announce state changes politely: a visually-hidden `role="status"` (`aria-live="polite"`) region saying "저장 중" then "저장됨". Do not use `assertive` for routine progress — reserve that for errors (see `error-states.md`).
200
+ - Keep the control's accessible name stable and meaningful during pending — the label swap ("저장" → "저장 중…") is fine; an icon-only spinner with no name is not.
201
+ - On success that removes the control (e.g. a submit that navigates), move focus deliberately to the next logical element; never drop focus to `<body>`.
202
+ - Respect `prefers-reduced-motion`: swap spinners/shimmer for a static or fade indicator.
203
+ - Disabled-while-pending must still be perceivable — don't rely on color alone; the busy affordance carries the meaning.
204
+
205
+ ## Korean considerations
206
+
207
+ Per [`knowledge/i18n/korean-product-conventions.md`](../i18n/korean-product-conventions.md):
208
+ - Progress labels use the present-progressive `~중…`: "저장 중…", "불러오는 중…", "처리 중…", "결제 처리 중…".
209
+ - Keep pending labels short — Korean verbs + `중…` stay compact, so the button width rarely jumps.
210
+ - For payment and transfer flows, show explicit real `pending` (never optimistic) and a clear "결제 처리 중…" state; cite [`knowledge/i18n/korean-payments.md`](../i18n/korean-payments.md) for the surrounding flow and failure messages.
211
+ - Dense Korean B2B layouts favor in-place busy affordances (inline spinner, row-level skeleton) over full-page blocking overlays — cite [`knowledge/i18n/korean-product-conventions.md`](../i18n/korean-product-conventions.md) on density.
212
+
213
+ ## Don't
214
+
215
+ - Don't leave a control clickable during its own async action — the double-submit bug.
216
+ - Don't guard double-submit with the disabled attribute alone; guard the handler too.
217
+ - Don't show a spinner for a sub-100ms wait — it reads as a flicker.
218
+ - Don't show a spinner that can spin forever — every request has a timeout.
219
+ - Don't blank a button to a bare spinner; keep a readable pending label.
220
+ - Don't use optimistic updates for money, payments, or irreversible actions.
221
+ - Don't let an older response overwrite a newer one — cancel or guard-on-apply.
222
+ - Don't hold a full-screen spinner for long work — move it to a background job with notify.
223
+ - Don't roll back an optimistic change silently — say what reverted and why.
224
+ - Don't announce routine progress with `aria-live="assertive"` — that's for errors.
225
+
226
+ ## Cross-reference
227
+
228
+ - [`knowledge/patterns/error-states.md`](error-states.md) — where the `error` state goes: recovery, retry-with-backoff, network/server messages
229
+ - [`knowledge/patterns/form-design.md`](form-design.md) — submit buttons, validation-in-flight, form-level pending
230
+ - [`knowledge/patterns/list-and-feed.md`](list-and-feed.md) — skeletons, pull-to-refresh, infinite scroll loading
231
+ - [`knowledge/patterns/empty-states.md`](empty-states.md) — the resolved-but-no-data end state, distinct from loading
232
+ - [`knowledge/patterns/money-and-amount.md`](money-and-amount.md) — why money actions use real pending + idempotency, never optimistic
233
+ - [`knowledge/i18n/korean-payments.md`](../i18n/korean-payments.md) — payment in-flight and failure states
@@ -2,7 +2,7 @@
2
2
  title: Brand reference index
3
3
  source: refs/awesome-design-md/design-md/
4
4
  upstream: https://github.com/VoltAgent/awesome-design-md
5
- extracted_at: 2026-05-19
5
+ extracted_at: 2026-07-03
6
6
  applies_to: [art-direction, brand-research]
7
7
  version: 1.0.0
8
8
  last_updated: 2026-05
@@ -16,77 +16,77 @@ Curated design notes on 71 brands. When designing for a comparable category, ope
16
16
  | Brand | Files |
17
17
  | --- | --- |
18
18
 
19
- | **[airbnb](../../refs/awesome-design-md/design-md/airbnb/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/airbnb/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/airbnb/README.md) |
20
- | **[airtable](../../refs/awesome-design-md/design-md/airtable/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/airtable/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/airtable/README.md) |
21
- | **[apple](../../refs/awesome-design-md/design-md/apple/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/apple/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/apple/README.md) |
22
- | **[binance](../../refs/awesome-design-md/design-md/binance/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/binance/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/binance/README.md) |
23
- | **[bmw](../../refs/awesome-design-md/design-md/bmw/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/bmw/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/bmw/README.md) |
24
- | **[bmw-m](../../refs/awesome-design-md/design-md/bmw-m/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/bmw-m/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/bmw-m/README.md) |
25
- | **[bugatti](../../refs/awesome-design-md/design-md/bugatti/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/bugatti/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/bugatti/README.md) |
26
- | **[cal](../../refs/awesome-design-md/design-md/cal/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/cal/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/cal/README.md) |
27
- | **[claude](../../refs/awesome-design-md/design-md/claude/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/claude/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/claude/README.md) |
28
- | **[clay](../../refs/awesome-design-md/design-md/clay/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/clay/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/clay/README.md) |
29
- | **[clickhouse](../../refs/awesome-design-md/design-md/clickhouse/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/clickhouse/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/clickhouse/README.md) |
30
- | **[cohere](../../refs/awesome-design-md/design-md/cohere/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/cohere/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/cohere/README.md) |
31
- | **[coinbase](../../refs/awesome-design-md/design-md/coinbase/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/coinbase/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/coinbase/README.md) |
32
- | **[composio](../../refs/awesome-design-md/design-md/composio/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/composio/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/composio/README.md) |
33
- | **[cursor](../../refs/awesome-design-md/design-md/cursor/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/cursor/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/cursor/README.md) |
34
- | **[elevenlabs](../../refs/awesome-design-md/design-md/elevenlabs/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/elevenlabs/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/elevenlabs/README.md) |
35
- | **[expo](../../refs/awesome-design-md/design-md/expo/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/expo/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/expo/README.md) |
36
- | **[ferrari](../../refs/awesome-design-md/design-md/ferrari/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/ferrari/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/ferrari/README.md) |
37
- | **[figma](../../refs/awesome-design-md/design-md/figma/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/figma/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/figma/README.md) |
38
- | **[framer](../../refs/awesome-design-md/design-md/framer/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/framer/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/framer/README.md) |
39
- | **[hashicorp](../../refs/awesome-design-md/design-md/hashicorp/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/hashicorp/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/hashicorp/README.md) |
40
- | **[ibm](../../refs/awesome-design-md/design-md/ibm/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/ibm/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/ibm/README.md) |
41
- | **[intercom](../../refs/awesome-design-md/design-md/intercom/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/intercom/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/intercom/README.md) |
42
- | **[kraken](../../refs/awesome-design-md/design-md/kraken/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/kraken/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/kraken/README.md) |
43
- | **[lamborghini](../../refs/awesome-design-md/design-md/lamborghini/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/lamborghini/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/lamborghini/README.md) |
44
- | **[linear.app](../../refs/awesome-design-md/design-md/linear.app/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/linear.app/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/linear.app/README.md) |
45
- | **[lovable](../../refs/awesome-design-md/design-md/lovable/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/lovable/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/lovable/README.md) |
46
- | **[mastercard](../../refs/awesome-design-md/design-md/mastercard/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/mastercard/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/mastercard/README.md) |
47
- | **[meta](../../refs/awesome-design-md/design-md/meta/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/meta/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/meta/README.md) |
48
- | **[minimax](../../refs/awesome-design-md/design-md/minimax/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/minimax/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/minimax/README.md) |
49
- | **[mintlify](../../refs/awesome-design-md/design-md/mintlify/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/mintlify/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/mintlify/README.md) |
50
- | **[miro](../../refs/awesome-design-md/design-md/miro/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/miro/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/miro/README.md) |
51
- | **[mistral.ai](../../refs/awesome-design-md/design-md/mistral.ai/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/mistral.ai/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/mistral.ai/README.md) |
52
- | **[mongodb](../../refs/awesome-design-md/design-md/mongodb/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/mongodb/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/mongodb/README.md) |
53
- | **[nike](../../refs/awesome-design-md/design-md/nike/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/nike/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/nike/README.md) |
54
- | **[notion](../../refs/awesome-design-md/design-md/notion/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/notion/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/notion/README.md) |
55
- | **[nvidia](../../refs/awesome-design-md/design-md/nvidia/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/nvidia/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/nvidia/README.md) |
56
- | **[ollama](../../refs/awesome-design-md/design-md/ollama/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/ollama/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/ollama/README.md) |
57
- | **[opencode.ai](../../refs/awesome-design-md/design-md/opencode.ai/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/opencode.ai/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/opencode.ai/README.md) |
58
- | **[pinterest](../../refs/awesome-design-md/design-md/pinterest/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/pinterest/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/pinterest/README.md) |
59
- | **[playstation](../../refs/awesome-design-md/design-md/playstation/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/playstation/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/playstation/README.md) |
60
- | **[posthog](../../refs/awesome-design-md/design-md/posthog/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/posthog/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/posthog/README.md) |
61
- | **[raycast](../../refs/awesome-design-md/design-md/raycast/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/raycast/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/raycast/README.md) |
62
- | **[renault](../../refs/awesome-design-md/design-md/renault/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/renault/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/renault/README.md) |
63
- | **[replicate](../../refs/awesome-design-md/design-md/replicate/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/replicate/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/replicate/README.md) |
64
- | **[resend](../../refs/awesome-design-md/design-md/resend/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/resend/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/resend/README.md) |
65
- | **[revolut](../../refs/awesome-design-md/design-md/revolut/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/revolut/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/revolut/README.md) |
66
- | **[runwayml](../../refs/awesome-design-md/design-md/runwayml/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/runwayml/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/runwayml/README.md) |
67
- | **[sanity](../../refs/awesome-design-md/design-md/sanity/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/sanity/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/sanity/README.md) |
68
- | **[sentry](../../refs/awesome-design-md/design-md/sentry/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/sentry/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/sentry/README.md) |
69
- | **[shopify](../../refs/awesome-design-md/design-md/shopify/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/shopify/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/shopify/README.md) |
70
- | **[slack](../../refs/awesome-design-md/design-md/slack/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/slack/DESIGN.md) |
71
- | **[spacex](../../refs/awesome-design-md/design-md/spacex/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/spacex/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/spacex/README.md) |
72
- | **[spotify](../../refs/awesome-design-md/design-md/spotify/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/spotify/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/spotify/README.md) |
73
- | **[starbucks](../../refs/awesome-design-md/design-md/starbucks/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/starbucks/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/starbucks/README.md) |
74
- | **[stripe](../../refs/awesome-design-md/design-md/stripe/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/stripe/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/stripe/README.md) |
75
- | **[supabase](../../refs/awesome-design-md/design-md/supabase/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/supabase/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/supabase/README.md) |
76
- | **[superhuman](../../refs/awesome-design-md/design-md/superhuman/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/superhuman/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/superhuman/README.md) |
77
- | **[tesla](../../refs/awesome-design-md/design-md/tesla/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/tesla/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/tesla/README.md) |
78
- | **[theverge](../../refs/awesome-design-md/design-md/theverge/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/theverge/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/theverge/README.md) |
79
- | **[together.ai](../../refs/awesome-design-md/design-md/together.ai/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/together.ai/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/together.ai/README.md) |
80
- | **[uber](../../refs/awesome-design-md/design-md/uber/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/uber/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/uber/README.md) |
81
- | **[vercel](../../refs/awesome-design-md/design-md/vercel/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/vercel/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/vercel/README.md) |
82
- | **[vodafone](../../refs/awesome-design-md/design-md/vodafone/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/vodafone/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/vodafone/README.md) |
83
- | **[voltagent](../../refs/awesome-design-md/design-md/voltagent/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/voltagent/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/voltagent/README.md) |
84
- | **[warp](../../refs/awesome-design-md/design-md/warp/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/warp/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/warp/README.md) |
85
- | **[webflow](../../refs/awesome-design-md/design-md/webflow/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/webflow/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/webflow/README.md) |
86
- | **[wired](../../refs/awesome-design-md/design-md/wired/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/wired/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/wired/README.md) |
87
- | **[wise](../../refs/awesome-design-md/design-md/wise/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/wise/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/wise/README.md) |
88
- | **[x.ai](../../refs/awesome-design-md/design-md/x.ai/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/x.ai/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/x.ai/README.md) |
89
- | **[zapier](../../refs/awesome-design-md/design-md/zapier/)** | [`DESIGN.md`](../../refs/awesome-design-md/design-md/zapier/DESIGN.md), [`README.md`](../../refs/awesome-design-md/design-md/zapier/README.md) |
19
+ | **[airbnb](../../docs/reference/awesome-design-md.md#airbnb)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#airbnb), [`README.md`](../../docs/reference/awesome-design-md.md#airbnb) |
20
+ | **[airtable](../../docs/reference/awesome-design-md.md#airtable)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#airtable), [`README.md`](../../docs/reference/awesome-design-md.md#airtable) |
21
+ | **[apple](../../docs/reference/awesome-design-md.md#apple)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#apple), [`README.md`](../../docs/reference/awesome-design-md.md#apple) |
22
+ | **[binance](../../docs/reference/awesome-design-md.md#binance)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#binance), [`README.md`](../../docs/reference/awesome-design-md.md#binance) |
23
+ | **[bmw](../../docs/reference/awesome-design-md.md#bmw)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#bmw), [`README.md`](../../docs/reference/awesome-design-md.md#bmw) |
24
+ | **[bmw-m](../../docs/reference/awesome-design-md.md#bmw-m)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#bmw-m), [`README.md`](../../docs/reference/awesome-design-md.md#bmw-m) |
25
+ | **[bugatti](../../docs/reference/awesome-design-md.md#bugatti)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#bugatti), [`README.md`](../../docs/reference/awesome-design-md.md#bugatti) |
26
+ | **[cal](../../docs/reference/awesome-design-md.md#cal)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#cal), [`README.md`](../../docs/reference/awesome-design-md.md#cal) |
27
+ | **[claude](../../docs/reference/awesome-design-md.md#claude)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#claude), [`README.md`](../../docs/reference/awesome-design-md.md#claude) |
28
+ | **[clay](../../docs/reference/awesome-design-md.md#clay)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#clay), [`README.md`](../../docs/reference/awesome-design-md.md#clay) |
29
+ | **[clickhouse](../../docs/reference/awesome-design-md.md#clickhouse)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#clickhouse), [`README.md`](../../docs/reference/awesome-design-md.md#clickhouse) |
30
+ | **[cohere](../../docs/reference/awesome-design-md.md#cohere)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#cohere), [`README.md`](../../docs/reference/awesome-design-md.md#cohere) |
31
+ | **[coinbase](../../docs/reference/awesome-design-md.md#coinbase)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#coinbase), [`README.md`](../../docs/reference/awesome-design-md.md#coinbase) |
32
+ | **[composio](../../docs/reference/awesome-design-md.md#composio)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#composio), [`README.md`](../../docs/reference/awesome-design-md.md#composio) |
33
+ | **[cursor](../../docs/reference/awesome-design-md.md#cursor)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#cursor), [`README.md`](../../docs/reference/awesome-design-md.md#cursor) |
34
+ | **[elevenlabs](../../docs/reference/awesome-design-md.md#elevenlabs)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#elevenlabs), [`README.md`](../../docs/reference/awesome-design-md.md#elevenlabs) |
35
+ | **[expo](../../docs/reference/awesome-design-md.md#expo)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#expo), [`README.md`](../../docs/reference/awesome-design-md.md#expo) |
36
+ | **[ferrari](../../docs/reference/awesome-design-md.md#ferrari)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#ferrari), [`README.md`](../../docs/reference/awesome-design-md.md#ferrari) |
37
+ | **[figma](../../docs/reference/awesome-design-md.md#figma)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#figma), [`README.md`](../../docs/reference/awesome-design-md.md#figma) |
38
+ | **[framer](../../docs/reference/awesome-design-md.md#framer)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#framer), [`README.md`](../../docs/reference/awesome-design-md.md#framer) |
39
+ | **[hashicorp](../../docs/reference/awesome-design-md.md#hashicorp)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#hashicorp), [`README.md`](../../docs/reference/awesome-design-md.md#hashicorp) |
40
+ | **[ibm](../../docs/reference/awesome-design-md.md#ibm)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#ibm), [`README.md`](../../docs/reference/awesome-design-md.md#ibm) |
41
+ | **[intercom](../../docs/reference/awesome-design-md.md#intercom)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#intercom), [`README.md`](../../docs/reference/awesome-design-md.md#intercom) |
42
+ | **[kraken](../../docs/reference/awesome-design-md.md#kraken)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#kraken), [`README.md`](../../docs/reference/awesome-design-md.md#kraken) |
43
+ | **[lamborghini](../../docs/reference/awesome-design-md.md#lamborghini)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#lamborghini), [`README.md`](../../docs/reference/awesome-design-md.md#lamborghini) |
44
+ | **[linear.app](../../docs/reference/awesome-design-md.md#linearapp)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#linearapp), [`README.md`](../../docs/reference/awesome-design-md.md#linearapp) |
45
+ | **[lovable](../../docs/reference/awesome-design-md.md#lovable)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#lovable), [`README.md`](../../docs/reference/awesome-design-md.md#lovable) |
46
+ | **[mastercard](../../docs/reference/awesome-design-md.md#mastercard)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#mastercard), [`README.md`](../../docs/reference/awesome-design-md.md#mastercard) |
47
+ | **[meta](../../docs/reference/awesome-design-md.md#meta)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#meta), [`README.md`](../../docs/reference/awesome-design-md.md#meta) |
48
+ | **[minimax](../../docs/reference/awesome-design-md.md#minimax)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#minimax), [`README.md`](../../docs/reference/awesome-design-md.md#minimax) |
49
+ | **[mintlify](../../docs/reference/awesome-design-md.md#mintlify)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#mintlify), [`README.md`](../../docs/reference/awesome-design-md.md#mintlify) |
50
+ | **[miro](../../docs/reference/awesome-design-md.md#miro)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#miro), [`README.md`](../../docs/reference/awesome-design-md.md#miro) |
51
+ | **[mistral.ai](../../docs/reference/awesome-design-md.md#mistralai)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#mistralai), [`README.md`](../../docs/reference/awesome-design-md.md#mistralai) |
52
+ | **[mongodb](../../docs/reference/awesome-design-md.md#mongodb)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#mongodb), [`README.md`](../../docs/reference/awesome-design-md.md#mongodb) |
53
+ | **[nike](../../docs/reference/awesome-design-md.md#nike)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#nike), [`README.md`](../../docs/reference/awesome-design-md.md#nike) |
54
+ | **[notion](../../docs/reference/awesome-design-md.md#notion)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#notion), [`README.md`](../../docs/reference/awesome-design-md.md#notion) |
55
+ | **[nvidia](../../docs/reference/awesome-design-md.md#nvidia)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#nvidia), [`README.md`](../../docs/reference/awesome-design-md.md#nvidia) |
56
+ | **[ollama](../../docs/reference/awesome-design-md.md#ollama)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#ollama), [`README.md`](../../docs/reference/awesome-design-md.md#ollama) |
57
+ | **[opencode.ai](../../docs/reference/awesome-design-md.md#opencodeai)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#opencodeai), [`README.md`](../../docs/reference/awesome-design-md.md#opencodeai) |
58
+ | **[pinterest](../../docs/reference/awesome-design-md.md#pinterest)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#pinterest), [`README.md`](../../docs/reference/awesome-design-md.md#pinterest) |
59
+ | **[playstation](../../docs/reference/awesome-design-md.md#playstation)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#playstation), [`README.md`](../../docs/reference/awesome-design-md.md#playstation) |
60
+ | **[posthog](../../docs/reference/awesome-design-md.md#posthog)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#posthog), [`README.md`](../../docs/reference/awesome-design-md.md#posthog) |
61
+ | **[raycast](../../docs/reference/awesome-design-md.md#raycast)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#raycast), [`README.md`](../../docs/reference/awesome-design-md.md#raycast) |
62
+ | **[renault](../../docs/reference/awesome-design-md.md#renault)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#renault), [`README.md`](../../docs/reference/awesome-design-md.md#renault) |
63
+ | **[replicate](../../docs/reference/awesome-design-md.md#replicate)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#replicate), [`README.md`](../../docs/reference/awesome-design-md.md#replicate) |
64
+ | **[resend](../../docs/reference/awesome-design-md.md#resend)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#resend), [`README.md`](../../docs/reference/awesome-design-md.md#resend) |
65
+ | **[revolut](../../docs/reference/awesome-design-md.md#revolut)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#revolut), [`README.md`](../../docs/reference/awesome-design-md.md#revolut) |
66
+ | **[runwayml](../../docs/reference/awesome-design-md.md#runwayml)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#runwayml), [`README.md`](../../docs/reference/awesome-design-md.md#runwayml) |
67
+ | **[sanity](../../docs/reference/awesome-design-md.md#sanity)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#sanity), [`README.md`](../../docs/reference/awesome-design-md.md#sanity) |
68
+ | **[sentry](../../docs/reference/awesome-design-md.md#sentry)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#sentry), [`README.md`](../../docs/reference/awesome-design-md.md#sentry) |
69
+ | **[shopify](../../docs/reference/awesome-design-md.md#shopify)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#shopify), [`README.md`](../../docs/reference/awesome-design-md.md#shopify) |
70
+ | **[slack](../../docs/reference/awesome-design-md.md#slack)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#slack) |
71
+ | **[spacex](../../docs/reference/awesome-design-md.md#spacex)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#spacex), [`README.md`](../../docs/reference/awesome-design-md.md#spacex) |
72
+ | **[spotify](../../docs/reference/awesome-design-md.md#spotify)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#spotify), [`README.md`](../../docs/reference/awesome-design-md.md#spotify) |
73
+ | **[starbucks](../../docs/reference/awesome-design-md.md#starbucks)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#starbucks), [`README.md`](../../docs/reference/awesome-design-md.md#starbucks) |
74
+ | **[stripe](../../docs/reference/awesome-design-md.md#stripe)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#stripe), [`README.md`](../../docs/reference/awesome-design-md.md#stripe) |
75
+ | **[supabase](../../docs/reference/awesome-design-md.md#supabase)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#supabase), [`README.md`](../../docs/reference/awesome-design-md.md#supabase) |
76
+ | **[superhuman](../../docs/reference/awesome-design-md.md#superhuman)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#superhuman), [`README.md`](../../docs/reference/awesome-design-md.md#superhuman) |
77
+ | **[tesla](../../docs/reference/awesome-design-md.md#tesla)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#tesla), [`README.md`](../../docs/reference/awesome-design-md.md#tesla) |
78
+ | **[theverge](../../docs/reference/awesome-design-md.md#theverge)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#theverge), [`README.md`](../../docs/reference/awesome-design-md.md#theverge) |
79
+ | **[together.ai](../../docs/reference/awesome-design-md.md#togetherai)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#togetherai), [`README.md`](../../docs/reference/awesome-design-md.md#togetherai) |
80
+ | **[uber](../../docs/reference/awesome-design-md.md#uber)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#uber), [`README.md`](../../docs/reference/awesome-design-md.md#uber) |
81
+ | **[vercel](../../docs/reference/awesome-design-md.md#vercel)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#vercel), [`README.md`](../../docs/reference/awesome-design-md.md#vercel) |
82
+ | **[vodafone](../../docs/reference/awesome-design-md.md#vodafone)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#vodafone), [`README.md`](../../docs/reference/awesome-design-md.md#vodafone) |
83
+ | **[voltagent](../../docs/reference/awesome-design-md.md#voltagent)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#voltagent), [`README.md`](../../docs/reference/awesome-design-md.md#voltagent) |
84
+ | **[warp](../../docs/reference/awesome-design-md.md#warp)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#warp), [`README.md`](../../docs/reference/awesome-design-md.md#warp) |
85
+ | **[webflow](../../docs/reference/awesome-design-md.md#webflow)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#webflow), [`README.md`](../../docs/reference/awesome-design-md.md#webflow) |
86
+ | **[wired](../../docs/reference/awesome-design-md.md#wired)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#wired), [`README.md`](../../docs/reference/awesome-design-md.md#wired) |
87
+ | **[wise](../../docs/reference/awesome-design-md.md#wise)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#wise), [`README.md`](../../docs/reference/awesome-design-md.md#wise) |
88
+ | **[x.ai](../../docs/reference/awesome-design-md.md#xai)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#xai), [`README.md`](../../docs/reference/awesome-design-md.md#xai) |
89
+ | **[zapier](../../docs/reference/awesome-design-md.md#zapier)** | [`DESIGN.md`](../../docs/reference/awesome-design-md.md#zapier), [`README.md`](../../docs/reference/awesome-design-md.md#zapier) |
90
90
 
91
91
  ## How to use
92
92
 
@@ -312,6 +312,7 @@ function PageContent() {
312
312
 
313
313
  ## Cross-reference
314
314
 
315
+ - [`knowledge/patterns/async-control.md`](async-control.md) — the in-flight state before the error: pending, retry-on-timeout, double-submit
315
316
  - [`knowledge/patterns/empty-states.md`](empty-states.md) — when there's no data, but it's not an error
316
317
  - [`knowledge/patterns/form-design.md`](form-design.md) — validation errors at the field level
317
318
  - [`knowledge/i18n/korean-payments.md`](../i18n/korean-payments.md) — payment-specific error messages