@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,309 @@
|
|
|
1
|
+
# `Tag` + `Badge` — combined spec
|
|
2
|
+
|
|
3
|
+
> Two sibling status indicators. Same family, distinct purposes — speccing together avoids duplicate decisions.
|
|
4
|
+
>
|
|
5
|
+
> Citing Ant Design `Tag` + `Badge`, MUI `Chip` + `Badge`, shadcn-ui `badge`
|
|
6
|
+
|
|
7
|
+
## Semantic difference
|
|
8
|
+
|
|
9
|
+
| Component | Use | Interactive? |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| **Tag** | Inline label or pill — categorize content, attribute, filter | Often (closable, clickable) |
|
|
12
|
+
| **Badge** | Small dot or count overlaid on another element (icon, avatar) | No (decorative status indicator) |
|
|
13
|
+
|
|
14
|
+
Picking the wrong one is common. A "3 new messages" indicator on a notification icon = **Badge**. A "Premium" label inline with a username = **Tag**.
|
|
15
|
+
|
|
16
|
+
## Tag
|
|
17
|
+
|
|
18
|
+
### Anatomy
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Static: ┌──────────┐
|
|
22
|
+
│ Premium │
|
|
23
|
+
└──────────┘
|
|
24
|
+
|
|
25
|
+
With icon: ┌──────────────┐
|
|
26
|
+
│ ★ Featured │
|
|
27
|
+
└──────────────┘
|
|
28
|
+
|
|
29
|
+
Closable: ┌──────────────┐
|
|
30
|
+
│ tag1 ✕ │
|
|
31
|
+
└──────────────┘
|
|
32
|
+
|
|
33
|
+
Color tag: ●━━━━━━━━━━● Critical [colored dot + text]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### API
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<Tag>Premium</Tag>
|
|
40
|
+
<Tag color="success">Completed</Tag>
|
|
41
|
+
<Tag closable onClose={() => removeTag(id)}>{tagText}</Tag>
|
|
42
|
+
<Tag iconStart={<StarIcon />} variant="solid">Featured</Tag>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| Prop | Type | Default | Description |
|
|
46
|
+
| --- | --- | --- | --- |
|
|
47
|
+
| `children` | `ReactNode` | — | Tag label |
|
|
48
|
+
| `variant` | `"subtle" \| "outlined" \| "solid"` | `"subtle"` | Visual emphasis |
|
|
49
|
+
| `color` | `"default" \| "primary" \| "success" \| "warning" \| "error" \| "info"` or hex | `"default"` | Semantic color |
|
|
50
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | |
|
|
51
|
+
| `closable` | `boolean` | `false` | Show ✕ |
|
|
52
|
+
| `onClose` | `(e) => void` | — | |
|
|
53
|
+
| `onClick` | `(e) => void` | — | If set, makes tag clickable (cursor + hover) |
|
|
54
|
+
| `iconStart` / `iconEnd` | `ReactNode` | — | |
|
|
55
|
+
| `disabled` | `boolean` | `false` | |
|
|
56
|
+
|
|
57
|
+
### Sizes
|
|
58
|
+
|
|
59
|
+
| Size | Height | Font | Padding-x |
|
|
60
|
+
| --- | --- | --- | --- |
|
|
61
|
+
| `sm` | 20px | 11px | 6px |
|
|
62
|
+
| `md` (default) | 24px | 12px | 8px |
|
|
63
|
+
| `lg` | 28px | 13px | 10px |
|
|
64
|
+
|
|
65
|
+
### Variants
|
|
66
|
+
|
|
67
|
+
| Variant | Subtle | Outlined | Solid |
|
|
68
|
+
| --- | --- | --- | --- |
|
|
69
|
+
| Background | `--color-<color>-subtle-bg` | transparent | `--color-<color>` |
|
|
70
|
+
| Border | none | `1px --color-<color>` | none |
|
|
71
|
+
| Text | `--color-text-primary` (or color-specific) | `--color-<color>` | `--color-on-<color>` |
|
|
72
|
+
|
|
73
|
+
`subtle` is the default — least visually noisy. Use `outlined` for important categorization. Use `solid` for "Premium" / "Featured" / status that needs to dominate.
|
|
74
|
+
|
|
75
|
+
### When to use Tag
|
|
76
|
+
|
|
77
|
+
- Category labels: "디자인", "엔지니어링", "마케팅"
|
|
78
|
+
- Status: "Active", "Archived", "Pending"
|
|
79
|
+
- Filter chips (in a filter bar): "Color: Red ✕", "Size: M ✕"
|
|
80
|
+
- Premium / status indicators: "Pro", "Enterprise"
|
|
81
|
+
- Multi-select selected values inside a Combobox
|
|
82
|
+
|
|
83
|
+
### When NOT to use Tag
|
|
84
|
+
|
|
85
|
+
- For interactive primary actions — that's a Button.
|
|
86
|
+
- For navigation — that's a Link or Breadcrumb item.
|
|
87
|
+
- For a container — that's a Card or Box.
|
|
88
|
+
|
|
89
|
+
## Badge
|
|
90
|
+
|
|
91
|
+
### Anatomy
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
Dot indicator: Count badge: Standalone:
|
|
95
|
+
|
|
96
|
+
📨 ● 📨 (3) [New]
|
|
97
|
+
max 99+: 📨 (99+)
|
|
98
|
+
|
|
99
|
+
Status dot on avatar: New indicator on tab:
|
|
100
|
+
● 김민지 설정 ●
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### API
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
<Badge variant="dot" color="success" /> {/* dot only */}
|
|
107
|
+
<Badge count={3}>{<NotificationIcon />}</Badge> {/* count overlay */}
|
|
108
|
+
<Badge count={142} max={99} showZero={false} /> {/* shows "99+" */}
|
|
109
|
+
<Badge content="NEW" color="primary" /> {/* text content */}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
| Prop | Type | Default | Description |
|
|
113
|
+
| --- | --- | --- | --- |
|
|
114
|
+
| `count` | `number` | — | Numeric value to show |
|
|
115
|
+
| `max` | `number` | `99` | Above this, show "max+" (e.g., "99+") |
|
|
116
|
+
| `showZero` | `boolean` | `false` | Render even when count is 0 |
|
|
117
|
+
| `content` | `ReactNode` | — | Text/element instead of count (e.g., "NEW") |
|
|
118
|
+
| `variant` | `"dot" \| "count"` | inferred | Dot if no count/content; otherwise count |
|
|
119
|
+
| `color` | `"primary" \| "success" \| "warning" \| "error" \| "info"` | `"error"` | |
|
|
120
|
+
| `size` | `"sm" \| "md"` | `"md"` | |
|
|
121
|
+
| `placement` | `"top-right" \| "top-left" \| "bottom-right" \| "bottom-left"` | `"top-right"` | When wrapping a child |
|
|
122
|
+
| `offset` | `[number, number]` | `[0, 0]` | Fine-tune placement |
|
|
123
|
+
| `children` | `ReactElement` | — | The element being badged |
|
|
124
|
+
|
|
125
|
+
### Sizes
|
|
126
|
+
|
|
127
|
+
| Size | Dot | Count badge height |
|
|
128
|
+
| --- | --- | --- |
|
|
129
|
+
| `sm` | 6px | 16px |
|
|
130
|
+
| `md` (default) | 8px | 18px |
|
|
131
|
+
|
|
132
|
+
The count badge wraps tightly around 1–2 digits. For 3-digit + show "99+".
|
|
133
|
+
|
|
134
|
+
### Placement
|
|
135
|
+
|
|
136
|
+
When `<Badge>` wraps a child element, it positions absolutely relative to the child:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
┌──────────┐
|
|
140
|
+
│ 📨 ● │ ← top-right (default)
|
|
141
|
+
└──────────┘
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Use `offset` to fine-tune (badges often need -4px / -4px to overlap nicely).
|
|
145
|
+
|
|
146
|
+
### When to use Badge
|
|
147
|
+
|
|
148
|
+
- Notification count on icons (mail, bell)
|
|
149
|
+
- Online status dot on avatars
|
|
150
|
+
- "New" indicator on tabs / menu items
|
|
151
|
+
- Cart count
|
|
152
|
+
- Unread count on chat list items
|
|
153
|
+
|
|
154
|
+
### When NOT to use Badge
|
|
155
|
+
|
|
156
|
+
- Inline text labels — use Tag
|
|
157
|
+
- Standalone status — use Tag
|
|
158
|
+
- Long text (4+ chars) — use Tag
|
|
159
|
+
|
|
160
|
+
## States
|
|
161
|
+
|
|
162
|
+
### Tag states
|
|
163
|
+
|
|
164
|
+
| State | Visual |
|
|
165
|
+
| --- | --- |
|
|
166
|
+
| Default | Resting |
|
|
167
|
+
| Hover (clickable) | Slight bg darken |
|
|
168
|
+
| Focus-visible (clickable) | 2px ring |
|
|
169
|
+
| Closing | Optional fade-out 100ms |
|
|
170
|
+
| Disabled | 50% opacity |
|
|
171
|
+
|
|
172
|
+
### Badge states
|
|
173
|
+
|
|
174
|
+
| State | Visual |
|
|
175
|
+
| --- | --- |
|
|
176
|
+
| Default | Always visible (with count > 0 or dot) |
|
|
177
|
+
| Animating in | 150ms scale 0.7 → 1 + opacity |
|
|
178
|
+
| Hidden | When count = 0 and `!showZero`, badge unmounts |
|
|
179
|
+
|
|
180
|
+
## Tokens consumed
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
--color-bg-default
|
|
184
|
+
--color-bg-subtle
|
|
185
|
+
--color-text-primary
|
|
186
|
+
--color-text-secondary
|
|
187
|
+
--color-on-primary, --color-on-success, etc.
|
|
188
|
+
--color-primary-default, --color-primary-subtle-bg
|
|
189
|
+
--color-success, --color-success-subtle-bg
|
|
190
|
+
--color-warning, --color-warning-subtle-bg
|
|
191
|
+
--color-error, --color-error-subtle-bg
|
|
192
|
+
--color-info, --color-info-subtle-bg
|
|
193
|
+
--color-border-default
|
|
194
|
+
--color-focus-ring
|
|
195
|
+
--space-xs, --space-sm
|
|
196
|
+
--radius-md (Tag)
|
|
197
|
+
--radius-full (Badge dot, Badge count)
|
|
198
|
+
--font-size-xs, --font-size-sm
|
|
199
|
+
--font-weight-medium
|
|
200
|
+
--motion-fast
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Accessibility
|
|
204
|
+
|
|
205
|
+
### Tag
|
|
206
|
+
|
|
207
|
+
- If purely decorative (e.g., category label): regular `<span>`, no special role.
|
|
208
|
+
- If clickable: `<button>` semantics.
|
|
209
|
+
- If closable: the close button has its own `aria-label="<tag content> 제거"`.
|
|
210
|
+
- Color is not the only signal — pair with text or icon. (e.g., "Critical" tag should have icon AND red color.)
|
|
211
|
+
|
|
212
|
+
### Badge
|
|
213
|
+
|
|
214
|
+
- For count badges: include screen-reader text. The visual count can be `aria-hidden`; the actual announcement should be richer.
|
|
215
|
+
|
|
216
|
+
```html
|
|
217
|
+
<button aria-label="알림, 새 알림 3개">
|
|
218
|
+
<BellIcon aria-hidden="true" />
|
|
219
|
+
<span class="badge" aria-hidden="true">3</span>
|
|
220
|
+
</button>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
- For dot indicators: `aria-label` on the parent describes the status.
|
|
224
|
+
- Don't put critical info only in a badge — visually small, easily missed.
|
|
225
|
+
|
|
226
|
+
## Code examples
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
// Multi-select tags inside a Combobox
|
|
230
|
+
<div className="tags-input">
|
|
231
|
+
{selectedTags.map(tag => (
|
|
232
|
+
<Tag key={tag} closable onClose={() => removeTag(tag)}>{tag}</Tag>
|
|
233
|
+
))}
|
|
234
|
+
<input ... />
|
|
235
|
+
</div>
|
|
236
|
+
|
|
237
|
+
// Filter bar
|
|
238
|
+
<div className="filter-bar">
|
|
239
|
+
Active filters:
|
|
240
|
+
{activeFilters.map(f => (
|
|
241
|
+
<Tag key={f.key} variant="outlined" closable onClose={() => clearFilter(f.key)}>
|
|
242
|
+
{f.label}: {f.value}
|
|
243
|
+
</Tag>
|
|
244
|
+
))}
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
// Status tag in a list
|
|
248
|
+
<TableCell>
|
|
249
|
+
{row.status === "active" && <Tag color="success">활성</Tag>}
|
|
250
|
+
{row.status === "pending" && <Tag color="warning">대기 중</Tag>}
|
|
251
|
+
{row.status === "archived" && <Tag color="default">보관됨</Tag>}
|
|
252
|
+
</TableCell>
|
|
253
|
+
|
|
254
|
+
// Notification count on bell icon
|
|
255
|
+
<Badge count={notificationCount} max={99}>
|
|
256
|
+
<button aria-label={`알림 ${notificationCount}개`}>
|
|
257
|
+
<BellIcon />
|
|
258
|
+
</button>
|
|
259
|
+
</Badge>
|
|
260
|
+
|
|
261
|
+
// Online dot on avatar
|
|
262
|
+
<Badge variant="dot" color="success" placement="bottom-right">
|
|
263
|
+
<Avatar src={user.photoUrl} alt={user.name} />
|
|
264
|
+
</Badge>
|
|
265
|
+
|
|
266
|
+
// "NEW" indicator on a menu item
|
|
267
|
+
<MenuItem>
|
|
268
|
+
새 기능
|
|
269
|
+
<Badge content="NEW" color="primary" size="sm" />
|
|
270
|
+
</MenuItem>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Edge cases
|
|
274
|
+
|
|
275
|
+
- **Tag with very long text**: cap with `max-width` + `text-overflow: ellipsis`. Provide `title` for full text.
|
|
276
|
+
- **Badge count flickering** (count changes rapidly): debounce updates to avoid visual jitter.
|
|
277
|
+
- **Badge over a clickable child**: badge should be `pointer-events: none` so clicks reach the child.
|
|
278
|
+
- **Tag click + close button click**: stop propagation on close button so tag's onClick doesn't fire.
|
|
279
|
+
- **Many tags wrapping**: use flex with gap, allow wrapping. Don't truncate the row of tags.
|
|
280
|
+
- **Korean tag text**: typically short (1–4 syllables) — fits easily.
|
|
281
|
+
|
|
282
|
+
## Don't
|
|
283
|
+
|
|
284
|
+
- Don't use Tag for buttons.
|
|
285
|
+
- Don't use Badge for decorative effect — meaning required.
|
|
286
|
+
- Don't combine 4+ colors of tags in one row — picks one or two semantic colors.
|
|
287
|
+
- Don't show "0" count badge unless `showZero` (visual noise).
|
|
288
|
+
- Don't put images / videos in a Tag. Text + small icon only.
|
|
289
|
+
- Don't use Badge as the only indicator for critical info.
|
|
290
|
+
- Don't omit screen reader text for count badges.
|
|
291
|
+
|
|
292
|
+
## References
|
|
293
|
+
|
|
294
|
+
- Ant Design: [`refs/ant-design/components/tag/`](../refs/ant-design/components/tag/) (Tag) + [`refs/ant-design/components/badge/`](../refs/ant-design/components/badge/) (Badge). Both well-developed; Tag has `Tag.CheckableTag` for filter-style.
|
|
295
|
+
- MUI: `Chip` (closest to Tag) + `Badge`. MUI Chip has `clickable`, `deletable`, `avatar` slot — most flexible.
|
|
296
|
+
- shadcn-ui: [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/badge.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/badge.tsx) — minimal Tag-equivalent. shadcn doesn't have a separate Tag/Badge distinction; user composes.
|
|
297
|
+
|
|
298
|
+
API choices made:
|
|
299
|
+
- **Tag and Badge as separate components**: matches Ant + MUI; clearer than a single "Pill" with a `mode` flag.
|
|
300
|
+
- **Tag's `color` accepts hex** in addition to semantic names — for category-colored tags (e.g., a project color).
|
|
301
|
+
- **Badge's `count` + `max`**: matches Ant convention. `99+` is the universal display.
|
|
302
|
+
- **Combined spec**: shared visual language and tokens; avoids triplicate maintenance for nearly-identical pieces.
|
|
303
|
+
|
|
304
|
+
## Cross-reference
|
|
305
|
+
|
|
306
|
+
- [`examples/component-button.md`](component-button.md) — when interactive emphasis matters more than category
|
|
307
|
+
- [`examples/component-avatar.md`](component-avatar.md) — Badge on Avatar pattern
|
|
308
|
+
- [`examples/component-form-controls.md`](component-form-controls.md) — Tag in multi-select
|
|
309
|
+
- [`knowledge/a11y/contrast.md`](../knowledge/a11y/contrast.md) — color tags must clear AA
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# `Tag` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from Ant Design `Tag`. Closeable label / chip for filters, attributes, or selected items. See [`component-tag-badge.md`](component-tag-badge.md) for Tag + Badge comparison.
|
|
4
|
+
|
|
5
|
+
## Tag vs Badge
|
|
6
|
+
|
|
7
|
+
> Tag = removable / interactive. Badge = passive indicator.
|
|
8
|
+
|
|
9
|
+
- Filter chips ("Marketing × Sales × ×"): Tag.
|
|
10
|
+
- Notification count: Badge.
|
|
11
|
+
- Selected items in multi-select: Tag.
|
|
12
|
+
- Status indicator on a parent: Badge.
|
|
13
|
+
|
|
14
|
+
## Anatomy
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
[ React ×] [ TypeScript ×] [ + Add tag ]
|
|
18
|
+
↑ closeable
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## API
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
<Tag>React</Tag>
|
|
25
|
+
<Tag closable onClose={() => removeTag("react")}>React</Tag>
|
|
26
|
+
<Tag color="error">Failed</Tag>
|
|
27
|
+
<Tag color="success">Active</Tag>
|
|
28
|
+
<Tag icon={<CheckIcon />}>Verified</Tag>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Prop | Type | Default | Description |
|
|
32
|
+
| --- | --- | --- | --- |
|
|
33
|
+
| `closable` | `boolean` | `false` | Show × button |
|
|
34
|
+
| `onClose` | `() => void` | — | Close callback |
|
|
35
|
+
| `color` | `"default" \| "brand" \| "success" \| "warning" \| "error" \| "info"` | `"default"` | Color preset |
|
|
36
|
+
| `icon` | `ReactNode` | — | Leading icon |
|
|
37
|
+
| `bordered` | `boolean` | `true` | Border style |
|
|
38
|
+
| `size` | `"sm" \| "md"` | `"md"` | — |
|
|
39
|
+
| `disabled` | `boolean` | `false` | — |
|
|
40
|
+
|
|
41
|
+
## States
|
|
42
|
+
|
|
43
|
+
| State | Visual |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| Default | Filled / outlined per variant |
|
|
46
|
+
| Hover (closable) | Subtle shift |
|
|
47
|
+
| Close button hover | Distinct hover on × |
|
|
48
|
+
| Disabled | Reduced opacity, no events |
|
|
49
|
+
|
|
50
|
+
## Tokens consumed
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
--tag-bg-default / -brand / -success / -warning / -error / -info
|
|
54
|
+
--tag-fg-default / ...
|
|
55
|
+
--tag-border-default / ...
|
|
56
|
+
--radius-sm (slightly less rounded than chips)
|
|
57
|
+
--space-xxs (icon gap)
|
|
58
|
+
--font-size-sm
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Accessibility
|
|
62
|
+
|
|
63
|
+
- For removable: `<button aria-label="Remove {label}">×</button>` inside the tag.
|
|
64
|
+
- For non-interactive: just `<span>`; no role needed.
|
|
65
|
+
- If tags are filterable: wrap group in `<div role="group" aria-label="Active filters">`.
|
|
66
|
+
|
|
67
|
+
## Code example — filter chips
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
<div role="group" aria-label="활성 필터">
|
|
71
|
+
{filters.map(f => (
|
|
72
|
+
<Tag
|
|
73
|
+
key={f.id}
|
|
74
|
+
closable
|
|
75
|
+
onClose={() => removeFilter(f.id)}
|
|
76
|
+
color="brand"
|
|
77
|
+
>
|
|
78
|
+
{f.label}
|
|
79
|
+
</Tag>
|
|
80
|
+
))}
|
|
81
|
+
</div>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Korean conventions
|
|
85
|
+
|
|
86
|
+
- 태그 / 필터: 합쇼체 / 해요체 either; tag labels are usually nouns.
|
|
87
|
+
- Status colors same as global conventions.
|
|
88
|
+
|
|
89
|
+
## Don't
|
|
90
|
+
|
|
91
|
+
- Don't use Tag for primary CTAs.
|
|
92
|
+
- Don't pile up 20+ tags inline. Wrap or paginate.
|
|
93
|
+
- Don't omit `aria-label` on close button.
|
|
94
|
+
|
|
95
|
+
## References
|
|
96
|
+
|
|
97
|
+
- Ant: [`Tag`](../refs/ant-design/components/tag)
|
|
98
|
+
|
|
99
|
+
## Cross-reference
|
|
100
|
+
|
|
101
|
+
- [`examples/component-tag-badge.md`](component-tag-badge.md) — combined spec
|
|
102
|
+
- [`examples/component-badge.md`](component-badge.md) — passive indicator
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# `TestimonialCarousel` — spec
|
|
2
|
+
|
|
3
|
+
> Marketing primitive. Rotates customer testimonials. Most-skipped section on landing pages — get it right or skip it entirely.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Display customer quotes / case studies / reviews. Used as social proof between feature display and pricing.
|
|
8
|
+
|
|
9
|
+
## When TestimonialCarousel vs static testimonials
|
|
10
|
+
|
|
11
|
+
| Pattern | Use |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| **Carousel** | Many testimonials (5+); horizontal screen real estate matters |
|
|
14
|
+
| **Static 3-up grid** | 3 strong testimonials; landing page already short |
|
|
15
|
+
| **No testimonials** | < 3 strong quotes, or audience won't care (developer tools rarely care about user testimonials) |
|
|
16
|
+
|
|
17
|
+
If you can't find 3 strong testimonials, **don't fake it**. Skip the section.
|
|
18
|
+
|
|
19
|
+
## Anatomy
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
┌────────────────────────────────────────────────────────────┐
|
|
23
|
+
│ Section title (optional) │
|
|
24
|
+
│ │
|
|
25
|
+
│ ┌────────────────────────────────────────────────────────┐ │
|
|
26
|
+
│ │ ★★★★★ │ │
|
|
27
|
+
│ │ │ │
|
|
28
|
+
│ │ "은행 앱을 30번씩 보지 않아도 되니 너무 편해요. │ │
|
|
29
|
+
│ │ 처음엔 이게 정말 자동으로 분류될까 의심했는데 │ │
|
|
30
|
+
│ │ 3주 쓰니 90% 이상 맞춰주네요." │ │
|
|
31
|
+
│ │ │ │
|
|
32
|
+
│ │ ┌──┐ 김민지 · 마케터 │ │
|
|
33
|
+
│ │ └──┘ 사용 6개월 │ │
|
|
34
|
+
│ └────────────────────────────────────────────────────────┘ │
|
|
35
|
+
│ │
|
|
36
|
+
│ ● ○ ○ ○ ○ │
|
|
37
|
+
└────────────────────────────────────────────────────────────┘
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<TestimonialCarousel
|
|
44
|
+
title="실제 사용자 후기"
|
|
45
|
+
testimonials={[
|
|
46
|
+
{
|
|
47
|
+
quote: "은행 앱을 30번씩 보지 않아도 되니 너무 편해요.",
|
|
48
|
+
authorName: "김민지",
|
|
49
|
+
authorRole: "마케터",
|
|
50
|
+
authorPhotoUrl: "/users/minji.jpg",
|
|
51
|
+
authorBadge: "사용 6개월",
|
|
52
|
+
rating: 5,
|
|
53
|
+
},
|
|
54
|
+
// ...
|
|
55
|
+
]}
|
|
56
|
+
variant="single-large"
|
|
57
|
+
autoplay={false}
|
|
58
|
+
/>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Prop | Type | Default | Description |
|
|
62
|
+
| --- | --- | --- | --- |
|
|
63
|
+
| `title` | `string` | — | Section heading |
|
|
64
|
+
| `testimonials` | `Testimonial[]` | — | Array of quotes |
|
|
65
|
+
| `variant` | `"single-large" \| "3-up-grid" \| "auto-scroll"` | `"single-large"` | Display layout |
|
|
66
|
+
| `autoplay` | `boolean` | `false` | (Default off — see deck-design rules) |
|
|
67
|
+
| `autoplayInterval` | `number` | `8000` | ms |
|
|
68
|
+
| `showNavigation` | `boolean` | `true` | Arrows + dots |
|
|
69
|
+
| `showRating` | `boolean` | `true` | Stars per testimonial |
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
type Testimonial = {
|
|
73
|
+
quote: string;
|
|
74
|
+
authorName: string;
|
|
75
|
+
authorRole?: string;
|
|
76
|
+
authorPhotoUrl?: string;
|
|
77
|
+
authorBadge?: string; // "사용 6개월", "Pro 회원"
|
|
78
|
+
rating?: 1 | 2 | 3 | 4 | 5;
|
|
79
|
+
source?: string; // "App Store 리뷰" / "사용자 인터뷰"
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Variants
|
|
84
|
+
|
|
85
|
+
### `single-large` (default)
|
|
86
|
+
|
|
87
|
+
One testimonial visible at a time, large. Carousel moves to next on click / swipe.
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
"Quote text — large, focal."
|
|
91
|
+
— Author photo + name + role
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Best for **hero quotes** that deserve full attention.
|
|
95
|
+
|
|
96
|
+
### `3-up-grid` (no carousel)
|
|
97
|
+
|
|
98
|
+
Three testimonials in a row. No rotation. Static.
|
|
99
|
+
|
|
100
|
+
Better when you want all 3 testimonials seen without interaction.
|
|
101
|
+
|
|
102
|
+
### `auto-scroll`
|
|
103
|
+
|
|
104
|
+
Continuous horizontal scroll (right-to-left), slow speed (~30 px/sec). Mimics infinite-marquee. Used for "logo wall" feel — many short quotes scrolling past.
|
|
105
|
+
|
|
106
|
+
Pause on hover. Respect `prefers-reduced-motion`.
|
|
107
|
+
|
|
108
|
+
## Quote rules
|
|
109
|
+
|
|
110
|
+
| Rule | Why |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| **Quote real customers**, with their permission. | Legal + trust. |
|
|
113
|
+
| **Use full names** (or initials with permission). | "JS, Seoul" reads as fake. |
|
|
114
|
+
| **Photos help** — match to name. | Real-people photos > stock photos. |
|
|
115
|
+
| **Specific quote** beats generic. | "Saves 4 hours / week" > "Great product!" |
|
|
116
|
+
| **Edit minimally** — typos OK to fix. | Don't reword to fit your marketing voice. |
|
|
117
|
+
| **Date or duration** matters. | "Used for 6 months" > undated. |
|
|
118
|
+
|
|
119
|
+
## Korean testimonial conventions
|
|
120
|
+
|
|
121
|
+
- Author name: 한국 이름 + 직책. "김민지 · 마케터".
|
|
122
|
+
- Photo: optional, but commonly included.
|
|
123
|
+
- Voice: ~해요 (casual) is most common in consumer testimonials. Don't overly formalize.
|
|
124
|
+
- "★★★★★ + 평점 4.8" — pair with overall rating if available.
|
|
125
|
+
- Source: "App Store 리뷰", "사용자 인터뷰", "Twitter" — adds legitimacy.
|
|
126
|
+
|
|
127
|
+
## States
|
|
128
|
+
|
|
129
|
+
| State | Visual |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| Default | One quote visible (single-large) |
|
|
132
|
+
| Auto-pause on hover | All variants |
|
|
133
|
+
| Reduced motion | Auto-scroll → static; auto-play → off |
|
|
134
|
+
| Loading | Skeleton matching quote shape |
|
|
135
|
+
| No testimonials | Render nothing (don't show empty section) |
|
|
136
|
+
|
|
137
|
+
## Tokens consumed
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
--color-bg-default
|
|
141
|
+
--color-bg-subtle (alternate row in grid)
|
|
142
|
+
--color-text-primary (quote text)
|
|
143
|
+
--color-text-secondary (author name + role)
|
|
144
|
+
--color-text-tertiary (date, source)
|
|
145
|
+
--color-warning (star rating)
|
|
146
|
+
--space-lg, --space-xl
|
|
147
|
+
--radius-lg
|
|
148
|
+
--font-size-lg, --font-size-xl (quote text — larger than body)
|
|
149
|
+
--font-weight-medium
|
|
150
|
+
--motion-default
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Sizes
|
|
154
|
+
|
|
155
|
+
| Element | Mobile | Desktop |
|
|
156
|
+
| --- | --- | --- |
|
|
157
|
+
| Quote font | 18px | 24–28px |
|
|
158
|
+
| Author name | 14px | 16px |
|
|
159
|
+
| Avatar | 40px | 48–56px |
|
|
160
|
+
|
|
161
|
+
## Accessibility
|
|
162
|
+
|
|
163
|
+
- Wrap in `<section>` with `<h2>` for section title.
|
|
164
|
+
- Each testimonial: `<blockquote>` with `<cite>` for attribution.
|
|
165
|
+
- Stars: `aria-label="평점 4점 / 5점"` (don't read each star separately).
|
|
166
|
+
- Carousel arrows: `aria-label="다음" / "이전"`.
|
|
167
|
+
- Auto-play: provide pause button (WCAG 2.2.2).
|
|
168
|
+
- For dot indicators: `aria-label="2 / 5번째"`.
|
|
169
|
+
|
|
170
|
+
## Code example
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
<TestimonialCarousel
|
|
174
|
+
title="실제 사용자 후기"
|
|
175
|
+
testimonials={[
|
|
176
|
+
{
|
|
177
|
+
quote: "은행 앱을 30번씩 보지 않아도 되니 너무 편해요. 처음엔 이게 정말 자동으로 분류될까 의심했는데 3주 쓰니 90% 이상 맞춰주네요.",
|
|
178
|
+
authorName: "김민지",
|
|
179
|
+
authorRole: "마케터",
|
|
180
|
+
authorPhotoUrl: "/users/minji.jpg",
|
|
181
|
+
authorBadge: "사용 6개월",
|
|
182
|
+
rating: 5,
|
|
183
|
+
source: "App Store 리뷰",
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
quote: "월급 받는 날 자동으로 적금에 옮겨주는 자동이체 룰이 신기해요.",
|
|
187
|
+
authorName: "박지훈",
|
|
188
|
+
authorRole: "개발자",
|
|
189
|
+
authorPhotoUrl: "/users/jihoon.jpg",
|
|
190
|
+
authorBadge: "사용 1년",
|
|
191
|
+
rating: 5,
|
|
192
|
+
},
|
|
193
|
+
// ...
|
|
194
|
+
]}
|
|
195
|
+
variant="single-large"
|
|
196
|
+
/>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Don't
|
|
200
|
+
|
|
201
|
+
- Don't fabricate testimonials.
|
|
202
|
+
- Don't auto-play without pause control (WCAG fail).
|
|
203
|
+
- Don't use stock-photo "models" — readers spot it.
|
|
204
|
+
- Don't put 5-paragraph quotes in a carousel — readers won't read.
|
|
205
|
+
- Don't omit names — "Anonymous user" is suspicious.
|
|
206
|
+
- Don't mix testimonial format (some with stars, some without) — pick one.
|
|
207
|
+
|
|
208
|
+
## References
|
|
209
|
+
|
|
210
|
+
No upstream component is exactly this. Each marketing builder (Webflow, Framer) has variants.
|
|
211
|
+
|
|
212
|
+
## Cross-reference
|
|
213
|
+
|
|
214
|
+
- [`examples/component-carousel.md`](component-carousel.md) — base Carousel pattern
|
|
215
|
+
- [`examples/component-hero-block.md`](component-hero-block.md) — comes before
|
|
216
|
+
- [`examples/component-feature-grid.md`](component-feature-grid.md) — comes between
|
|
217
|
+
- [`examples/component-pricing-cards.md`](component-pricing-cards.md) — comes after
|
|
218
|
+
- [`knowledge/patterns/landing-page-patterns.md`](../knowledge/patterns/landing-page-patterns.md)
|