📦 deps(skills): sync thirdparty skills
This commit is contained in:
@@ -55,6 +55,11 @@ CSV_CONFIG = {
|
||||
"search_cols": ["Category", "Icon Name", "Keywords", "Best For"],
|
||||
"output_cols": ["Category", "Icon Name", "Keywords", "Library", "Import Code", "Usage", "Best For", "Style"]
|
||||
},
|
||||
"gsap": {
|
||||
"file": "motion.csv",
|
||||
"search_cols": ["Category", "Intensity Tier", "Keywords", "Trigger"],
|
||||
"output_cols": ["Category", "Intensity Tier", "Trigger", "Duration", "Easing", "GSAP Snippet", "Framework Notes", "Do", "Don't", "Performance Notes"]
|
||||
},
|
||||
"react": {
|
||||
"file": "react-performance.csv",
|
||||
"search_cols": ["Category", "Issue", "Keywords", "Description"],
|
||||
@@ -215,6 +220,7 @@ def detect_domain(query):
|
||||
"typography": ["font pairing", "typography pairing", "heading font", "body font"],
|
||||
"google-fonts": ["google font", "font family", "font weight", "font style", "variable font", "noto", "font for", "find font", "font subset", "font language", "monospace font", "serif font", "sans serif font", "display font", "handwriting font", "font", "typography", "serif", "sans"],
|
||||
"icons": ["icon", "icons", "lucide", "heroicons", "symbol", "glyph", "pictogram", "svg icon"],
|
||||
"gsap": ["gsap", "quickto", "scrolltrigger", "stagger", "magnetic cursor", "parallax", "page transition", "scroll reveal", "scroll-triggered", "scrollytelling", "flip plugin", "splittext", "shimmer", "skeleton loader"],
|
||||
"react": ["react", "next.js", "nextjs", "suspense", "memo", "usecallback", "useeffect", "rerender", "bundle", "waterfall", "barrel", "dynamic import", "rsc", "server component"],
|
||||
"web": ["aria", "focus", "outline", "semantic", "virtualize", "autocomplete", "form", "input type", "preconnect"]
|
||||
}
|
||||
|
||||
+193
-21
@@ -40,6 +40,39 @@ SEARCH_CONFIG = {
|
||||
"typography": {"max_results": 2}
|
||||
}
|
||||
|
||||
# ============ DESIGN DIALS (1-10) ============
|
||||
# Inspired by taste-skill's DESIGN_VARIANCE / MOTION_INTENSITY / VISUAL_DENSITY
|
||||
# knobs: three optional 1-10 sliders that bias the existing query-based search
|
||||
# instead of replacing it. Each dial buckets into a low/mid/high tier.
|
||||
DIAL_TIERS = {
|
||||
"variance": [
|
||||
(1, 3, {"label": "Centered / Minimal", "style_keywords": ["Minimalism", "Exaggerated Minimalism", "centered", "symmetric", "grid-based"]}),
|
||||
(4, 7, {"label": "Balanced / Modern", "style_keywords": ["modern", "structured", "balanced"]}),
|
||||
(8, 10, {"label": "Bold / Asymmetric", "style_keywords": ["Brutalism", "Bento Grids", "asymmetric", "experimental"]}),
|
||||
],
|
||||
"motion": [
|
||||
(1, 3, {"label": "Subtle", "tier": "Subtle"}),
|
||||
(4, 7, {"label": "Standard", "tier": "Standard"}),
|
||||
(8, 10, {"label": "Complex", "tier": "Complex"}),
|
||||
],
|
||||
"density": [
|
||||
(1, 3, {"label": "Spacious", "spacing": {"xs": "4px", "sm": "8px", "md": "24px", "lg": "32px", "xl": "48px", "2xl": "64px", "3xl": "96px"}}),
|
||||
(4, 7, {"label": "Standard", "spacing": {"xs": "4px", "sm": "8px", "md": "16px", "lg": "24px", "xl": "32px", "2xl": "48px", "3xl": "64px"}}),
|
||||
(8, 10, {"label": "Dense / Dashboard", "spacing": {"xs": "2px", "sm": "4px", "md": "8px", "lg": "12px", "xl": "16px", "2xl": "24px", "3xl": "32px"}}),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def _resolve_dial(dial_name: str, value) -> dict:
|
||||
"""Bucket a 1-10 dial value into its tier config. Returns None if value is None."""
|
||||
if value is None:
|
||||
return None
|
||||
value = max(1, min(10, int(value)))
|
||||
for lo, hi, info in DIAL_TIERS[dial_name]:
|
||||
if lo <= value <= hi:
|
||||
return {**info, "value": value}
|
||||
return None
|
||||
|
||||
|
||||
# ============ DESIGN SYSTEM GENERATOR ============
|
||||
class DesignSystemGenerator:
|
||||
@@ -168,8 +201,18 @@ class DesignSystemGenerator:
|
||||
"""Extract results list from search result dict."""
|
||||
return search_result.get("results", [])
|
||||
|
||||
def generate(self, query: str, project_name: str = None) -> dict:
|
||||
"""Generate complete design system recommendation."""
|
||||
def generate(self, query: str, project_name: str = None,
|
||||
variance: int = None, motion: int = None, density: int = None) -> dict:
|
||||
"""Generate complete design system recommendation.
|
||||
|
||||
variance/motion/density are optional 1-10 dials (see DIAL_TIERS) that bias
|
||||
style selection, pull in a matching motion.csv snippet, and override the
|
||||
spacing scale, without changing behavior when left unset.
|
||||
"""
|
||||
variance_info = _resolve_dial("variance", variance)
|
||||
motion_info = _resolve_dial("motion", motion)
|
||||
density_info = _resolve_dial("density", density)
|
||||
|
||||
# Step 1: First search product to get category
|
||||
product_result = search(query, "product", 1)
|
||||
product_results = product_result.get("results", [])
|
||||
@@ -181,8 +224,14 @@ class DesignSystemGenerator:
|
||||
reasoning = self._apply_reasoning(category, {})
|
||||
style_priority = reasoning.get("style_priority", [])
|
||||
|
||||
# DESIGN_VARIANCE dial: bias style retrieval/selection toward
|
||||
# centered-minimal (low) or bold-asymmetric (high) keywords.
|
||||
effective_style_priority = style_priority
|
||||
if variance_info:
|
||||
effective_style_priority = variance_info["style_keywords"] + style_priority
|
||||
|
||||
# Step 3: Multi-domain search with style priority hints
|
||||
search_results = self._multi_domain_search(query, style_priority)
|
||||
search_results = self._multi_domain_search(query, effective_style_priority)
|
||||
search_results["product"] = product_result # Reuse product search
|
||||
|
||||
# Step 4: Select best matches from each domain using priority
|
||||
@@ -191,11 +240,24 @@ class DesignSystemGenerator:
|
||||
typography_results = self._extract_results(search_results.get("typography", {}))
|
||||
landing_results = self._extract_results(search_results.get("landing", {}))
|
||||
|
||||
best_style = self._select_best_match(style_results, reasoning.get("style_priority", []))
|
||||
best_style = self._select_best_match(style_results, effective_style_priority)
|
||||
best_color = color_results[0] if color_results else {}
|
||||
best_typography = typography_results[0] if typography_results else {}
|
||||
best_landing = landing_results[0] if landing_results else {}
|
||||
|
||||
# MOTION_INTENSITY dial: pull a matching GSAP skeleton from motion.csv
|
||||
# (domain key is "gsap", not "motion" - PR #296 already owns the "motion"
|
||||
# domain for Emil Kowalski's motion-design principles, motion-principles.csv).
|
||||
motion_snippet = {}
|
||||
if motion_info:
|
||||
motion_result = search(f"{query} {motion_info['tier']}", "gsap", 5)
|
||||
motion_matches = motion_result.get("results", [])
|
||||
tiered = [m for m in motion_matches if m.get("Intensity Tier") == motion_info["tier"]]
|
||||
if tiered:
|
||||
motion_snippet = tiered[0]
|
||||
elif motion_matches:
|
||||
motion_snippet = motion_matches[0]
|
||||
|
||||
# Step 5: Build final recommendation
|
||||
# Combine effects from both reasoning and style search
|
||||
style_effects = best_style.get("Effects & Animation", "")
|
||||
@@ -250,7 +312,17 @@ class DesignSystemGenerator:
|
||||
"key_effects": combined_effects,
|
||||
"anti_patterns": reasoning.get("anti_patterns", ""),
|
||||
"decision_rules": reasoning.get("decision_rules", {}),
|
||||
"severity": reasoning.get("severity", "MEDIUM")
|
||||
"severity": reasoning.get("severity", "MEDIUM"),
|
||||
"dials": {
|
||||
"variance": variance_info["value"] if variance_info else None,
|
||||
"variance_label": variance_info["label"] if variance_info else None,
|
||||
"motion": motion_info["value"] if motion_info else None,
|
||||
"motion_label": motion_info["label"] if motion_info else None,
|
||||
"density": density_info["value"] if density_info else None,
|
||||
"density_label": density_info["label"] if density_info else None,
|
||||
},
|
||||
"motion_snippet": motion_snippet,
|
||||
"spacing_scale": density_info["spacing"] if density_info else None,
|
||||
}
|
||||
|
||||
|
||||
@@ -296,6 +368,8 @@ def format_ascii_box(design_system: dict) -> str:
|
||||
typography = design_system.get("typography", {})
|
||||
effects = design_system.get("key_effects", "")
|
||||
anti_patterns = design_system.get("anti_patterns", "")
|
||||
dials = design_system.get("dials", {})
|
||||
motion_snippet = design_system.get("motion_snippet", {})
|
||||
|
||||
def wrap_text(text: str, prefix: str, width: int) -> list:
|
||||
"""Wrap long text into multiple lines."""
|
||||
@@ -329,6 +403,16 @@ def format_ascii_box(design_system: dict) -> str:
|
||||
lines.append("╚" + "═" * w + "╝")
|
||||
lines.append("┌" + "─" * w + "┐")
|
||||
|
||||
# Design Dials section (only if at least one dial was set)
|
||||
if any(dials.get(k) is not None for k in ("variance", "motion", "density")):
|
||||
lines.append(section_header("DESIGN DIALS", BOX_WIDTH + 1))
|
||||
if dials.get("variance") is not None:
|
||||
lines.append(f"│ Variance: {dials['variance']}/10 — {dials['variance_label']}".ljust(BOX_WIDTH) + "│")
|
||||
if dials.get("motion") is not None:
|
||||
lines.append(f"│ Motion: {dials['motion']}/10 — {dials['motion_label']}".ljust(BOX_WIDTH) + "│")
|
||||
if dials.get("density") is not None:
|
||||
lines.append(f"│ Density: {dials['density']}/10 — {dials['density_label']}".ljust(BOX_WIDTH) + "│")
|
||||
|
||||
# Pattern section
|
||||
lines.append(section_header("PATTERN", BOX_WIDTH + 1))
|
||||
lines.append(f"│ Name: {pattern.get('name', '')}".ljust(BOX_WIDTH) + "│")
|
||||
@@ -402,6 +486,17 @@ def format_ascii_box(design_system: dict) -> str:
|
||||
for line in wrap_text(effects, "│ ", BOX_WIDTH):
|
||||
lines.append(line.ljust(BOX_WIDTH) + "│")
|
||||
|
||||
# Motion section (GSAP skeleton, only if --motion dial was set)
|
||||
if motion_snippet:
|
||||
lines.append(section_header("MOTION", BOX_WIDTH + 1))
|
||||
lines.append(f"│ {motion_snippet.get('Category', '')} ({motion_snippet.get('Intensity Tier', '')})".ljust(BOX_WIDTH) + "│")
|
||||
lines.append(f"│ Trigger: {motion_snippet.get('Trigger', '')} | Duration: {motion_snippet.get('Duration', '')} | Easing: {motion_snippet.get('Easing', '')}".ljust(BOX_WIDTH) + "│")
|
||||
for line in wrap_text(f"GSAP: {motion_snippet.get('GSAP Snippet', '')}", "│ ", BOX_WIDTH):
|
||||
lines.append(line.ljust(BOX_WIDTH) + "│")
|
||||
if motion_snippet.get("Framework Notes"):
|
||||
for line in wrap_text(f"Framework: {motion_snippet.get('Framework Notes', '')}", "│ ", BOX_WIDTH):
|
||||
lines.append(line.ljust(BOX_WIDTH) + "│")
|
||||
|
||||
# Anti-patterns section
|
||||
if anti_patterns:
|
||||
lines.append(section_header("AVOID", BOX_WIDTH + 1))
|
||||
@@ -436,11 +531,24 @@ def format_markdown(design_system: dict) -> str:
|
||||
typography = design_system.get("typography", {})
|
||||
effects = design_system.get("key_effects", "")
|
||||
anti_patterns = design_system.get("anti_patterns", "")
|
||||
dials = design_system.get("dials", {})
|
||||
motion_snippet = design_system.get("motion_snippet", {})
|
||||
|
||||
lines = []
|
||||
lines.append(f"## Design System: {project}")
|
||||
lines.append("")
|
||||
|
||||
# Design Dials section (only if at least one dial was set)
|
||||
if any(dials.get(k) is not None for k in ("variance", "motion", "density")):
|
||||
lines.append("### Design Dials")
|
||||
if dials.get("variance") is not None:
|
||||
lines.append(f"- **Variance:** {dials['variance']}/10 — {dials['variance_label']}")
|
||||
if dials.get("motion") is not None:
|
||||
lines.append(f"- **Motion:** {dials['motion']}/10 — {dials['motion_label']}")
|
||||
if dials.get("density") is not None:
|
||||
lines.append(f"- **Density:** {dials['density']}/10 — {dials['density_label']}")
|
||||
lines.append("")
|
||||
|
||||
# Pattern section
|
||||
lines.append("### Pattern")
|
||||
lines.append(f"- **Name:** {pattern.get('name', '')}")
|
||||
@@ -515,6 +623,23 @@ def format_markdown(design_system: dict) -> str:
|
||||
lines.append(f"{effects}")
|
||||
lines.append("")
|
||||
|
||||
# Motion section (GSAP skeleton, only if --motion dial was set)
|
||||
if motion_snippet:
|
||||
lines.append("### Motion")
|
||||
lines.append(f"**{motion_snippet.get('Category', '')}** ({motion_snippet.get('Intensity Tier', '')}) — Trigger: {motion_snippet.get('Trigger', '')} | Duration: {motion_snippet.get('Duration', '')} | Easing: `{motion_snippet.get('Easing', '')}`")
|
||||
lines.append("```js")
|
||||
lines.append(motion_snippet.get("GSAP Snippet", ""))
|
||||
lines.append("```")
|
||||
if motion_snippet.get("Framework Notes"):
|
||||
lines.append(f"*Framework notes: {motion_snippet.get('Framework Notes', '')}*")
|
||||
motion_do = motion_snippet.get("Do", "")
|
||||
motion_dont = motion_snippet.get("Don't", "")
|
||||
if motion_do:
|
||||
lines.append(f"- ✅ {motion_do}")
|
||||
if motion_dont:
|
||||
lines.append(f"- ❌ {motion_dont}")
|
||||
lines.append("")
|
||||
|
||||
# Anti-patterns section
|
||||
if anti_patterns:
|
||||
lines.append("### Avoid (Anti-patterns)")
|
||||
@@ -537,8 +662,9 @@ def format_markdown(design_system: dict) -> str:
|
||||
|
||||
|
||||
# ============ MAIN ENTRY POINT ============
|
||||
def generate_design_system(query: str, project_name: str = None, output_format: str = "ascii",
|
||||
persist: bool = False, page: str = None, output_dir: str = None) -> str:
|
||||
def generate_design_system(query: str, project_name: str = None, output_format: str = "ascii",
|
||||
persist: bool = False, page: str = None, output_dir: str = None,
|
||||
variance: int = None, motion: int = None, density: int = None) -> str:
|
||||
"""
|
||||
Main entry point for design system generation.
|
||||
|
||||
@@ -549,13 +675,16 @@ def generate_design_system(query: str, project_name: str = None, output_format:
|
||||
persist: If True, save design system to design-system/ folder
|
||||
page: Optional page name for page-specific override file
|
||||
output_dir: Optional output directory (defaults to current working directory)
|
||||
variance: Optional 1-10 DESIGN_VARIANCE dial (1=centered/minimal, 10=bold/asymmetric)
|
||||
motion: Optional 1-10 MOTION_INTENSITY dial, pulls a matching GSAP snippet from motion.csv
|
||||
density: Optional 1-10 VISUAL_DENSITY dial, overrides the spacing scale (1=spacious, 10=dense)
|
||||
|
||||
Returns:
|
||||
Formatted design system string
|
||||
"""
|
||||
generator = DesignSystemGenerator()
|
||||
design_system = generator.generate(query, project_name)
|
||||
|
||||
design_system = generator.generate(query, project_name, variance=variance, motion=motion, density=density)
|
||||
|
||||
# Persist to files if requested
|
||||
if persist:
|
||||
persist_design_system(design_system, page, output_dir, query)
|
||||
@@ -627,11 +756,14 @@ def format_master_md(design_system: dict) -> str:
|
||||
typography = design_system.get("typography", {})
|
||||
effects = design_system.get("key_effects", "")
|
||||
anti_patterns = design_system.get("anti_patterns", "")
|
||||
|
||||
dials = design_system.get("dials", {})
|
||||
motion_snippet = design_system.get("motion_snippet", {})
|
||||
spacing_scale = design_system.get("spacing_scale")
|
||||
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
|
||||
lines = []
|
||||
|
||||
|
||||
# Logic header
|
||||
lines.append("# Design System Master File")
|
||||
lines.append("")
|
||||
@@ -644,6 +776,15 @@ def format_master_md(design_system: dict) -> str:
|
||||
lines.append(f"**Project:** {project}")
|
||||
lines.append(f"**Generated:** {timestamp}")
|
||||
lines.append(f"**Category:** {design_system.get('category', 'General')}")
|
||||
if any(dials.get(k) is not None for k in ("variance", "motion", "density")):
|
||||
dial_parts = []
|
||||
if dials.get("variance") is not None:
|
||||
dial_parts.append(f"Variance {dials['variance']}/10 ({dials['variance_label']})")
|
||||
if dials.get("motion") is not None:
|
||||
dial_parts.append(f"Motion {dials['motion']}/10 ({dials['motion_label']})")
|
||||
if dials.get("density") is not None:
|
||||
dial_parts.append(f"Density {dials['density']}/10 ({dials['density_label']})")
|
||||
lines.append(f"**Design Dials:** {' | '.join(dial_parts)}")
|
||||
lines.append("")
|
||||
lines.append("---")
|
||||
lines.append("")
|
||||
@@ -695,18 +836,24 @@ def format_master_md(design_system: dict) -> str:
|
||||
lines.append("```")
|
||||
lines.append("")
|
||||
|
||||
# Spacing Variables
|
||||
# Spacing Variables (overridden by the VISUAL_DENSITY dial when set)
|
||||
default_spacing = DIAL_TIERS["density"][1][2]["spacing"] # mid-tier = the historical defaults
|
||||
scale = spacing_scale or default_spacing
|
||||
spacing_usage = {
|
||||
"xs": "Tight gaps", "sm": "Icon gaps, inline spacing", "md": "Standard padding",
|
||||
"lg": "Section padding", "xl": "Large gaps", "2xl": "Section margins", "3xl": "Hero padding",
|
||||
}
|
||||
lines.append("### Spacing Variables")
|
||||
lines.append("")
|
||||
if spacing_scale:
|
||||
lines.append(f"*Density: {dials.get('density')}/10 — {dials.get('density_label')}*")
|
||||
lines.append("")
|
||||
lines.append("| Token | Value | Usage |")
|
||||
lines.append("|-------|-------|-------|")
|
||||
lines.append("| `--space-xs` | `4px` / `0.25rem` | Tight gaps |")
|
||||
lines.append("| `--space-sm` | `8px` / `0.5rem` | Icon gaps, inline spacing |")
|
||||
lines.append("| `--space-md` | `16px` / `1rem` | Standard padding |")
|
||||
lines.append("| `--space-lg` | `24px` / `1.5rem` | Section padding |")
|
||||
lines.append("| `--space-xl` | `32px` / `2rem` | Large gaps |")
|
||||
lines.append("| `--space-2xl` | `48px` / `3rem` | Section margins |")
|
||||
lines.append("| `--space-3xl` | `64px` / `4rem` | Hero padding |")
|
||||
for token in ("xs", "sm", "md", "lg", "xl", "2xl", "3xl"):
|
||||
px_value = scale[token]
|
||||
rem_value = f"{int(px_value.rstrip('px')) / 16:g}rem"
|
||||
lines.append(f"| `--space-{token}` | `{px_value}` / `{rem_value}` | {spacing_usage[token]} |")
|
||||
lines.append("")
|
||||
|
||||
# Shadow Depths
|
||||
@@ -848,7 +995,32 @@ def format_master_md(design_system: dict) -> str:
|
||||
lines.append(f"- **CTA Placement:** {pattern.get('cta_placement', '')}")
|
||||
lines.append(f"- **Section Order:** {pattern.get('sections', '')}")
|
||||
lines.append("")
|
||||
|
||||
|
||||
# Motion section (GSAP skeleton, only if --motion dial was set)
|
||||
if motion_snippet:
|
||||
lines.append("---")
|
||||
lines.append("")
|
||||
lines.append("## Motion")
|
||||
lines.append("")
|
||||
lines.append(f"**{motion_snippet.get('Category', '')}** ({motion_snippet.get('Intensity Tier', '')}) — Trigger: {motion_snippet.get('Trigger', '')} | Duration: {motion_snippet.get('Duration', '')} | Easing: `{motion_snippet.get('Easing', '')}`")
|
||||
lines.append("")
|
||||
lines.append("```js")
|
||||
lines.append(motion_snippet.get("GSAP Snippet", ""))
|
||||
lines.append("```")
|
||||
lines.append("")
|
||||
if motion_snippet.get("Framework Notes"):
|
||||
lines.append(f"**Framework notes:** {motion_snippet.get('Framework Notes', '')}")
|
||||
lines.append("")
|
||||
motion_do = motion_snippet.get("Do", "")
|
||||
motion_dont = motion_snippet.get("Don't", "")
|
||||
if motion_do:
|
||||
lines.append(f"- ✅ {motion_do}")
|
||||
if motion_dont:
|
||||
lines.append(f"- ❌ {motion_dont}")
|
||||
if motion_snippet.get("Performance Notes"):
|
||||
lines.append(f"- ⚡ {motion_snippet.get('Performance Notes', '')}")
|
||||
lines.append("")
|
||||
|
||||
# Anti-Patterns section
|
||||
lines.append("---")
|
||||
lines.append("")
|
||||
|
||||
+17
-4
@@ -5,10 +5,16 @@ UI/UX Pro Max Search - BM25 search engine for UI/UX style guides
|
||||
Usage: python search.py "<query>" [--domain <domain>] [--stack <stack>] [--max-results 3]
|
||||
python search.py "<query>" --design-system [-p "Project Name"]
|
||||
python search.py "<query>" --design-system --persist [-p "Project Name"] [--page "dashboard"]
|
||||
python search.py "<query>" --design-system --variance 8 --motion 9 --density 7
|
||||
|
||||
Domains: style, prompt, color, chart, landing, product, ux, typography, google-fonts
|
||||
Domains: style, prompt, color, chart, landing, product, ux, typography, google-fonts, gsap
|
||||
Stacks: react, nextjs, vue, svelte, astro, swiftui, react-native, flutter, nuxtjs, nuxt-ui, html-tailwind, shadcn, jetpack-compose, threejs, angular, laravel, javafx, wpf, winui, avalonia, uno, uwp
|
||||
|
||||
Design dials (1-10, only with --design-system):
|
||||
--variance DESIGN_VARIANCE: 1=centered/minimal, 10=bold/asymmetric
|
||||
--motion MOTION_INTENSITY: 1=subtle, 10=complex; attaches a GSAP snippet from motion.csv
|
||||
--density VISUAL_DENSITY: 1=spacious, 10=dense/dashboard; overrides the spacing scale
|
||||
|
||||
Persistence (Master + Overrides pattern):
|
||||
--persist Save design system to design-system/MASTER.md
|
||||
--page Also create a page-specific override file in design-system/pages/
|
||||
@@ -68,18 +74,25 @@ if __name__ == "__main__":
|
||||
parser.add_argument("--persist", action="store_true", help="Save design system to design-system/MASTER.md (creates hierarchical structure)")
|
||||
parser.add_argument("--page", type=str, default=None, help="Create page-specific override file in design-system/pages/")
|
||||
parser.add_argument("--output-dir", "-o", type=str, default=None, help="Output directory for persisted files (default: current directory)")
|
||||
# Design dials (1-10), only applied with --design-system
|
||||
parser.add_argument("--variance", type=int, choices=range(1, 11), metavar="1-10", help="DESIGN_VARIANCE dial: 1=centered/minimal, 10=bold/asymmetric (only with --design-system)")
|
||||
parser.add_argument("--motion", type=int, choices=range(1, 11), metavar="1-10", help="MOTION_INTENSITY dial: 1=subtle, 10=complex; pulls a matching GSAP snippet from motion.csv (only with --design-system)")
|
||||
parser.add_argument("--density", type=int, choices=range(1, 11), metavar="1-10", help="VISUAL_DENSITY dial: 1=spacious, 10=dense/dashboard; overrides the spacing scale (only with --design-system)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Design system takes priority
|
||||
if args.design_system:
|
||||
result = generate_design_system(
|
||||
args.query,
|
||||
args.project_name,
|
||||
args.query,
|
||||
args.project_name,
|
||||
args.format,
|
||||
persist=args.persist,
|
||||
page=args.page,
|
||||
output_dir=args.output_dir
|
||||
output_dir=args.output_dir,
|
||||
variance=args.variance,
|
||||
motion=args.motion,
|
||||
density=args.density
|
||||
)
|
||||
print(result)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user