@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,281 @@
|
|
|
1
|
+
# `BiometricGate` (custom — Korean mobile fintech) — spec
|
|
2
|
+
|
|
3
|
+
> Custom component pattern. Required for Korean fintech / banking apps. No upstream design system has this — it's a domain-specific composition over OS APIs.
|
|
4
|
+
>
|
|
5
|
+
> Cited knowledge: [`knowledge/i18n/korean-product-conventions.md`](../knowledge/i18n/korean-product-conventions.md), [`knowledge/i18n/korean-payments.md`](../knowledge/i18n/korean-payments.md), [`knowledge/platforms/react-native.md`](../knowledge/platforms/react-native.md)
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Gates app entry (or a sensitive flow) behind biometric authentication: Face ID / Touch ID (iOS), fingerprint / face recognition (Android).
|
|
10
|
+
|
|
11
|
+
Korean financial apps **almost universally implement this**. Users have come to expect it for any app touching money — banking, fintech, payments, asset management. Skipping it makes the app feel insecure or unfinished.
|
|
12
|
+
|
|
13
|
+
## When to use
|
|
14
|
+
|
|
15
|
+
| Use case | Required? |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| App open (banking, KakaoPay, Toss) | Strongly expected by users |
|
|
18
|
+
| Before transfer / payment | Common (configurable per user) |
|
|
19
|
+
| Before viewing sensitive details (account number, balance) | Sometimes |
|
|
20
|
+
| Before changing payment methods | Sometimes |
|
|
21
|
+
| Before changing security settings | Yes |
|
|
22
|
+
| First-time setup | No — biometric is enrolled later |
|
|
23
|
+
|
|
24
|
+
## Anatomy
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
┌─────────────────────────────────────────┐
|
|
28
|
+
│ │
|
|
29
|
+
│ [App logo] │
|
|
30
|
+
│ │
|
|
31
|
+
│ [biometric icon] │ ← face/fingerprint icon
|
|
32
|
+
│ (~80px) │
|
|
33
|
+
│ │
|
|
34
|
+
│ Face ID로 인증해 주세요 │ ← title
|
|
35
|
+
│ (또는 Touch ID / 지문) │
|
|
36
|
+
│ │
|
|
37
|
+
│ │
|
|
38
|
+
│ [📱 Face ID 사용] │ ← primary CTA
|
|
39
|
+
│ [비밀번호로 로그인] │ ← fallback
|
|
40
|
+
│ │
|
|
41
|
+
└─────────────────────────────────────────┘
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
| Slot | Required | Notes |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| App logo | optional | Reassures user this is the legitimate app |
|
|
47
|
+
| Biometric icon | yes | Matches the available method (face / fingerprint) |
|
|
48
|
+
| Title | yes | "Face ID로 인증해 주세요" or device-appropriate |
|
|
49
|
+
| Description | optional | Explanation if needed |
|
|
50
|
+
| Primary CTA | yes | Triggers the OS biometric prompt |
|
|
51
|
+
| Fallback CTA | yes | Password / PIN login (always provide) |
|
|
52
|
+
|
|
53
|
+
## API
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
<BiometricGate
|
|
57
|
+
required
|
|
58
|
+
fallbackMethod="pin"
|
|
59
|
+
onSuccess={() => navigate("/dashboard")}
|
|
60
|
+
onFallback={() => navigate("/login/pin")}
|
|
61
|
+
onCancel={() => navigate("/login")}
|
|
62
|
+
reason="개인 정보 보호를 위해 인증이 필요합니다"
|
|
63
|
+
appLogo={<Logo />}
|
|
64
|
+
/>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| Prop | Type | Default | Description |
|
|
68
|
+
| --- | --- | --- | --- |
|
|
69
|
+
| `required` | `boolean` | `true` | If false, allow skip via close button |
|
|
70
|
+
| `fallbackMethod` | `"pin" \| "password" \| "pattern" \| "none"` | `"pin"` | Backup auth method |
|
|
71
|
+
| `onSuccess` | `() => void` | — | Called when biometric succeeds |
|
|
72
|
+
| `onFallback` | `() => void` | — | Called when user picks fallback |
|
|
73
|
+
| `onCancel` | `() => void` | — | (When `required: false`) close pressed |
|
|
74
|
+
| `reason` | `string` | — | Shown to user; also passed to OS prompt as the reason |
|
|
75
|
+
| `autoTrigger` | `boolean` | `true` | Trigger OS prompt on mount automatically |
|
|
76
|
+
| `appLogo` | `ReactNode` | — | Decorative logo |
|
|
77
|
+
| `errorText` | `string` | — | Error after a failed attempt |
|
|
78
|
+
|
|
79
|
+
## OS integration
|
|
80
|
+
|
|
81
|
+
### iOS (React Native)
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import * as LocalAuthentication from "expo-local-authentication";
|
|
85
|
+
|
|
86
|
+
const triggerBiometric = async () => {
|
|
87
|
+
const isCompatible = await LocalAuthentication.hasHardwareAsync();
|
|
88
|
+
const isEnrolled = await LocalAuthentication.isEnrolledAsync();
|
|
89
|
+
if (!isCompatible || !isEnrolled) {
|
|
90
|
+
onFallback();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const result = await LocalAuthentication.authenticateAsync({
|
|
95
|
+
promptMessage: reason || "본인 확인",
|
|
96
|
+
fallbackLabel: "비밀번호로 로그인",
|
|
97
|
+
cancelLabel: "취소",
|
|
98
|
+
disableDeviceFallback: false,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
if (result.success) onSuccess();
|
|
102
|
+
else if (result.error === "user_cancel") onCancel();
|
|
103
|
+
else if (result.error === "user_fallback") onFallback();
|
|
104
|
+
else setErrorText("인증에 실패했습니다");
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Android (React Native)
|
|
109
|
+
|
|
110
|
+
Same `expo-local-authentication` API; falls back to fingerprint or face on supported devices.
|
|
111
|
+
|
|
112
|
+
### Web
|
|
113
|
+
|
|
114
|
+
Web's `WebAuthn` API exists but is rarely used in Korean consumer apps. For web fintech: typically a 6-digit PIN or 본인인증 (PASS / SMS) instead.
|
|
115
|
+
|
|
116
|
+
This spec primarily targets **mobile native apps** (React Native or platform native).
|
|
117
|
+
|
|
118
|
+
## Behavior
|
|
119
|
+
|
|
120
|
+
### On mount
|
|
121
|
+
|
|
122
|
+
1. Component renders with biometric icon + CTA.
|
|
123
|
+
2. If `autoTrigger: true`: OS prompt opens immediately.
|
|
124
|
+
3. User completes biometric → `onSuccess`.
|
|
125
|
+
4. User cancels → `onCancel` (or stay on screen if `required`).
|
|
126
|
+
5. User picks "Use password" → `onFallback`.
|
|
127
|
+
|
|
128
|
+
### After failed attempt
|
|
129
|
+
|
|
130
|
+
- iOS: 3 failed attempts disable biometric for that session; user must use fallback.
|
|
131
|
+
- Android: similar; OS handles lockout.
|
|
132
|
+
- Update `errorText` with "인증에 실패했습니다. 비밀번호를 사용해 주세요."
|
|
133
|
+
- Don't auto-retry. User decides.
|
|
134
|
+
|
|
135
|
+
### After lockout (5+ failures)
|
|
136
|
+
|
|
137
|
+
- Biometric disabled until app is reopened.
|
|
138
|
+
- Prompt user to use the fallback method.
|
|
139
|
+
- Optionally: log out and require full sign-in.
|
|
140
|
+
|
|
141
|
+
## States
|
|
142
|
+
|
|
143
|
+
| State | Visual |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| Idle (waiting for trigger) | Icon + CTA visible |
|
|
146
|
+
| Authenticating | Icon pulsing or spinner overlay |
|
|
147
|
+
| Success | Brief checkmark, then navigate (or instant navigate) |
|
|
148
|
+
| Failed | Error text below icon, CTA re-enabled to retry |
|
|
149
|
+
| Locked out | "Biometric unavailable" text, fallback only |
|
|
150
|
+
| OS prompt visible | Component is dimmed; OS handles input |
|
|
151
|
+
|
|
152
|
+
## Tokens consumed
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
--color-bg-default
|
|
156
|
+
--color-text-primary
|
|
157
|
+
--color-text-secondary
|
|
158
|
+
--color-primary-default (icon, primary CTA)
|
|
159
|
+
--color-error (error state)
|
|
160
|
+
--color-success (success checkmark)
|
|
161
|
+
--space-lg, --space-xl, --space-2xl
|
|
162
|
+
--font-size-xl, --font-size-2xl
|
|
163
|
+
--motion-default (icon pulse, success checkmark)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Accessibility
|
|
167
|
+
|
|
168
|
+
- Title is `<h1>` — primary message of the screen.
|
|
169
|
+
- Biometric icon: `aria-hidden="true"` (decorative, the title carries meaning).
|
|
170
|
+
- CTA button: clear `aria-label` if icon-only ("Use Face ID to sign in").
|
|
171
|
+
- Fallback button: visible label, easy to find — don't bury it.
|
|
172
|
+
- Error text: `role="alert"` so screen reader announces.
|
|
173
|
+
- For users who can't use biometric: fallback path must be accessible without going through the biometric prompt.
|
|
174
|
+
|
|
175
|
+
## Korean copy patterns
|
|
176
|
+
|
|
177
|
+
| Method | Title (KR) |
|
|
178
|
+
| --- | --- |
|
|
179
|
+
| Face ID (iOS) | "Face ID로 인증해 주세요" |
|
|
180
|
+
| Touch ID (iOS) | "Touch ID로 인증해 주세요" |
|
|
181
|
+
| Fingerprint (Android) | "지문으로 인증해 주세요" |
|
|
182
|
+
| Face (Android) | "얼굴 인식으로 인증해 주세요" |
|
|
183
|
+
| Generic | "본인 확인" / "생체 인증" |
|
|
184
|
+
|
|
185
|
+
| Action | Korean |
|
|
186
|
+
| --- | --- |
|
|
187
|
+
| Use Face ID | Face ID 사용 |
|
|
188
|
+
| Use fingerprint | 지문 사용 |
|
|
189
|
+
| Use password | 비밀번호로 로그인 |
|
|
190
|
+
| Use PIN | PIN 입력 |
|
|
191
|
+
| Cancel | 취소 |
|
|
192
|
+
| Try again | 다시 시도 |
|
|
193
|
+
|
|
194
|
+
## Code example
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
function AppLaunchGate() {
|
|
198
|
+
const navigate = useNavigation();
|
|
199
|
+
const [error, setError] = useState<string>();
|
|
200
|
+
|
|
201
|
+
const handleSuccess = () => navigate("/dashboard");
|
|
202
|
+
const handleFallback = () => navigate("/login/pin");
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<BiometricGate
|
|
206
|
+
required
|
|
207
|
+
autoTrigger
|
|
208
|
+
reason="대시보드를 보려면 인증이 필요합니다"
|
|
209
|
+
fallbackMethod="pin"
|
|
210
|
+
onSuccess={handleSuccess}
|
|
211
|
+
onFallback={handleFallback}
|
|
212
|
+
errorText={error}
|
|
213
|
+
appLogo={<Logo />}
|
|
214
|
+
/>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// As an action gate (not full screen)
|
|
219
|
+
function TransferConfirm() {
|
|
220
|
+
const [showGate, setShowGate] = useState(false);
|
|
221
|
+
|
|
222
|
+
return (
|
|
223
|
+
<>
|
|
224
|
+
<Button onClick={() => setShowGate(true)}>송금하기</Button>
|
|
225
|
+
{showGate && (
|
|
226
|
+
<BiometricGate
|
|
227
|
+
required={false}
|
|
228
|
+
reason="송금을 위해 본인 확인이 필요합니다"
|
|
229
|
+
onSuccess={() => { setShowGate(false); executeTransfer(); }}
|
|
230
|
+
onCancel={() => setShowGate(false)}
|
|
231
|
+
/>
|
|
232
|
+
)}
|
|
233
|
+
</>
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Edge cases
|
|
239
|
+
|
|
240
|
+
- **Biometric not enrolled** (user hasn't set up Face ID / fingerprint on device): show fallback as primary, with explanation.
|
|
241
|
+
- **Biometric hardware not available** (older device): same — fallback only.
|
|
242
|
+
- **User has enrolled but disabled biometric for this app** in OS settings: show fallback + link to settings.
|
|
243
|
+
- **Background return** (user backgrounds app, returns): re-trigger gate based on app's session policy (typically 30 sec timeout).
|
|
244
|
+
- **Multiple biometric methods on Android** (face + fingerprint): OS prompt handles selection. Don't try to manage in app.
|
|
245
|
+
- **Server-side rejection** (biometric ok locally but server doesn't accept token): show error and route to fallback. Treat as auth failure, not biometric failure.
|
|
246
|
+
- **Network offline at gate**: this is local auth — should work offline. The token is verified later when network returns.
|
|
247
|
+
- **First time biometric on this device**: prompt before triggering ("Use Face ID for faster sign-in?") — don't surprise the user with an OS prompt cold.
|
|
248
|
+
|
|
249
|
+
## Korean app submission considerations
|
|
250
|
+
|
|
251
|
+
Per [`knowledge/i18n/korean-publishing.md`](../knowledge/i18n/korean-publishing.md):
|
|
252
|
+
|
|
253
|
+
- iOS: `NSFaceIDUsageDescription` in `Info.plist` must be in Korean for KR storefront ("Face ID를 사용하여 안전하게 로그인합니다.").
|
|
254
|
+
- Android: permission `USE_BIOMETRIC` (or `USE_FINGERPRINT` for older API). Permission rationale popup required for KR Play Store.
|
|
255
|
+
- App Store Connect: privacy policy must mention biometric data (even though it's processed on-device).
|
|
256
|
+
|
|
257
|
+
## Don't
|
|
258
|
+
|
|
259
|
+
- Don't make biometric the **only** auth method. Always provide fallback.
|
|
260
|
+
- Don't auto-trigger biometric on every screen — user fatigue.
|
|
261
|
+
- Don't trigger biometric without user-initiated action (e.g., on app launch is OK; mid-scrolling is not).
|
|
262
|
+
- Don't process biometric data on server. Per OS APIs, biometric verification is on-device; the server gets a token, not biometric data.
|
|
263
|
+
- Don't gate trivial actions behind biometric. Reserve for sensitive operations.
|
|
264
|
+
- Don't show biometric on web without a serious WebAuthn implementation. Use PIN / 본인인증 instead.
|
|
265
|
+
- Don't store biometric "results" in app state beyond the session. Re-prompt next session.
|
|
266
|
+
- Don't omit privacy disclosure (Korean law requires it).
|
|
267
|
+
|
|
268
|
+
## API rationale
|
|
269
|
+
|
|
270
|
+
- **`required: true` default**: matches user expectation for fintech app launch. False is the in-app action gate case.
|
|
271
|
+
- **`autoTrigger: true` default**: a screen with biometric should immediately attempt — making the user tap the button first adds a step.
|
|
272
|
+
- **`fallbackMethod` typed**: PIN / password / pattern are the realistic options. "None" rare and discouraged.
|
|
273
|
+
- **`reason` passed to OS prompt**: iOS shows this as the prompt subtitle. Be specific.
|
|
274
|
+
|
|
275
|
+
## Cross-reference
|
|
276
|
+
|
|
277
|
+
- [`knowledge/i18n/korean-product-conventions.md`](../knowledge/i18n/korean-product-conventions.md) — biometric expectations in KR
|
|
278
|
+
- [`knowledge/i18n/korean-payments.md`](../knowledge/i18n/korean-payments.md) — payment auth context
|
|
279
|
+
- [`knowledge/i18n/korean-publishing.md`](../knowledge/i18n/korean-publishing.md) — privacy disclosure requirements
|
|
280
|
+
- [`knowledge/platforms/react-native.md`](../knowledge/platforms/react-native.md) — RN-specific implementation
|
|
281
|
+
- [`examples/component-modal.md`](component-modal.md) — focus management when as inline gate
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# `Blockquote` — spec
|
|
2
|
+
|
|
3
|
+
> Doc-specific. For attributed quotations from other people. Distinct from `Callout` (which is editor-flagged content).
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Render a quotation visually distinct from body text. Cite the source. Used in long-form articles, research reports (user quotes), case studies (customer quotes).
|
|
8
|
+
|
|
9
|
+
## Anatomy
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
"
|
|
13
|
+
The quote text, often slightly larger and styled
|
|
14
|
+
distinctly from body. May span multiple lines.
|
|
15
|
+
"
|
|
16
|
+
|
|
17
|
+
— Attribution name, role
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
OR with bar accent:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
│ The quote text. Bar on left signals quote.
|
|
24
|
+
│
|
|
25
|
+
│ — Attribution name
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## API
|
|
29
|
+
|
|
30
|
+
```jsx
|
|
31
|
+
<Blockquote>
|
|
32
|
+
<p>The quote text.</p>
|
|
33
|
+
<Blockquote.Cite>Attribution name, role</Blockquote.Cite>
|
|
34
|
+
</Blockquote>
|
|
35
|
+
|
|
36
|
+
// Or with the cite prop
|
|
37
|
+
<Blockquote cite="https://example.com/source">
|
|
38
|
+
The quote text.
|
|
39
|
+
</Blockquote>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| Prop | Type | Default | Description |
|
|
43
|
+
| --- | --- | --- | --- |
|
|
44
|
+
| `children` | `ReactNode` | — | Quote content |
|
|
45
|
+
| `cite` | `string` | — | Source URL (renders as `<cite>` element) |
|
|
46
|
+
| `variant` | `"default" \| "pull-quote"` | `"default"` | |
|
|
47
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | |
|
|
48
|
+
|
|
49
|
+
## Variants
|
|
50
|
+
|
|
51
|
+
### Default
|
|
52
|
+
|
|
53
|
+
Inline within reading flow:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
> Body text body text body text...
|
|
57
|
+
>
|
|
58
|
+
> "The quote text."
|
|
59
|
+
> — Source
|
|
60
|
+
>
|
|
61
|
+
> Body text continues...
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Pull-quote
|
|
65
|
+
|
|
66
|
+
Larger, often centered, breaks up dense reading:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
"The quote text — larger,
|
|
70
|
+
emphasized, distinct."
|
|
71
|
+
|
|
72
|
+
— Source
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Used in editorial / marketing prose to surface a key sentiment.
|
|
76
|
+
|
|
77
|
+
## Sizes
|
|
78
|
+
|
|
79
|
+
| Size | Font | Body context |
|
|
80
|
+
| --- | --- | --- |
|
|
81
|
+
| `sm` | matches body | Inline mention |
|
|
82
|
+
| `md` (default) | 1.125× body | Standard quote |
|
|
83
|
+
| `lg` (pull-quote) | 1.5× body | Editorial breaking-out |
|
|
84
|
+
|
|
85
|
+
## Style choices
|
|
86
|
+
|
|
87
|
+
| Style cue | Use |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| Italic body | Latin convention. Don't use for Hangul. |
|
|
90
|
+
| Larger size | Universal — signals quote |
|
|
91
|
+
| Left bar (border-left) | Modern, clean |
|
|
92
|
+
| Quote marks (large) | Editorial / marketing |
|
|
93
|
+
| Centered text | Pull-quote variant |
|
|
94
|
+
| Subtle bg tint | Differentiation in dense layouts |
|
|
95
|
+
|
|
96
|
+
For Korean: don't italicize (no italic Hangul). Use weight (`font-weight: 500`) or color shift.
|
|
97
|
+
|
|
98
|
+
## Tokens consumed
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
--color-text-primary
|
|
102
|
+
--color-text-secondary (attribution)
|
|
103
|
+
--color-text-tertiary
|
|
104
|
+
--color-border-default (left bar)
|
|
105
|
+
--color-bg-subtle (optional bg tint)
|
|
106
|
+
--space-md, --space-base
|
|
107
|
+
--font-size-base, --font-size-lg, --font-size-xl
|
|
108
|
+
--font-weight-medium
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Accessibility
|
|
112
|
+
|
|
113
|
+
- Use semantic `<blockquote>` element. Ships with implicit role.
|
|
114
|
+
- Attribution: `<cite>` element. Renders as italic by default; override per language.
|
|
115
|
+
- Cite URL: optional `cite` attribute on `<blockquote>` for machine-readable source.
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<blockquote cite="https://example.com/source">
|
|
119
|
+
<p>The quote text.</p>
|
|
120
|
+
<footer><cite>— Source name</cite></footer>
|
|
121
|
+
</blockquote>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Korean conventions
|
|
125
|
+
|
|
126
|
+
For quotations:
|
|
127
|
+
- Use double quotes `" "` or angle quotes `「 」` — double Latin is most common in modern Korean docs.
|
|
128
|
+
- Attribution: `— 이름` or `— 이름, 직책`.
|
|
129
|
+
- Don't italicize (Hangul has no italic form). Use weight or color.
|
|
130
|
+
|
|
131
|
+
```html
|
|
132
|
+
<blockquote>
|
|
133
|
+
<p>"이 디자인은 정말 신선합니다."</p>
|
|
134
|
+
<cite>— 김민지, 디자인 디렉터</cite>
|
|
135
|
+
</blockquote>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Don't
|
|
139
|
+
|
|
140
|
+
- Don't italicize Hangul.
|
|
141
|
+
- Don't omit attribution. An unattributed quote is suspicious.
|
|
142
|
+
- Don't use blockquote for non-quotations (rule, tip, note — those are Callouts).
|
|
143
|
+
- Don't nest blockquotes. Quote-in-a-quote is rare; use prose.
|
|
144
|
+
|
|
145
|
+
## References
|
|
146
|
+
|
|
147
|
+
Universal HTML element. Most doc tools render `<blockquote>` consistently. Style varies.
|
|
148
|
+
|
|
149
|
+
## Cross-reference
|
|
150
|
+
|
|
151
|
+
- [`examples/component-callout.md`](component-callout.md) — for editor flags, not quotes
|
|
152
|
+
- [`knowledge/patterns/document-typography.md`](../knowledge/patterns/document-typography.md) — pull-quote rules
|
|
153
|
+
- [`knowledge/patterns/report-design.md`](../knowledge/patterns/report-design.md) — research quote patterns
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# `BorderBeam` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from Ant Design `BorderBeam`, with host-surface guidance cross-checked against MUI `Paper` / `Card` and shadcn-ui `Card`. `BorderBeam` is a decorative emphasis layer, not a semantic status, focus, or validation border.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- A single container needs controlled visual emphasis: featured AI panel, recommended card, login panel, onboarding highlight, or primary dashboard module.
|
|
8
|
+
- The surface already has a clear semantic role and the beam only increases visual salience.
|
|
9
|
+
- The child host is a real DOM element or a component that forwards its ref to a DOM element.
|
|
10
|
+
|
|
11
|
+
When NOT to use:
|
|
12
|
+
- Validation, focus, selected, error, success, warning, or destructive state. Use semantic border/status tokens instead.
|
|
13
|
+
- Dense dashboards with many cards. More than one or two beams on a viewport reads as noise.
|
|
14
|
+
- Motion-sensitive or high-focus workflows where a moving border competes with reading or data entry.
|
|
15
|
+
- Containers whose root cannot provide a stable DOM ref, position context, or border radius.
|
|
16
|
+
|
|
17
|
+
## Anatomy
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
BorderBeam
|
|
21
|
+
├── Child host element
|
|
22
|
+
│ ├── Existing surface content
|
|
23
|
+
│ └── Beam effect layer (portal, aria-hidden)
|
|
24
|
+
└── Gradient / inset / radius CSS variables
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| Part | Purpose | Required | Default if omitted |
|
|
28
|
+
| --- | --- | --- | --- |
|
|
29
|
+
| Child host | The decorated element that receives the portal layer. | yes | Plain text or non-ref children render without the beam. |
|
|
30
|
+
| Beam effect layer | Absolutely-positioned visual border effect inside the host. | internal | Hidden until browser support and host resolution pass. |
|
|
31
|
+
| Gradient | Beam color or gradient stops. | no | Uses primary theme gradient. |
|
|
32
|
+
| Inset offset | Moves the effect outward from the host edge. | no | Inferred from host border width. |
|
|
33
|
+
| Radius bridge | Mirrors the host border radius for alignment. | internal | Reads computed radius during initialization. |
|
|
34
|
+
|
|
35
|
+
## API
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
<BorderBeam
|
|
39
|
+
color={[
|
|
40
|
+
{ color: "var(--color-primary-default)", percent: 0 },
|
|
41
|
+
{ color: "var(--color-accent-default)", percent: 100 },
|
|
42
|
+
]}
|
|
43
|
+
outset={0}
|
|
44
|
+
>
|
|
45
|
+
<section className="featured-panel">
|
|
46
|
+
<h2>AI review ready</h2>
|
|
47
|
+
<p>3 design-system risks need review.</p>
|
|
48
|
+
</section>
|
|
49
|
+
</BorderBeam>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
| Prop | Type | Default | Description |
|
|
53
|
+
| --- | --- | --- | --- |
|
|
54
|
+
| `children` | `ReactNode` | — | Decorated content. Must resolve to a single host DOM element for the beam to render. |
|
|
55
|
+
| `color` | `string \| { color: string; percent: number }[]` | theme primary gradient | Solid beam color or ordered gradient stops. `percent` is authored as `0` to `100`; implementation maps it into the visible beam segment. |
|
|
56
|
+
| `outset` | `number \| string` | host border width | Offset from the container edge. Use `0` when the host clips overflow or already owns a visible border. |
|
|
57
|
+
| `className` | `string` | — | Class applied to the beam effect layer, not the child host. |
|
|
58
|
+
| `style` | `CSSProperties` | — | Inline styles for the beam effect layer, including custom CSS variables. |
|
|
59
|
+
| `prefixCls` | `string` | design-system prefix | Advanced namespace override. Prefer provider-level configuration. |
|
|
60
|
+
|
|
61
|
+
## API choices made
|
|
62
|
+
|
|
63
|
+
- Keep the API intentionally small. `BorderBeam` should decorate a surface; it should not become a full Card variant system.
|
|
64
|
+
- Keep `color` as either one semantic token string or explicit gradient stops. Do not add `intent="success"` / `intent="error"` because that would imply semantic status.
|
|
65
|
+
- Treat `outset` as an alignment escape hatch. Most product code should rely on host border inference or set `outset={0}` for clipped cards.
|
|
66
|
+
- Do not expose speed, direction, or looping props by default. Constant decorative motion should be rare, reduced-motion-safe, and globally governed by motion tokens.
|
|
67
|
+
|
|
68
|
+
## States
|
|
69
|
+
|
|
70
|
+
| State | Trigger | Visual / behavior |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| Default | Host resolves and browser supports required CSS masking / offset-path | Beam layer renders around the host, `pointer-events: none`, `aria-hidden="true"`. |
|
|
73
|
+
| Unsupported CSS | Browser lacks mask or offset-path support | Beam stays hidden; child content remains unchanged. |
|
|
74
|
+
| Missing host | Plain text, fragment, non-ref component, or SVG child | Beam is skipped; child content still renders. |
|
|
75
|
+
| Hover | Pointer over host | No built-in change. Host component may own its normal hover state. |
|
|
76
|
+
| Focus-visible | Keyboard focus on host or child control | Beam must not replace the 2px focus ring. Focus ring keeps at least 3:1 contrast per `keyboard-and-focus.md`. |
|
|
77
|
+
| Active | Pointer / keyboard activation on host content | No built-in change. Interactive child components own active feedback. |
|
|
78
|
+
| Disabled | Disabled content inside host | Beam should usually be removed; a disabled surface should not attract attention. |
|
|
79
|
+
| Loading | Async content inside host | Keep only if it helps identify the active module; never use the beam as loading progress. |
|
|
80
|
+
| Error | Error content inside host | Remove or recolor through semantic error UI; do not use decorative beam as the only error indicator. |
|
|
81
|
+
| Reduced motion | `prefers-reduced-motion: reduce` | Hide the moving effect or freeze it into a non-moving border highlight. |
|
|
82
|
+
|
|
83
|
+
## Variants
|
|
84
|
+
|
|
85
|
+
### Emphasis level
|
|
86
|
+
|
|
87
|
+
| Level | Use | Visual rule |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| `subtle` | Secondary highlight, recommendation card | Low-opacity token gradient, no extra shadow. |
|
|
90
|
+
| `default` | One primary featured surface | Primary to accent gradient, one beam per viewport region. |
|
|
91
|
+
| `campaign` | Marketing or onboarding hero module | Stronger gradient is allowed, but still respects reduced motion and contrast. |
|
|
92
|
+
|
|
93
|
+
### Host surface
|
|
94
|
+
|
|
95
|
+
| Host | Rule |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| Card / Paper | Put radius and `position: relative` on the actual root element. |
|
|
98
|
+
| Button / link card | Keep the focus ring outside or above the beam; do not rely on the beam for focus. |
|
|
99
|
+
| Modal / dialog | Avoid except for onboarding. Motion around modal edges can distract from the task. |
|
|
100
|
+
| Data table / form | Avoid. Continuous motion is disruptive for scanning and input. |
|
|
101
|
+
|
|
102
|
+
## Tokens consumed
|
|
103
|
+
|
|
104
|
+
```css
|
|
105
|
+
--color-primary-default
|
|
106
|
+
--color-primary-hover
|
|
107
|
+
--color-accent-default
|
|
108
|
+
--color-focus-ring
|
|
109
|
+
--color-border-emphasis
|
|
110
|
+
--radius-md
|
|
111
|
+
--radius-lg
|
|
112
|
+
--border-width-sm
|
|
113
|
+
--motion-duration-slow
|
|
114
|
+
--motion-easing-linear
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
If your design system does not have `--color-border-emphasis`, map the default beam to primary/accent tokens and keep semantic status tokens separate.
|
|
118
|
+
|
|
119
|
+
## Accessibility
|
|
120
|
+
|
|
121
|
+
- **Semantics**: the beam layer is decorative and must render with `aria-hidden="true"`.
|
|
122
|
+
- **Keyboard**: `BorderBeam` itself is not focusable and adds no keyboard behavior. Any interactive child keeps its native keyboard contract.
|
|
123
|
+
- **Focus**: never use the moving beam as focus indication. Interactive descendants need a visible 2px focus ring with at least 3:1 contrast against adjacent colors.
|
|
124
|
+
- **Reduced motion**: hide the moving beam for `prefers-reduced-motion: reduce`, or replace it with a static border. This follows `motion/principles.md`.
|
|
125
|
+
- **Pointer behavior**: the effect layer uses `pointer-events: none` so it cannot block clicks, text selection, or hover states on the host.
|
|
126
|
+
- **Contrast**: because the beam is decorative, it does not carry required information. If a design uses border color to communicate state, provide text/icon redundancy and at least 3:1 non-text contrast.
|
|
127
|
+
- **Screen readers**: no announcement is needed for beam appearance. Announce only the actual state or content change inside the host.
|
|
128
|
+
- **Touch target**: if the decorated host is interactive, keep the host target at least 44x44 on mobile and at least 24x24 for WCAG 2.2 AA web minimum.
|
|
129
|
+
|
|
130
|
+
## Code example — featured module
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
type FeaturedModuleProps = {
|
|
134
|
+
title: string;
|
|
135
|
+
description: string;
|
|
136
|
+
action: React.ReactNode;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export function FeaturedModule({ title, description, action }: FeaturedModuleProps) {
|
|
140
|
+
return (
|
|
141
|
+
<BorderBeam
|
|
142
|
+
color={[
|
|
143
|
+
{ color: "var(--color-primary-default)", percent: 0 },
|
|
144
|
+
{ color: "var(--color-accent-default)", percent: 100 },
|
|
145
|
+
]}
|
|
146
|
+
outset={0}
|
|
147
|
+
>
|
|
148
|
+
<section className="featured-module" aria-labelledby="featured-module-title">
|
|
149
|
+
<div>
|
|
150
|
+
<h2 id="featured-module-title">{title}</h2>
|
|
151
|
+
<p>{description}</p>
|
|
152
|
+
</div>
|
|
153
|
+
{action}
|
|
154
|
+
</section>
|
|
155
|
+
</BorderBeam>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
```css
|
|
161
|
+
.featured-module {
|
|
162
|
+
position: relative;
|
|
163
|
+
overflow: hidden;
|
|
164
|
+
border: 1px solid var(--color-border-subtle);
|
|
165
|
+
border-radius: var(--radius-lg);
|
|
166
|
+
background: var(--color-bg-elevated);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.featured-module:focus-within {
|
|
170
|
+
outline: 2px solid var(--color-focus-ring);
|
|
171
|
+
outline-offset: 2px;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@media (prefers-reduced-motion: reduce) {
|
|
175
|
+
.ant-border-beam::before {
|
|
176
|
+
display: none;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Edge cases
|
|
182
|
+
|
|
183
|
+
- **Non-ref child**: function components must forward a ref to the real DOM root, or the beam cannot mount.
|
|
184
|
+
- **Plain text / fragment**: render content without decoration. Do not wrap automatically because it can change layout and semantics.
|
|
185
|
+
- **Static positioning**: the beam may inject, but deterministic placement needs `position: relative` on the host.
|
|
186
|
+
- **Overflow clipping**: use `outset={0}` when the host has `overflow: hidden`; negative offsets can be clipped unpredictably.
|
|
187
|
+
- **Changing radius**: radius is read during initialization. If responsive or state-driven radius changes matter, set the final radius on the host before mount or remount the decorated host.
|
|
188
|
+
- **Custom gradient stops**: clamp authored `percent` to `0..100`; preserve a transparent tail so the beam has a visible fade.
|
|
189
|
+
- **RTL**: the decorative direction does not need semantic mirroring. If brand motion direction matters, define it in the motion system rather than per component.
|
|
190
|
+
- **Print**: hide the beam in print; decorative motion and gradients do not belong on invoices, reports, or contracts.
|
|
191
|
+
- **Korean B2B sensitive-data surfaces**: use sparingly. One highlighted review panel is acceptable; continuous decoration around HR or payroll forms can reduce perceived seriousness.
|
|
192
|
+
|
|
193
|
+
## Don't
|
|
194
|
+
|
|
195
|
+
- Don't use `BorderBeam` as a substitute for focus-visible, selected, validation, or status borders.
|
|
196
|
+
- Don't decorate every card in a grid.
|
|
197
|
+
- Don't pass literal brand hex values in product code; use semantic color tokens.
|
|
198
|
+
- Don't wrap a component that cannot forward a DOM ref and then treat the missing beam as a rendering bug.
|
|
199
|
+
- Don't animate around long-form reading, tables, or data-entry forms unless the user explicitly requested a guided highlight.
|
|
200
|
+
|
|
201
|
+
## References
|
|
202
|
+
|
|
203
|
+
- Ant Design: [`BorderBeam.tsx`](../refs/ant-design/components/border-beam/BorderBeam.tsx), [`BorderBeamEffect.tsx`](../refs/ant-design/components/border-beam/BorderBeamEffect.tsx), [`border-beam/index.en-US.md`](../refs/ant-design/components/border-beam/index.en-US.md), [`border-beam/style/index.ts`](../refs/ant-design/components/border-beam/style/index.ts)
|
|
204
|
+
- MUI: [`Paper.d.ts`](../refs/mui/packages/mui-material/src/Paper/Paper.d.ts), [`Card.d.ts`](../refs/mui/packages/mui-material/src/Card/Card.d.ts)
|
|
205
|
+
- shadcn-ui: [`card.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/card.tsx)
|
|
206
|
+
- Knowledge: [`a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md), [`motion/principles.md`](../knowledge/motion/principles.md), [`components/INDEX.md`](../knowledge/components/INDEX.md)
|
|
207
|
+
- Cross-reference: [`component-card.md`](component-card.md), [`component-paper.md`](component-paper.md), [`component-button-base.md`](component-button-base.md)
|