@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.
- package/.claude-plugin/plugin.json +164 -0
- package/AGENTS.ko.md +126 -0
- package/AGENTS.md +182 -0
- package/CHANGELOG.md +6883 -0
- package/CLAUDE.md +39 -0
- package/LICENSE +21 -0
- package/README.ko.md +245 -0
- package/README.md +277 -0
- package/agents/README.md +14 -0
- package/agents/a11y-reviewer.md +121 -0
- package/agents/component-architect.md +57 -0
- package/agents/design-critic.md +46 -0
- package/agents/token-extractor.md +63 -0
- package/cli/bin/design-ai-mcp.mjs +6 -0
- package/cli/bin/design-ai.mjs +40 -0
- package/cli/commands/audit.mjs +111 -0
- package/cli/commands/check.mjs +226 -0
- package/cli/commands/doctor.mjs +141 -0
- package/cli/commands/examples.mjs +58 -0
- package/cli/commands/help.mjs +271 -0
- package/cli/commands/install.mjs +161 -0
- package/cli/commands/learn.mjs +1871 -0
- package/cli/commands/list.mjs +143 -0
- package/cli/commands/mcp.mjs +27 -0
- package/cli/commands/pack.mjs +211 -0
- package/cli/commands/prompt.mjs +199 -0
- package/cli/commands/route.mjs +247 -0
- package/cli/commands/search.mjs +60 -0
- package/cli/commands/show.mjs +52 -0
- package/cli/commands/site.mjs +558 -0
- package/cli/commands/status.mjs +161 -0
- package/cli/commands/uninstall.mjs +119 -0
- package/cli/commands/update.mjs +184 -0
- package/cli/commands/version.mjs +94 -0
- package/cli/commands/workspace.mjs +176 -0
- package/cli/lib/brief.mjs +52 -0
- package/cli/lib/check.mjs +642 -0
- package/cli/lib/dispatch.mjs +109 -0
- package/cli/lib/doctor.mjs +505 -0
- package/cli/lib/examples.mjs +258 -0
- package/cli/lib/exec.mjs +63 -0
- package/cli/lib/help-flags.mjs +5 -0
- package/cli/lib/learn.mjs +3694 -0
- package/cli/lib/log.mjs +47 -0
- package/cli/lib/mcp-server.mjs +426 -0
- package/cli/lib/output.mjs +101 -0
- package/cli/lib/pack.mjs +599 -0
- package/cli/lib/paths.mjs +63 -0
- package/cli/lib/prompt.mjs +603 -0
- package/cli/lib/route.mjs +740 -0
- package/cli/lib/search.mjs +158 -0
- package/cli/lib/show.mjs +161 -0
- package/cli/lib/signals.mjs +2337 -0
- package/cli/lib/site.mjs +6617 -0
- package/cli/lib/skill-proposals.mjs +2046 -0
- package/cli/lib/suggest.mjs +66 -0
- package/cli/lib/workspace.mjs +1056 -0
- package/commands/README.md +25 -0
- package/commands/component-spec.md +34 -0
- package/commands/conversational.md +44 -0
- package/commands/design-from-brief.md +141 -0
- package/commands/design-review.md +62 -0
- package/commands/document-from-brief.md +47 -0
- package/commands/extract-tokens.md +38 -0
- package/commands/game-ui.md +40 -0
- package/commands/illustration.md +37 -0
- package/commands/iterate.md +167 -0
- package/commands/motion-design.md +54 -0
- package/commands/palette-from-brand.md +50 -0
- package/commands/print.md +49 -0
- package/commands/slide-deck.md +46 -0
- package/commands/spatial.md +47 -0
- package/commands/stability-review.md +74 -0
- package/commands/video.md +42 -0
- package/commands/website-improvement.md +77 -0
- package/docs/AGENT-DEVELOPMENT.md +658 -0
- package/docs/AI-LEARNING.md +429 -0
- package/docs/AIDER-INTEGRATION.md +224 -0
- package/docs/ARCHITECTURE.ko.md +183 -0
- package/docs/ARCHITECTURE.md +105 -0
- package/docs/CODEX-INTEGRATION.md +311 -0
- package/docs/COMPANY-WEBSITE-DOGFOOD.ko.md +144 -0
- package/docs/COMPANY-WEBSITE-DOGFOOD.md +150 -0
- package/docs/COMPANY-WEBSITE-INTAKE-TEMPLATE.ko.md +153 -0
- package/docs/COMPANY-WEBSITE-INTAKE-TEMPLATE.md +154 -0
- package/docs/CONTRIBUTING.ko.md +203 -0
- package/docs/CONTRIBUTING.md +242 -0
- package/docs/CURSOR-INTEGRATION.md +220 -0
- package/docs/DISTRIBUTION.ko.md +248 -0
- package/docs/DISTRIBUTION.md +253 -0
- package/docs/DOGFOOD-FINDINGS.md +180 -0
- package/docs/DOGFOOD-V4-FINDINGS.md +139 -0
- package/docs/DOGFOOD-V4-MKDOCS-FINDINGS.md +233 -0
- package/docs/DOGFOOD-V4-NPM-FINDINGS.md +157 -0
- package/docs/DOGFOOD-V4-VSCODE-FINDINGS.md +135 -0
- package/docs/FIGMA-INTEGRATION.md +222 -0
- package/docs/MCP-INTEGRATION.md +243 -0
- package/docs/MIGRATION-v4.md +121 -0
- package/docs/PLUGIN-PACKAGING.md +240 -0
- package/docs/PRODUCT-READINESS.md +66 -0
- package/docs/QUICKSTART.ko.md +178 -0
- package/docs/QUICKSTART.md +179 -0
- package/docs/RELEASE-CHECKLIST.md +292 -0
- package/docs/ROADMAP.md +19495 -0
- package/docs/SESSION-LOG.md +940 -0
- package/docs/TOKEN-SYNC.md +237 -0
- package/docs/USING.ko.md +206 -0
- package/docs/USING.md +218 -0
- package/docs/WEBSITE-IMPROVEMENT.ko.md +75 -0
- package/docs/WEBSITE-IMPROVEMENT.md +89 -0
- package/docs/announcements/README.md +56 -0
- package/docs/announcements/dev-to-korea.md +206 -0
- package/docs/announcements/hashnode-post.ko.md +232 -0
- package/docs/announcements/okky-post.ko.md +158 -0
- package/docs/announcements/press-kit.md +101 -0
- package/docs/announcements/reddit-r-korea.md +196 -0
- package/docs/announcements/show-hn.md +114 -0
- package/docs/announcements/twitter-thread.md +255 -0
- package/docs/external-status.md +34 -0
- package/docs/integrations/aider-walkthrough.ko.md +275 -0
- package/docs/integrations/aider-walkthrough.md +274 -0
- package/docs/integrations/codex-walkthrough.ko.md +297 -0
- package/docs/integrations/codex-walkthrough.md +297 -0
- package/docs/integrations/cursor-walkthrough.ko.md +281 -0
- package/docs/integrations/cursor-walkthrough.md +284 -0
- package/docs/integrations/design-ai-mcp-server.md +169 -0
- package/docs/integrations/figma-mcp.md +149 -0
- package/docs/integrations/github-mcp.md +178 -0
- package/docs/integrations/linear-mcp.md +215 -0
- package/docs/integrations/notion-mcp.md +174 -0
- package/docs/integrations/sdk-walkthrough.ko.md +375 -0
- package/docs/integrations/sdk-walkthrough.md +375 -0
- package/docs/integrations/slack-mcp.md +208 -0
- package/docs/integrations/vscode-walkthrough.ko.md +202 -0
- package/docs/integrations/vscode-walkthrough.md +205 -0
- package/docs/requirements.txt +16 -0
- package/docs/site-overrides/extra.css +83 -0
- package/docs/site-overrides/favicon.svg +4 -0
- package/docs/site-overrides/logo.svg +10 -0
- package/docs/site-overrides/main.html +18 -0
- package/docs/website-console/app.js +2540 -0
- package/docs/website-console/index.html +24 -0
- package/docs/website-console/styles.css +975 -0
- package/examples/README.md +252 -0
- package/examples/cases/dogfood-v4-korean-hr-onboarding.md +356 -0
- package/examples/component-accordion-actions.md +153 -0
- package/examples/component-accordion-details.md +147 -0
- package/examples/component-accordion-summary.md +180 -0
- package/examples/component-accordion.md +229 -0
- package/examples/component-account-card.md +284 -0
- package/examples/component-address-input.md +260 -0
- package/examples/component-affix.md +190 -0
- package/examples/component-alert-dialog.md +210 -0
- package/examples/component-alert-title.md +77 -0
- package/examples/component-alert.md +192 -0
- package/examples/component-amount-input.md +278 -0
- package/examples/component-anchor.md +198 -0
- package/examples/component-app-bar.md +249 -0
- package/examples/component-aspect-ratio.md +156 -0
- package/examples/component-auto-complete.md +199 -0
- package/examples/component-avatar-group.md +170 -0
- package/examples/component-avatar.md +191 -0
- package/examples/component-back-top.md +123 -0
- package/examples/component-backdrop.md +148 -0
- package/examples/component-badge.md +181 -0
- package/examples/component-banner.md +237 -0
- package/examples/component-biometric-gate.md +281 -0
- package/examples/component-blockquote.md +153 -0
- package/examples/component-border-beam.md +207 -0
- package/examples/component-bottom-navigation.md +226 -0
- package/examples/component-box.md +112 -0
- package/examples/component-breadcrumb.md +222 -0
- package/examples/component-button-base.md +190 -0
- package/examples/component-button-group.md +117 -0
- package/examples/component-button.md +213 -0
- package/examples/component-calendar.md +280 -0
- package/examples/component-callout.md +131 -0
- package/examples/component-card-actions.md +101 -0
- package/examples/component-card-content.md +90 -0
- package/examples/component-card-header.md +122 -0
- package/examples/component-card-media.md +79 -0
- package/examples/component-card.md +233 -0
- package/examples/component-carousel.md +266 -0
- package/examples/component-cascader.md +135 -0
- package/examples/component-category-picker.md +271 -0
- package/examples/component-chart.md +237 -0
- package/examples/component-chat-interface.md +399 -0
- package/examples/component-checkbox.md +149 -0
- package/examples/component-click-away-listener.md +87 -0
- package/examples/component-code.md +213 -0
- package/examples/component-collapsible.md +219 -0
- package/examples/component-color-picker.md +110 -0
- package/examples/component-combobox.md +267 -0
- package/examples/component-command.md +299 -0
- package/examples/component-config-provider.md +190 -0
- package/examples/component-context-menu.md +179 -0
- package/examples/component-css-baseline.md +148 -0
- package/examples/component-date-picker.md +249 -0
- package/examples/component-descriptions.md +242 -0
- package/examples/component-dialog-actions.md +111 -0
- package/examples/component-dialog-content-text.md +76 -0
- package/examples/component-dialog-content.md +105 -0
- package/examples/component-dialog-title.md +104 -0
- package/examples/component-dialog.md +176 -0
- package/examples/component-divider.md +182 -0
- package/examples/component-doc-page.md +217 -0
- package/examples/component-drawer.md +257 -0
- package/examples/component-dropdown.md +220 -0
- package/examples/component-email-layout.md +253 -0
- package/examples/component-empty-state.md +269 -0
- package/examples/component-empty.md +172 -0
- package/examples/component-fade.md +87 -0
- package/examples/component-feature-grid.md +201 -0
- package/examples/component-field.md +266 -0
- package/examples/component-filled-input.md +114 -0
- package/examples/component-flex.md +117 -0
- package/examples/component-float-button.md +214 -0
- package/examples/component-form-control-label.md +134 -0
- package/examples/component-form-control.md +113 -0
- package/examples/component-form-controls.md +251 -0
- package/examples/component-form-group.md +86 -0
- package/examples/component-form-helper-text.md +95 -0
- package/examples/component-form-label.md +98 -0
- package/examples/component-form.md +291 -0
- package/examples/component-game-hud.md +362 -0
- package/examples/component-game-menu.md +327 -0
- package/examples/component-grid.md +140 -0
- package/examples/component-grow.md +79 -0
- package/examples/component-hero-block.md +252 -0
- package/examples/component-hover-card.md +211 -0
- package/examples/component-icon-button.md +142 -0
- package/examples/component-icon.md +102 -0
- package/examples/component-illustration.md +280 -0
- package/examples/component-image-list.md +107 -0
- package/examples/component-image.md +282 -0
- package/examples/component-input-adornment.md +101 -0
- package/examples/component-input-base.md +134 -0
- package/examples/component-input-number.md +141 -0
- package/examples/component-input-otp.md +271 -0
- package/examples/component-input.md +213 -0
- package/examples/component-item.md +243 -0
- package/examples/component-kbd.md +197 -0
- package/examples/component-krw-amount.md +219 -0
- package/examples/component-label.md +118 -0
- package/examples/component-layout.md +217 -0
- package/examples/component-link.md +223 -0
- package/examples/component-list-item-avatar.md +72 -0
- package/examples/component-list-item-button.md +139 -0
- package/examples/component-list-item-icon.md +82 -0
- package/examples/component-list-item-text.md +98 -0
- package/examples/component-list-item.md +116 -0
- package/examples/component-list-subheader.md +70 -0
- package/examples/component-list.md +198 -0
- package/examples/component-loading-button.md +125 -0
- package/examples/component-loading-sequence.md +254 -0
- package/examples/component-lottie-player.md +279 -0
- package/examples/component-masonry.md +191 -0
- package/examples/component-mentions.md +189 -0
- package/examples/component-menu-item.md +102 -0
- package/examples/component-menu-list.md +98 -0
- package/examples/component-menu.md +139 -0
- package/examples/component-menubar.md +259 -0
- package/examples/component-message.md +162 -0
- package/examples/component-mobile-stepper.md +155 -0
- package/examples/component-modal.md +220 -0
- package/examples/component-navigation-menu.md +295 -0
- package/examples/component-notification.md +166 -0
- package/examples/component-otp-countdown.md +245 -0
- package/examples/component-outlined-input.md +145 -0
- package/examples/component-page-transition.md +281 -0
- package/examples/component-pagination.md +226 -0
- package/examples/component-paper.md +199 -0
- package/examples/component-pass-auth.md +265 -0
- package/examples/component-payment-brand-button.md +253 -0
- package/examples/component-payment-method-selector.md +272 -0
- package/examples/component-payment-receipt.md +277 -0
- package/examples/component-popconfirm.md +144 -0
- package/examples/component-popover.md +239 -0
- package/examples/component-popper.md +129 -0
- package/examples/component-pricing-cards.md +247 -0
- package/examples/component-progress.md +195 -0
- package/examples/component-qr-code.md +201 -0
- package/examples/component-radio.md +167 -0
- package/examples/component-rate.md +202 -0
- package/examples/component-resizable.md +163 -0
- package/examples/component-result.md +270 -0
- package/examples/component-scroll-area.md +199 -0
- package/examples/component-scroll-reveal.md +320 -0
- package/examples/component-segmented.md +178 -0
- package/examples/component-select.md +258 -0
- package/examples/component-separator.md +177 -0
- package/examples/component-sheet.md +277 -0
- package/examples/component-sidebar.md +257 -0
- package/examples/component-skeleton.md +178 -0
- package/examples/component-slide.md +89 -0
- package/examples/component-slider.md +208 -0
- package/examples/component-snackbar-content.md +92 -0
- package/examples/component-snackbar.md +121 -0
- package/examples/component-sonner.md +165 -0
- package/examples/component-space.md +125 -0
- package/examples/component-spatial-locomotion.md +373 -0
- package/examples/component-spatial-panel.md +330 -0
- package/examples/component-speed-dial-action.md +78 -0
- package/examples/component-speed-dial.md +177 -0
- package/examples/component-spin.md +173 -0
- package/examples/component-spinner.md +204 -0
- package/examples/component-splitter.md +210 -0
- package/examples/component-stack.md +130 -0
- package/examples/component-statistic.md +282 -0
- package/examples/component-step-button.md +157 -0
- package/examples/component-step-connector.md +157 -0
- package/examples/component-step-content.md +121 -0
- package/examples/component-step-icon.md +115 -0
- package/examples/component-step-label.md +101 -0
- package/examples/component-step.md +84 -0
- package/examples/component-steps.md +264 -0
- package/examples/component-stock-chart.md +251 -0
- package/examples/component-swipeable-drawer.md +149 -0
- package/examples/component-switch.md +99 -0
- package/examples/component-tab-scroll-button.md +180 -0
- package/examples/component-tab.md +120 -0
- package/examples/component-table-body.md +82 -0
- package/examples/component-table-cell.md +118 -0
- package/examples/component-table-container.md +75 -0
- package/examples/component-table-footer.md +72 -0
- package/examples/component-table-head.md +78 -0
- package/examples/component-table-pagination.md +137 -0
- package/examples/component-table-row.md +113 -0
- package/examples/component-table-sort-label.md +109 -0
- package/examples/component-table.md +202 -0
- package/examples/component-tabs.md +184 -0
- package/examples/component-tag-badge.md +309 -0
- package/examples/component-tag.md +102 -0
- package/examples/component-testimonial-carousel.md +218 -0
- package/examples/component-textarea-autosize.md +114 -0
- package/examples/component-textarea.md +173 -0
- package/examples/component-time-picker.md +205 -0
- package/examples/component-timeline.md +170 -0
- package/examples/component-toast.md +224 -0
- package/examples/component-toggle-button.md +129 -0
- package/examples/component-toggle.md +220 -0
- package/examples/component-toolbar.md +104 -0
- package/examples/component-tooltip.md +178 -0
- package/examples/component-tour.md +176 -0
- package/examples/component-transaction-list-item.md +243 -0
- package/examples/component-transfer.md +156 -0
- package/examples/component-tree-select.md +202 -0
- package/examples/component-tree.md +297 -0
- package/examples/component-typography.md +215 -0
- package/examples/component-upload.md +295 -0
- package/examples/component-video-hero.md +409 -0
- package/examples/component-video-player.md +340 -0
- package/examples/component-voice-input.md +408 -0
- package/examples/component-watermark.md +217 -0
- package/examples/component-zoom.md +92 -0
- package/examples/doc-explanation-example.md +196 -0
- package/examples/doc-how-to-example.md +205 -0
- package/examples/doc-tutorial-example.md +162 -0
- package/examples/dogfood-korean-fintech-system.md +433 -0
- package/examples/email-transactional-example.md +259 -0
- package/examples/palette-saas-violet.md +235 -0
- package/examples/print-business-card-spec.md +205 -0
- package/examples/print-packaging-spec.md +285 -0
- package/examples/report-example.md +228 -0
- package/examples/slide-deck-example.md +237 -0
- package/examples/website-improvement-report.md +128 -0
- package/examples/website-improvement-workspace.json +126 -0
- package/install.sh +189 -0
- package/knowledge/COVERAGE.md +740 -0
- package/knowledge/PRINCIPLES.md +108 -0
- package/knowledge/a11y/contrast.md +70 -0
- package/knowledge/a11y/keyboard-and-focus.md +108 -0
- package/knowledge/colors/color-theory.md +90 -0
- package/knowledge/colors/mui-palette-structure.md +105 -0
- package/knowledge/colors/palettes-by-product-type.md +876 -0
- package/knowledge/components/INDEX.md +231 -0
- package/knowledge/components/index.json +1470 -0
- package/knowledge/components/shadcn-registry.md +159 -0
- package/knowledge/conversational/ai-chat-interfaces.md +323 -0
- package/knowledge/conversational/chatbot-design.md +312 -0
- package/knowledge/conversational/conversational-ui-fundamentals.md +299 -0
- package/knowledge/conversational/korean-voice-conventions.md +281 -0
- package/knowledge/conversational/voice-ui-patterns.md +297 -0
- package/knowledge/design-tokens/ant-design.md +124 -0
- package/knowledge/design-tokens/material-3.md +235 -0
- package/knowledge/design-tokens/polaris-and-carbon.md +231 -0
- package/knowledge/design-tokens/tailwind-v4.md +284 -0
- package/knowledge/game-ui/game-accessibility.md +317 -0
- package/knowledge/game-ui/game-ui-fundamentals.md +281 -0
- package/knowledge/game-ui/hud-design.md +324 -0
- package/knowledge/game-ui/korean-gaming-conventions.md +312 -0
- package/knowledge/game-ui/menu-systems.md +388 -0
- package/knowledge/i18n/korean-app-store-visual.md +223 -0
- package/knowledge/i18n/korean-document-style.md +301 -0
- package/knowledge/i18n/korean-payments.md +211 -0
- package/knowledge/i18n/korean-product-conventions.md +96 -0
- package/knowledge/i18n/korean-publishing.md +139 -0
- package/knowledge/i18n/korean-typography.md +123 -0
- package/knowledge/icons/curated-sets.md +225 -0
- package/knowledge/illustration/hero-illustrations.md +234 -0
- package/knowledge/illustration/illustration-systems.md +221 -0
- package/knowledge/illustration/mascot-design.md +208 -0
- package/knowledge/illustration/spot-illustrations.md +246 -0
- package/knowledge/illustration/svg-optimization.md +308 -0
- package/knowledge/layout/spacing-and-grid.md +119 -0
- package/knowledge/motion/app-loading-sequences.md +277 -0
- package/knowledge/motion/choreography-depth.md +297 -0
- package/knowledge/motion/marketing-motion.md +223 -0
- package/knowledge/motion/micro-interactions.md +266 -0
- package/knowledge/motion/motion-tools.md +281 -0
- package/knowledge/motion/principles.md +126 -0
- package/knowledge/patterns/auth-flow-design.md +316 -0
- package/knowledge/patterns/b2b-onboarding-flows.md +182 -0
- package/knowledge/patterns/brand-identity.md +238 -0
- package/knowledge/patterns/brand-references.md +97 -0
- package/knowledge/patterns/chart-color-encoding.md +269 -0
- package/knowledge/patterns/chart-types.md +344 -0
- package/knowledge/patterns/dashboard-composition.md +299 -0
- package/knowledge/patterns/design-system-qa.md +356 -0
- package/knowledge/patterns/document-typography.md +248 -0
- package/knowledge/patterns/email-design.md +338 -0
- package/knowledge/patterns/empty-states.md +263 -0
- package/knowledge/patterns/error-states.md +318 -0
- package/knowledge/patterns/form-design.md +237 -0
- package/knowledge/patterns/information-architecture.md +341 -0
- package/knowledge/patterns/landing-hero-design.md +283 -0
- package/knowledge/patterns/landing-page-patterns.md +681 -0
- package/knowledge/patterns/list-and-feed.md +371 -0
- package/knowledge/patterns/mobile-navigation.md +278 -0
- package/knowledge/patterns/money-and-amount.md +301 -0
- package/knowledge/patterns/onboarding.md +300 -0
- package/knowledge/patterns/pricing-page-design.md +261 -0
- package/knowledge/patterns/realtime-data.md +280 -0
- package/knowledge/patterns/report-design.md +330 -0
- package/knowledge/patterns/search-ux.md +373 -0
- package/knowledge/patterns/settings-page.md +325 -0
- package/knowledge/patterns/slide-deck-design.md +316 -0
- package/knowledge/patterns/styles-catalog.md +2599 -0
- package/knowledge/patterns/technical-writing.md +306 -0
- package/knowledge/patterns/ui-reasoning.md +1853 -0
- package/knowledge/patterns/ux-guidelines.md +1454 -0
- package/knowledge/platforms/react-native.md +395 -0
- package/knowledge/print/brochures-and-flyers.md +276 -0
- package/knowledge/print/korean-print-conventions.md +284 -0
- package/knowledge/print/packaging.md +321 -0
- package/knowledge/print/print-fundamentals.md +238 -0
- package/knowledge/print/signage-and-posters.md +235 -0
- package/knowledge/print/stationery.md +262 -0
- package/knowledge/spatial/ar-patterns.md +253 -0
- package/knowledge/spatial/comfort-and-accessibility.md +245 -0
- package/knowledge/spatial/spatial-design-fundamentals.md +346 -0
- package/knowledge/spatial/spatial-ui-elements.md +343 -0
- package/knowledge/spatial/vr-patterns.md +302 -0
- package/knowledge/typography/font-pairings.md +332 -0
- package/knowledge/typography/mui-type-scale.md +57 -0
- package/knowledge/typography/type-scale-fundamentals.md +105 -0
- package/knowledge/video/in-product-video.md +277 -0
- package/knowledge/video/korean-video-conventions.md +247 -0
- package/knowledge/video/marketing-video.md +258 -0
- package/knowledge/video/social-and-short-form.md +257 -0
- package/knowledge/video/video-fundamentals.md +296 -0
- package/package.json +106 -0
- package/skills/README.md +39 -0
- package/skills/color-palette/PLAYBOOK.md +175 -0
- package/skills/color-palette/SKILL.md +6 -0
- package/skills/color-palette/TEMPLATE.md +103 -0
- package/skills/component-spec-writer/PLAYBOOK.md +169 -0
- package/skills/component-spec-writer/SKILL.md +6 -0
- package/skills/component-spec-writer/TEMPLATE.md +115 -0
- package/skills/conversational-ui-designer/PLAYBOOK.md +231 -0
- package/skills/conversational-ui-designer/SKILL.md +6 -0
- package/skills/design-broadcast/PLAYBOOK.md +146 -0
- package/skills/design-broadcast/SKILL.md +6 -0
- package/skills/design-critique/PLAYBOOK.md +137 -0
- package/skills/design-critique/SKILL.md +6 -0
- package/skills/design-pr-review/PLAYBOOK.md +171 -0
- package/skills/design-pr-review/SKILL.md +6 -0
- package/skills/design-system-builder/PLAYBOOK.md +218 -0
- package/skills/design-system-builder/SKILL.md +6 -0
- package/skills/design-system-qa/PLAYBOOK.md +163 -0
- package/skills/design-system-qa/SKILL.md +6 -0
- package/skills/document-author/PLAYBOOK.md +167 -0
- package/skills/document-author/SKILL.md +6 -0
- package/skills/figma-token-sync/PLAYBOOK.md +149 -0
- package/skills/figma-token-sync/SKILL.md +6 -0
- package/skills/game-ui-designer/PLAYBOOK.md +209 -0
- package/skills/game-ui-designer/SKILL.md +6 -0
- package/skills/handoff-spec/PLAYBOOK.md +170 -0
- package/skills/handoff-spec/SKILL.md +6 -0
- package/skills/illustration-designer/PLAYBOOK.md +166 -0
- package/skills/illustration-designer/SKILL.md +6 -0
- package/skills/motion-designer/PLAYBOOK.md +223 -0
- package/skills/motion-designer/SKILL.md +6 -0
- package/skills/print-designer/PLAYBOOK.md +209 -0
- package/skills/print-designer/SKILL.md +6 -0
- package/skills/slide-deck-author/PLAYBOOK.md +198 -0
- package/skills/slide-deck-author/SKILL.md +6 -0
- package/skills/spatial-designer/PLAYBOOK.md +238 -0
- package/skills/spatial-designer/SKILL.md +6 -0
- package/skills/ux-audit/PLAYBOOK.md +142 -0
- package/skills/ux-audit/SKILL.md +6 -0
- package/skills/video-designer/PLAYBOOK.md +240 -0
- package/skills/video-designer/SKILL.md +6 -0
- package/skills/website-improvement/PLAYBOOK.md +118 -0
- package/skills/website-improvement/SKILL.md +6 -0
- package/skills/website-improvement/TEMPLATE.md +103 -0
- package/tools/audit/changelog-generate.py +176 -0
- package/tools/audit/check-coverage.py +483 -0
- package/tools/audit/doctor_assertions.py +256 -0
- package/tools/audit/example-qa.py +108 -0
- package/tools/audit/frontmatter-check.py +199 -0
- package/tools/audit/integration-check.py +95 -0
- package/tools/audit/korean-copy-check.py +161 -0
- package/tools/audit/link-check.py +146 -0
- package/tools/audit/local-ci.py +558 -0
- package/tools/audit/package-contents.py +723 -0
- package/tools/audit/package-smoke.py +22443 -0
- package/tools/audit/raw-hex-check.py +252 -0
- package/tools/audit/registry-smoke.py +8188 -0
- package/tools/audit/release-metadata.py +9832 -0
- package/tools/audit/run-all.py +351 -0
- package/tools/audit/smoke_assertions.py +12742 -0
- package/tools/audit/stability-review.py +332 -0
- package/tools/audit/stale-check.py +156 -0
- package/tools/migrations/add-version-frontmatter.py +132 -0
- package/tools/migrations/bump-last-updated.py +131 -0
- package/tools/migrations/promote-stability.py +172 -0
- package/tools/preview/README.md +58 -0
- package/tools/preview/render-tokens.py +454 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
<!-- hand-written -->
|
|
2
|
+
---
|
|
3
|
+
title: Email design (transactional + marketing)
|
|
4
|
+
applies_to: [email, transactional, marketing-email, html-email]
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
last_updated: 2026-05
|
|
7
|
+
stability: stable
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Email design
|
|
11
|
+
|
|
12
|
+
Email is a constrained design medium. HTML email rendering is **stuck in 2005** for a meaningful percentage of clients. Designs that work on web break in Outlook. This file covers what actually works.
|
|
13
|
+
|
|
14
|
+
## Two archetypes
|
|
15
|
+
|
|
16
|
+
| Type | Use | Examples |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| **Transactional** | Triggered by user action | Receipt, password reset, "order shipped", "verified" |
|
|
19
|
+
| **Marketing** | Broadcast, opt-in | Newsletter, promo, product updates, re-engagement |
|
|
20
|
+
|
|
21
|
+
Different rules for each. Transactional is **functional + minimal**; marketing is **brand-led + rich**.
|
|
22
|
+
|
|
23
|
+
## HTML email constraints (the painful reality)
|
|
24
|
+
|
|
25
|
+
Email clients render HTML wildly differently:
|
|
26
|
+
|
|
27
|
+
| Capability | Universal | Most | Some | Outlook (desktop) |
|
|
28
|
+
| --- | --- | --- | --- | --- |
|
|
29
|
+
| Tables | ✓ | ✓ | ✓ | ✓ (must use for layout!) |
|
|
30
|
+
| Inline CSS | ✓ | ✓ | ✓ | ✓ (must inline; <style> stripped) |
|
|
31
|
+
| Web fonts | — | ✓ | ✓ | partial (use fallbacks) |
|
|
32
|
+
| Flexbox / Grid | partial | ✓ | ✓ | **broken** |
|
|
33
|
+
| `:hover` | partial | ✓ | ✓ | **broken** |
|
|
34
|
+
| Dark mode | ✓ | ✓ | ✓ | partial |
|
|
35
|
+
| Animation / GIF | ✓ | ✓ | ✓ | ✓ (GIF stops at first frame in Outlook 2007) |
|
|
36
|
+
| Background images | ✓ | ✓ | ✓ | requires VML hack |
|
|
37
|
+
| `<button>` | — | — | — | **don't use** — fake with linked image or styled <a> |
|
|
38
|
+
| SVG | partial | partial | partial | **broken** — convert to PNG |
|
|
39
|
+
|
|
40
|
+
**The takeaway**: layout with `<table>` and inline CSS. Modern frameworks (`mjml`, `react-email`) generate this for you.
|
|
41
|
+
|
|
42
|
+
## Frameworks
|
|
43
|
+
|
|
44
|
+
Don't hand-write HTML email. Use a framework:
|
|
45
|
+
|
|
46
|
+
| Framework | Approach |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| **MJML** | Markup language → email HTML. Mature. |
|
|
49
|
+
| **react-email** | React components → email HTML. Modern. |
|
|
50
|
+
| **Maizzle** | Tailwind-flavored. Designer-friendly. |
|
|
51
|
+
| **Foundation for Emails** | CSS framework with email-tested components |
|
|
52
|
+
|
|
53
|
+
For new projects: `react-email` (if React stack) or `mjml` (if any). Both produce hardened HTML that works across clients.
|
|
54
|
+
|
|
55
|
+
## Layout — the table layout
|
|
56
|
+
|
|
57
|
+
```html
|
|
58
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
|
|
59
|
+
<tr>
|
|
60
|
+
<td align="center" style="padding: 24px;">
|
|
61
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="600">
|
|
62
|
+
<!-- email body, max-width 600px, centered -->
|
|
63
|
+
</td>
|
|
64
|
+
</tr>
|
|
65
|
+
</tr>
|
|
66
|
+
</table>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`role="presentation"` tells screen readers the table is for layout, not data.
|
|
70
|
+
|
|
71
|
+
### Width
|
|
72
|
+
|
|
73
|
+
| Width | Use |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| 600px | Standard email — the universal default |
|
|
76
|
+
| 480–540px | More conservative; works better on narrow mobile |
|
|
77
|
+
| 320px | Strict mobile (rare) |
|
|
78
|
+
|
|
79
|
+
Below 600px: contents may be cramped. Above 600px: gets clipped in some clients.
|
|
80
|
+
|
|
81
|
+
### Mobile
|
|
82
|
+
|
|
83
|
+
Use `@media` queries inline (yes, in `<style>` tags inside `<head>`) for responsive:
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<style>
|
|
87
|
+
@media (max-width: 480px) {
|
|
88
|
+
.container { width: 100% !important; }
|
|
89
|
+
.stack { display: block !important; width: 100% !important; }
|
|
90
|
+
}
|
|
91
|
+
</style>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`!important` is needed to override email-client defaults.
|
|
95
|
+
|
|
96
|
+
## Transactional email anatomy
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
┌──────────────────────────────────────────────┐
|
|
100
|
+
│ [Logo] │ ← header (small, brand)
|
|
101
|
+
├──────────────────────────────────────────────┤
|
|
102
|
+
│ │
|
|
103
|
+
│ Hi {{first_name}}, │ ← greeting
|
|
104
|
+
│ │
|
|
105
|
+
│ Your order #1234 has shipped. │ ← what happened
|
|
106
|
+
│ │
|
|
107
|
+
│ ┌──────────────────────────┐ │
|
|
108
|
+
│ │ Order summary │ │
|
|
109
|
+
│ │ ... │ │
|
|
110
|
+
│ └──────────────────────────┘ │
|
|
111
|
+
│ │
|
|
112
|
+
│ [Track order] │ ← primary CTA
|
|
113
|
+
│ │
|
|
114
|
+
│ If you didn't expect this email, contact │ ← contextual help
|
|
115
|
+
│ support@example.com. │
|
|
116
|
+
│ │
|
|
117
|
+
├──────────────────────────────────────────────┤
|
|
118
|
+
│ Footer: company info, legal, unsubscribe │
|
|
119
|
+
└──────────────────────────────────────────────┘
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
| Slot | Required | Notes |
|
|
123
|
+
| --- | --- | --- |
|
|
124
|
+
| Logo | yes | Top, small (40–60px high), centered or left |
|
|
125
|
+
| Greeting | yes | Personalized when possible |
|
|
126
|
+
| Body | yes | What this email is about — plain language |
|
|
127
|
+
| Primary CTA | usually | One button, brand color |
|
|
128
|
+
| Help / contact | yes (transactional) | "If you have questions..." |
|
|
129
|
+
| Footer | yes (legal) | Sender info, address, unsubscribe (marketing only) |
|
|
130
|
+
|
|
131
|
+
### Transactional rules
|
|
132
|
+
|
|
133
|
+
- **One purpose per email.** Don't combine "your order shipped" + "check out our new products."
|
|
134
|
+
- **One CTA.** "Track order" or "View receipt" — not both.
|
|
135
|
+
- **No marketing in transactional.** It's an anti-pattern AND violates GDPR / Korean e-commerce law for some categories.
|
|
136
|
+
- **Sender from + reply-to**: a real address. `noreply@` is hostile.
|
|
137
|
+
- **Subject line**: action-specific. "Your order #1234 has shipped" beats "Order update."
|
|
138
|
+
|
|
139
|
+
## Marketing email anatomy
|
|
140
|
+
|
|
141
|
+
Looser rules, more brand-led:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
┌──────────────────────────────────────────────┐
|
|
145
|
+
│ [Hero image — full width] │ ← hero
|
|
146
|
+
├──────────────────────────────────────────────┤
|
|
147
|
+
│ │
|
|
148
|
+
│ H1 Headline — what this email is about │
|
|
149
|
+
│ │
|
|
150
|
+
│ Brief copy. │
|
|
151
|
+
│ │
|
|
152
|
+
│ [CTA button] │
|
|
153
|
+
│ │
|
|
154
|
+
├──────────────────────────────────────────────┤
|
|
155
|
+
│ Section 2 (3-up) │
|
|
156
|
+
│ ┌────┐ ┌────┐ ┌────┐ │
|
|
157
|
+
│ │ A │ │ B │ │ C │ │
|
|
158
|
+
│ └────┘ └────┘ └────┘ │
|
|
159
|
+
├──────────────────────────────────────────────┤
|
|
160
|
+
│ Footer: brand, legal, unsubscribe │
|
|
161
|
+
└──────────────────────────────────────────────┘
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Marketing rules
|
|
165
|
+
|
|
166
|
+
- **Hero matters most.** Above the fold = the only thing 60% of recipients see.
|
|
167
|
+
- **One primary message.** Multiple "secondary" calls dilute.
|
|
168
|
+
- **Visual hierarchy**: image > headline > body > CTA.
|
|
169
|
+
- **Mobile first**: 60%+ of email opens on mobile. Single column stacks.
|
|
170
|
+
- **Personalization** if data permits: `{{first_name}}`, recently-viewed items, location.
|
|
171
|
+
- **Unsubscribe link prominent** in footer. Hidden / tiny is illegal in many jurisdictions.
|
|
172
|
+
|
|
173
|
+
## Subject line
|
|
174
|
+
|
|
175
|
+
Most-skipped, most-important detail.
|
|
176
|
+
|
|
177
|
+
| Rule | Why |
|
|
178
|
+
| --- | --- |
|
|
179
|
+
| Under 50 characters | Mobile preview cuts off. Front-loaded. |
|
|
180
|
+
| Lowercase / sentence case | Title Case Reads Like Marketing — Skipped |
|
|
181
|
+
| No clickbait | "Your account is at risk" → unsubscribe |
|
|
182
|
+
| Specific over generic | "Order #1234 shipped" > "Order update" |
|
|
183
|
+
| Emoji optional | Sparingly. ❤️🎉 work; 🤖 spam-flag in some clients. |
|
|
184
|
+
| Korean: 1-2 phrases, similar rules | "5월 정기 결제 완료" |
|
|
185
|
+
|
|
186
|
+
## Preheader text
|
|
187
|
+
|
|
188
|
+
The "preview text" shown after subject in inbox lists. Many emails leave this as the email's first body line — wasteful.
|
|
189
|
+
|
|
190
|
+
Set it explicitly:
|
|
191
|
+
|
|
192
|
+
```html
|
|
193
|
+
<div style="display: none; max-height: 0; overflow: hidden;">
|
|
194
|
+
Your tracking number is FX12345678 — see when it arrives.
|
|
195
|
+
</div>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
This shows in inbox preview, hidden in email body.
|
|
199
|
+
|
|
200
|
+
40–100 character target.
|
|
201
|
+
|
|
202
|
+
## Color and typography
|
|
203
|
+
|
|
204
|
+
### Color
|
|
205
|
+
|
|
206
|
+
| Use | Convention |
|
|
207
|
+
| --- | --- |
|
|
208
|
+
| Background | White or very light (`#FAFAFA`) |
|
|
209
|
+
| Body text | `#1F2937` or similar (off-black) |
|
|
210
|
+
| Brand accent | One color, consistent across all email |
|
|
211
|
+
| Buttons | Brand primary fill, white text |
|
|
212
|
+
| Links | Brand accent, underlined |
|
|
213
|
+
|
|
214
|
+
For dark mode: most clients respect `prefers-color-scheme` if you provide a dark variant. Test in Apple Mail, Outlook, Gmail.
|
|
215
|
+
|
|
216
|
+
### Typography
|
|
217
|
+
|
|
218
|
+
Email-safe fonts:
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Web fonts work in modern clients (Apple Mail, Gmail) but fail in Outlook desktop. Pair with a system fallback.
|
|
225
|
+
|
|
226
|
+
For Korean:
|
|
227
|
+
```
|
|
228
|
+
font-family: "Pretendard", -apple-system, "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Pretendard ships fonts via CDN; works in Apple Mail / Gmail.
|
|
232
|
+
|
|
233
|
+
### Type sizes
|
|
234
|
+
|
|
235
|
+
| Element | Size |
|
|
236
|
+
| --- | --- |
|
|
237
|
+
| Body | 16px (web) — important for mobile readability |
|
|
238
|
+
| Heading | 24–32px |
|
|
239
|
+
| Button | 16px (text inside button) |
|
|
240
|
+
| Footer / legal | 12–14px |
|
|
241
|
+
|
|
242
|
+
Don't go below 14px body — too small on mobile.
|
|
243
|
+
|
|
244
|
+
## Buttons (the "bulletproof button" pattern)
|
|
245
|
+
|
|
246
|
+
Outlook strips `<button>` styles. The "bulletproof button" uses a styled `<a>` inside a styled table cell:
|
|
247
|
+
|
|
248
|
+
```html
|
|
249
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0">
|
|
250
|
+
<tr>
|
|
251
|
+
<td bgcolor="#7C3AED" style="border-radius: 8px;">
|
|
252
|
+
<a href="https://example.com/track"
|
|
253
|
+
style="display: inline-block; padding: 14px 32px;
|
|
254
|
+
color: #FFFFFF; text-decoration: none;
|
|
255
|
+
font-family: sans-serif; font-size: 16px; font-weight: 600;
|
|
256
|
+
border-radius: 8px;">
|
|
257
|
+
Track order
|
|
258
|
+
</a>
|
|
259
|
+
</td>
|
|
260
|
+
</tr>
|
|
261
|
+
</table>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
This works in every email client. Use a framework — they generate this automatically.
|
|
265
|
+
|
|
266
|
+
## Korean email conventions
|
|
267
|
+
|
|
268
|
+
Per [`knowledge/i18n/korean-product-conventions.md`](../i18n/korean-product-conventions.md):
|
|
269
|
+
|
|
270
|
+
- Subject lines in Korean for KR audience.
|
|
271
|
+
- Polite form (~합니다) for transactional.
|
|
272
|
+
- Casual (~해요) for friendly product newsletters.
|
|
273
|
+
- 한국어 사이트의 unsubscribe 링크: "수신거부", per Korean spam law (정보통신망법).
|
|
274
|
+
- Sender domain: typically a separate subdomain (`mail.example.com`) for SPF / DKIM clean separation.
|
|
275
|
+
|
|
276
|
+
Korean spam regulations:
|
|
277
|
+
- Marketing emails MUST include `[광고]` prefix in subject (e-commerce / promotional).
|
|
278
|
+
- Sender's company info + address + business registration number in footer.
|
|
279
|
+
- Unsubscribe link must be functional with no login required.
|
|
280
|
+
|
|
281
|
+
Skipping these = legal risk.
|
|
282
|
+
|
|
283
|
+
## Testing
|
|
284
|
+
|
|
285
|
+
Email rendering varies by client. Test in:
|
|
286
|
+
- Gmail (web + iOS app + Android app)
|
|
287
|
+
- Apple Mail (Mac + iOS)
|
|
288
|
+
- Outlook (desktop, mobile, web)
|
|
289
|
+
- Yahoo Mail
|
|
290
|
+
- For KR market: Naver Mail, Daum Hanmail
|
|
291
|
+
|
|
292
|
+
Tools:
|
|
293
|
+
- **Litmus** (paid, comprehensive client previews)
|
|
294
|
+
- **Email on Acid** (paid, similar)
|
|
295
|
+
- **MJML's online preview** (free, basic)
|
|
296
|
+
|
|
297
|
+
Test darkmode + light mode + mobile + desktop.
|
|
298
|
+
|
|
299
|
+
## Accessibility
|
|
300
|
+
|
|
301
|
+
- `role="presentation"` on layout tables (screen readers skip).
|
|
302
|
+
- `<img alt="">` on every image — even decorative ones (so screen readers don't read filenames).
|
|
303
|
+
- High contrast for text (≥ 4.5:1).
|
|
304
|
+
- Don't put critical info only in images — assume images blocked (Outlook default).
|
|
305
|
+
- Plain-text version: provide alongside HTML for plain-text-only readers.
|
|
306
|
+
- Unsubscribe link ≥ 14px with ≥ 4.5:1 contrast — don't bury legally-required text.
|
|
307
|
+
|
|
308
|
+
## Tracking
|
|
309
|
+
|
|
310
|
+
Most marketing emails embed tracking pixels (1×1 image fetched on open) and link wrapping (rewrites URLs to track clicks).
|
|
311
|
+
|
|
312
|
+
Privacy considerations:
|
|
313
|
+
- iOS 15+ Mail loads images automatically (defeats open tracking).
|
|
314
|
+
- Disclose tracking in privacy policy.
|
|
315
|
+
- Korean PIPA: image-load tracking is "personal information processing"; needs consent or legitimate-interest basis.
|
|
316
|
+
|
|
317
|
+
For transactional: don't track. It's not the user's intent.
|
|
318
|
+
|
|
319
|
+
## Don't
|
|
320
|
+
|
|
321
|
+
- Don't write HTML email by hand — use a framework.
|
|
322
|
+
- Don't use `<button>` in email — use bulletproof button pattern.
|
|
323
|
+
- Don't use SVG — convert to PNG.
|
|
324
|
+
- Don't put critical info only in images — show as text too.
|
|
325
|
+
- Don't forget the preheader text.
|
|
326
|
+
- Don't make the unsubscribe hard to find.
|
|
327
|
+
- Don't include `[광고]` in subject if it's actually transactional (legal misclassification).
|
|
328
|
+
- Don't mix transactional + marketing in one email.
|
|
329
|
+
- Don't ship without testing in Outlook (broken layouts are common there).
|
|
330
|
+
|
|
331
|
+
## Cross-reference
|
|
332
|
+
|
|
333
|
+
- [`knowledge/patterns/document-typography.md`](document-typography.md) — long-form reading rules
|
|
334
|
+
- [`knowledge/patterns/technical-writing.md`](technical-writing.md) — voice for transactional copy
|
|
335
|
+
- [`knowledge/i18n/korean-product-conventions.md`](../i18n/korean-product-conventions.md) — Korean spam law
|
|
336
|
+
- [`knowledge/i18n/korean-publishing.md`](../i18n/korean-publishing.md) — Korean compliance
|
|
337
|
+
- [react-email docs](https://react.email/)
|
|
338
|
+
- [MJML docs](https://mjml.io/)
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
<!-- hand-written -->
|
|
2
|
+
---
|
|
3
|
+
title: Empty states
|
|
4
|
+
applies_to: [web, mobile, all-ui]
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
last_updated: 2026-05
|
|
7
|
+
stability: stable
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Empty states
|
|
11
|
+
|
|
12
|
+
An empty state is what users see when there's no data — first visit, all items deleted, no search results. It's a high-leverage screen: get it right and you guide the user forward; get it wrong and they bounce.
|
|
13
|
+
|
|
14
|
+
## The four types of empty
|
|
15
|
+
|
|
16
|
+
Different causes need different responses. Don't show one generic empty state for all four.
|
|
17
|
+
|
|
18
|
+
| Type | When | Tone | Primary CTA |
|
|
19
|
+
| --- | --- | --- | --- |
|
|
20
|
+
| **First-time / never had data** | New user, never created anything | Welcoming, instructional | "Add first <thing>" or "Get started" |
|
|
21
|
+
| **Cleared / all deleted** | User removed everything intentionally | Neutral, optionally celebratory | Restore option, or "Add new" |
|
|
22
|
+
| **Filtered to nothing** | User's search/filter excluded all data | Helpful | "Clear filters" + "Adjust criteria" |
|
|
23
|
+
| **No data after action** | User completed something, list now empty | Confirmation | "Add another" or navigate elsewhere |
|
|
24
|
+
|
|
25
|
+
The most-skipped distinction is **first-time** vs **filtered**. They look the same (empty list) but the response differs:
|
|
26
|
+
- First-time: "Welcome! Let's add your first project."
|
|
27
|
+
- Filtered: "No projects match 'archived'. Clear filters?"
|
|
28
|
+
|
|
29
|
+
## Anatomy
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
┌──────────────────────────────────────────────────┐
|
|
33
|
+
│ │
|
|
34
|
+
│ [illustration / icon] │
|
|
35
|
+
│ │
|
|
36
|
+
│ Title — what's empty │
|
|
37
|
+
│ │
|
|
38
|
+
│ Description — why and what to do │
|
|
39
|
+
│ │
|
|
40
|
+
│ [Primary CTA] │
|
|
41
|
+
│ │
|
|
42
|
+
│ (optional: secondary action or link) │
|
|
43
|
+
│ │
|
|
44
|
+
└──────────────────────────────────────────────────┘
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
| Slot | Required | Notes |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| Illustration / icon | recommended | Soft, friendly. Not a stock empty box. |
|
|
50
|
+
| Title | yes | What's empty (in user terms, ≤ 60 chars) |
|
|
51
|
+
| Description | yes | Why + what to do (1 sentence) |
|
|
52
|
+
| Primary CTA | usually | The action that fills the void |
|
|
53
|
+
| Secondary action | optional | "Learn more", "Watch tutorial", "Import data" |
|
|
54
|
+
|
|
55
|
+
## Copy guidelines
|
|
56
|
+
|
|
57
|
+
### Tone
|
|
58
|
+
|
|
59
|
+
| Context | Tone |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| Consumer mobile / casual | Friendly, slight enthusiasm |
|
|
62
|
+
| B2B / enterprise | Direct, helpful, no exclamation marks |
|
|
63
|
+
| Korean apps | Polite (존댓말), avoid casual slang |
|
|
64
|
+
| Fintech | Reassuring, professional |
|
|
65
|
+
|
|
66
|
+
### Title formulas
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
✓ "아직 거래 내역이 없어요" [casual KR — friendly product]
|
|
70
|
+
✓ "거래 내역이 없습니다" [polite KR — fintech/B2B]
|
|
71
|
+
✓ "No transactions yet" [casual EN]
|
|
72
|
+
✓ "No transactions found" [neutral EN]
|
|
73
|
+
|
|
74
|
+
✗ "Empty" [hostile, no context]
|
|
75
|
+
✗ "Oops!" [twee, content-free]
|
|
76
|
+
✗ "404" [technical jargon for empty]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Description formulas
|
|
80
|
+
|
|
81
|
+
For first-time:
|
|
82
|
+
- "<Action> to start." — "Add your first project to get started."
|
|
83
|
+
- "<Outcome> when you <action>." — "Your transactions will appear here when you connect a bank account."
|
|
84
|
+
|
|
85
|
+
For filtered:
|
|
86
|
+
- "Try <alternative>" — "Try a different search term or clear filters."
|
|
87
|
+
|
|
88
|
+
For after-action:
|
|
89
|
+
- "<Confirmation>. <Next step>?" — "All caught up. Want to schedule the next sync?"
|
|
90
|
+
|
|
91
|
+
### Korean copy patterns
|
|
92
|
+
|
|
93
|
+
Per [`knowledge/i18n/korean-product-conventions.md`](../i18n/korean-product-conventions.md):
|
|
94
|
+
|
|
95
|
+
| Type | Title | Description | CTA |
|
|
96
|
+
| --- | --- | --- | --- |
|
|
97
|
+
| First-time | "아직 등록된 항목이 없어요" | "첫 항목을 추가해 보세요." | "추가하기" |
|
|
98
|
+
| Filtered | "검색 결과가 없습니다" | "다른 검색어를 시도해 보세요." | "필터 초기화" |
|
|
99
|
+
| After-action | "모두 처리되었어요" | — | "새로 추가하기" |
|
|
100
|
+
| Network / can't load | "불러올 수 없어요" | "잠시 후 다시 시도해 주세요." | "다시 시도" (note: this is error, not empty — see error-states.md) |
|
|
101
|
+
|
|
102
|
+
## Illustration vs icon
|
|
103
|
+
|
|
104
|
+
| Use | When |
|
|
105
|
+
| --- | --- |
|
|
106
|
+
| Custom illustration | Brand-leading product, marketing-adjacent screens, flagship features |
|
|
107
|
+
| Stock icon (single, large) | Functional product, dense UIs, internal tools |
|
|
108
|
+
| Skeleton-like neutral shapes | Lightweight; avoids "decorative" feel |
|
|
109
|
+
| Nothing | Dense list views (just title + CTA centered) |
|
|
110
|
+
|
|
111
|
+
Custom illustrations should be:
|
|
112
|
+
- Single-line, single-color (matches brand)
|
|
113
|
+
- Soft / approachable (no harsh angles for empty states)
|
|
114
|
+
- ~80–120px in the empty area
|
|
115
|
+
- Same illustration style across the product (consistency)
|
|
116
|
+
|
|
117
|
+
Don't:
|
|
118
|
+
- Don't use sad / disappointed faces. Empty isn't a failure.
|
|
119
|
+
- Don't use generic stock illustrations from a vendor (Drag-along figures, paper-plane stuff). They date fast.
|
|
120
|
+
- Don't make the illustration so large it pushes the CTA below the fold.
|
|
121
|
+
|
|
122
|
+
## Layout
|
|
123
|
+
|
|
124
|
+
### Centered (most common)
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
[empty space above]
|
|
128
|
+
[illustration centered]
|
|
129
|
+
[title centered]
|
|
130
|
+
[description centered, max-width ~480px]
|
|
131
|
+
[CTA centered]
|
|
132
|
+
[empty space below]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Vertical centering in the parent container. Allow ~30% of viewport height above for visual breathing room.
|
|
136
|
+
|
|
137
|
+
### Inline / compact (small areas)
|
|
138
|
+
|
|
139
|
+
For empty states inside a card, sidebar, or small panel:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
[icon + small title in one row]
|
|
143
|
+
[description below]
|
|
144
|
+
[link CTA]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Don't show an 80px illustration in a 200px-wide sidebar.
|
|
148
|
+
|
|
149
|
+
### Full-screen
|
|
150
|
+
|
|
151
|
+
For first-time onboarding contexts where the whole screen is "empty":
|
|
152
|
+
- Move CTA to the bottom (sticky on mobile).
|
|
153
|
+
- Add secondary actions (Skip, Learn more).
|
|
154
|
+
- Consider a Stepper if there's a multi-step path.
|
|
155
|
+
|
|
156
|
+
See [`knowledge/patterns/onboarding.md`](onboarding.md) for first-run patterns.
|
|
157
|
+
|
|
158
|
+
## States
|
|
159
|
+
|
|
160
|
+
| State | Shows when |
|
|
161
|
+
| --- | --- |
|
|
162
|
+
| Empty (first-time) | `data.length === 0 && !hasEverHadData` |
|
|
163
|
+
| Empty (filtered) | `data.length === 0 && filters.active` |
|
|
164
|
+
| Empty (cleared) | `data.length === 0 && hasEverHadData && !filters.active` |
|
|
165
|
+
| Loading | `isLoading && data.length === 0` — skeleton, not empty state |
|
|
166
|
+
| Error | `error` — separate file, see [`error-states.md`](error-states.md) |
|
|
167
|
+
|
|
168
|
+
**Don't conflate empty with loading.** During load, show skeleton. After load with no data, show the right empty type.
|
|
169
|
+
|
|
170
|
+
## CTA targeting
|
|
171
|
+
|
|
172
|
+
The CTA in an empty state should be the **single most likely next action** for that user in that context.
|
|
173
|
+
|
|
174
|
+
For first-time empty:
|
|
175
|
+
- "Add your first transaction" (primary action — populates the list)
|
|
176
|
+
- secondary: "Connect a bank account" (alternative path)
|
|
177
|
+
|
|
178
|
+
For filtered empty:
|
|
179
|
+
- "Clear filters" (primary — most likely intent)
|
|
180
|
+
- secondary: "Adjust search" (focuses the search input)
|
|
181
|
+
|
|
182
|
+
For after-action:
|
|
183
|
+
- "Add another" (continues the flow)
|
|
184
|
+
- secondary: "Done" or "Back to dashboard"
|
|
185
|
+
|
|
186
|
+
Avoid:
|
|
187
|
+
- Multiple primary CTAs (decision paralysis)
|
|
188
|
+
- Generic "Refresh" as the only CTA on first-time (doesn't load any new data)
|
|
189
|
+
- "Contact support" as primary on common empties
|
|
190
|
+
|
|
191
|
+
## Tokens consumed
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
--color-text-primary (title)
|
|
195
|
+
--color-text-secondary (description)
|
|
196
|
+
--color-bg-default
|
|
197
|
+
--color-primary-default (CTA)
|
|
198
|
+
--space-xl, --space-2xl (vertical breathing)
|
|
199
|
+
--font-size-xl (title)
|
|
200
|
+
--font-size-base (description)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Accessibility
|
|
204
|
+
|
|
205
|
+
- Title is a heading (`<h2>` or appropriate level for the page hierarchy).
|
|
206
|
+
- Empty state container: `role="status"` if dynamic (e.g., loaded async), so screen readers announce it on render.
|
|
207
|
+
- Illustrations: `aria-hidden="true"` (decorative) — title carries the meaning.
|
|
208
|
+
- CTA: standard button accessibility.
|
|
209
|
+
|
|
210
|
+
## Code example
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
function TransactionList() {
|
|
214
|
+
const { data, isLoading, error, filters } = useTransactions();
|
|
215
|
+
|
|
216
|
+
if (isLoading && data.length === 0) return <SkeletonList />;
|
|
217
|
+
if (error) return <ErrorState error={error} />;
|
|
218
|
+
if (data.length === 0) {
|
|
219
|
+
return (
|
|
220
|
+
<EmptyState
|
|
221
|
+
type={filters.active ? "filtered" : "first-time"}
|
|
222
|
+
title={filters.active ? "검색 결과가 없습니다" : "아직 거래 내역이 없어요"}
|
|
223
|
+
description={
|
|
224
|
+
filters.active
|
|
225
|
+
? "다른 검색어를 시도해 보세요."
|
|
226
|
+
: "첫 거래를 추가해 보세요."
|
|
227
|
+
}
|
|
228
|
+
action={
|
|
229
|
+
filters.active
|
|
230
|
+
? { label: "필터 초기화", onClick: clearFilters }
|
|
231
|
+
: { label: "거래 추가", onClick: openAddTransaction }
|
|
232
|
+
}
|
|
233
|
+
/>
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return <List items={data} />;
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Edge cases
|
|
242
|
+
|
|
243
|
+
- **Empty after destructive action** (user just deleted last item): show a transient toast first ("3 items deleted"), then settle into the cleared empty state. Don't jump from "list" to "first-time empty" silently.
|
|
244
|
+
- **Empty during sync** (data is being fetched but takes time): show skeleton, not empty. Empty implies "we know there's nothing"; don't lie.
|
|
245
|
+
- **Permission-blocked empty** (user doesn't have access): different from regular empty — explain what would be there + how to request access. See [`error-states.md`](error-states.md) for permission errors.
|
|
246
|
+
- **Mobile**: less padding, less large illustration. Center on the visible area, not the full document.
|
|
247
|
+
- **Inside a paginated list**: empty state is page 1's empty. Don't show on page 5 of a paginated list — that's just "no more results", handle differently.
|
|
248
|
+
|
|
249
|
+
## Don't
|
|
250
|
+
|
|
251
|
+
- Don't ship a generic "No data" alone. Always include description + CTA.
|
|
252
|
+
- Don't use empty states for error states. Different message, different action.
|
|
253
|
+
- Don't use empty states with no CTA. Even "Refresh" is something. Stuck-in-empty is hostile.
|
|
254
|
+
- Don't use the same illustration for first-time and filtered — the meaning differs.
|
|
255
|
+
- Don't use marketing copy in empty states ("Welcome to the future of finance!"). Functional + warm.
|
|
256
|
+
- Don't auto-show onboarding modal on top of empty state. Pick one — overlay or inline.
|
|
257
|
+
|
|
258
|
+
## Cross-reference
|
|
259
|
+
|
|
260
|
+
- [`knowledge/patterns/error-states.md`](error-states.md) — when there's an error, not just empty
|
|
261
|
+
- [`knowledge/patterns/onboarding.md`](onboarding.md) — full first-run onboarding flow
|
|
262
|
+
- [`knowledge/patterns/list-and-feed.md`](list-and-feed.md) — list-level empty rendering
|
|
263
|
+
- [`knowledge/i18n/korean-product-conventions.md`](../i18n/korean-product-conventions.md) — Korean tone
|