{
  "version": "1.0.0",
  "description": "Reference data for hyper-animator skill: scoring formula, prompt mappings, taxonomies, and quality gates. Extracted from SKILL.md v1.12.1.",

  "scoringFormula": {
    "description": "7-factor weighted scoring model used in Step 3 catalog scoring. Hard constraints are applied BEFORE scoring; items failing hard constraints get score 0. KeywordMatch and intentDomainMatch together account for 55% because the user's domain and their own words are the strongest signal.",
    "totalWeight": 1.0,
    "factors": [
      {
        "name": "keywordMatch",
        "weight": 0.30,
        "calculation": "+0.05 per matching naturalLanguageTrigger (case-insensitive substring match)",
        "cap": "6 matches, max contribution 0.30",
        "rationale": "User's own words are the strongest signal"
      },
      {
        "name": "intentDomainMatch",
        "weight": 0.25,
        "calculation": "+0.25 if profile.purpose matches any item.intentDomains (boolean check)",
        "cap": "1 match, max contribution 0.25"
      },
      {
        "name": "formatMatch",
        "weight": 0.15,
        "calculation": "+0.15 if profile.format matches item.format.aspect",
        "cap": "1 match, max contribution 0.15"
      },
      {
        "name": "assetRoleMatch",
        "weight": 0.10,
        "calculation": "+0.05 per matching neededRole from profile",
        "cap": "2 matches, max contribution 0.10"
      },
      {
        "name": "styleMatch",
        "weight": 0.10,
        "calculation": "+0.04 per matching styleTag from profile",
        "cap": "3 matches, max contribution 0.10"
      },
      {
        "name": "motionMatch",
        "weight": 0.05,
        "calculation": "+0.025 per matching motionTag from profile",
        "cap": "2 matches, max contribution 0.05"
      },
      {
        "name": "constraintsMatch",
        "weight": 0.05,
        "calculation": "+0.025 for portrait format match, +0.025 for caption role match",
        "cap": "2 matches, max contribution 0.05"
      }
    ],
    "hardConstraints": [
      "Portrait requirements: if format is portrait_9_16, prioritize items with format.aspect === 'portrait_9_16' and exclude landscape-only blocks",
      "Caption overlay needed: if neededRoles includes 'caption', deprioritize items without caption capability for the caption slot",
      "code-morph exclusion: always exclude code-morph (manifest failed to load, source unavailable)",
      "Block vs Component: main_scene role prefers type:'block'; overlay roles (caption, effect) prefer type:'component'"
    ],
    "scoringWeightsJson": {
      "keywordMatch": 0.3,
      "intentDomainMatch": 0.25,
      "formatMatch": 0.15,
      "assetRoleMatch": 0.1,
      "styleMatch": 0.1,
      "motionMatch": 0.05,
      "constraintsMatch": 0.05
    }
  },

  "promptMappings": {
    "description": "Map style/motion tags to Minimax music-2.6 API prompt keywords (from Step 6.6a Prompt Construction). Build the final prompt by concatenating: style keywords + motion keywords + structure template.",
    "styleTags": {
      "apple_like":     ["modern", "clean", "electronic"],
      "cinematic":      ["cinematic", "orchestral", "dramatic"],
      "cyberpunk":      ["cyberpunk", "dark electronic", "industrial"],
      "minimal":        ["ambient", "minimal", "atmospheric"],
      "social_dynamic": ["upbeat", "energetic", "pop"],
      "editorial":      ["jazz", "sophisticated", "smooth"],
      "dark":           ["dark", "brooding", "bass-heavy"],
      "playful":        ["playful", "bouncy", "light"]
    },
    "motionTags": {
      "steady_premium": { "keywords": ["80 BPM"],            "bpm": 80  },
      "fast_impact":    { "keywords": ["140 BPM"],           "bpm": 140 },
      "soft_fluid":     { "keywords": ["100 BPM"],           "bpm": 100 },
      "glitch_cyber":   { "keywords": ["110 BPM", "glitch", "distorted"], "bpm": 110 }
    },
    "structureTemplate": "[Intro][Build Up][Drop][Break][Outro]",
    "fullPromptExample": "cyberpunk, dark electronic, 110 BPM, instrumental, glitch effects, [Intro][Build Up][Drop][Break][Outro]"
  },

  "taxonomies": {
    "intentDomains": [
      { "id": "product_launch",      "description": "Product/feature showcases, launch videos",                   "exampleItems": ["app-showcase", "hero-product", "feature-highlight"] },
      { "id": "developer_demo",      "description": "Code walkthroughs, terminal demos, SDK tutorials",            "exampleItems": ["code-typing", "code-scroll", "terminal-demo"] },
      { "id": "data_visualization",  "description": "Charts, maps, statistics, growth reports",                   "exampleItems": ["data-chart", "map-globe", "flowchart"] },
      { "id": "podcast_interview",   "description": "Interview overlays, speaker titles, podcast captions",       "exampleItems": ["lower-third", "podcast-title", "interview-frame"] },
      { "id": "social_media",        "description": "Short-form, TikTok/Reels, trending content",                  "exampleItems": ["tiktok-follow", "instagram-follow", "reels-template"] },
      { "id": "branding_outro",      "description": "Logo reveals, end cards, channel branding",                  "exampleItems": ["logo-outro", "brand-reveal", "sponsor-card"] },
      { "id": "caption_style",       "description": "Caption/karaoke/lyrics visual styles",                       "exampleItems": ["caption-pill-karaoke", "caption-line-reveal"] },
      { "id": "device_showcase",     "description": "Device frames, mockups, screen captures",                    "exampleItems": ["vfx-iphone-device", "browser-frame", "device-mockup"] },
      { "id": "transition",          "description": "Scene transitions, wipes, morphs",                           "exampleItems": ["grid-pixelate-wipe", "parallax-transition"] },
      { "id": "vfx",                 "description": "Visual effects, overlays, grain, glow",                      "exampleItems": ["grain-overlay", "glow-effect", "shimmer"] },
      { "id": "visual_enhancement",  "description": "General visual polish, depth, atmosphere",                   "exampleItems": ["vignette", "depth-glow", "light-leak"] }
    ],
    "formats": [
      { "id": "landscape_16_9", "width": 1920, "height": 1080, "typicalUse": "YouTube, Bilibili, widescreen, desktop" },
      { "id": "portrait_9_16",  "width": 1080, "height": 1920, "typicalUse": "TikTok, Shorts, Reels, mobile" },
      { "id": "square",         "width": 1080, "height": 1080, "typicalUse": "Instagram feed" },
      { "id": "custom",         "description": "Non-standard aspect ratios" },
      { "id": "flexible",       "description": "Adapts to container, responsive components" },
      { "id": "unknown",        "description": "Unspecified, needs user clarification" }
    ],
    "assetRoles": [
      { "id": "main_scene",      "typePreference": "block",       "whenNeeded": "Always — the core visual content" },
      { "id": "caption",         "typePreference": "component",   "whenNeeded": "User wants text overlays, subtitles, lyrics" },
      { "id": "effect",          "typePreference": "component",   "whenNeeded": "User wants visual polish, overlays, transitions" },
      { "id": "outro",           "typePreference": "block/component", "whenNeeded": "User wants end card, logo, branding" },
      { "id": "device_showcase", "typePreference": "component",   "whenNeeded": "User wants product in device frame" },
      { "id": "overlay",         "typePreference": "component",   "whenNeeded": "User wants grain, vignette, atmosphere" },
      { "id": "transition",      "typePreference": "component",   "whenNeeded": "User wants scene change effects" }
    ],
    "styleTags": {
      "apple_like":     { "visualDirection": "Apple-esque premium",           "characteristics": ["Clean geometry", "thin fonts", "soft lighting", "high contrast"] },
      "cinematic":      { "visualDirection": "Cinematic/dark tech",           "characteristics": ["Deep shadows", "anamorphic flares", "film grain", "letterbox"] },
      "minimal":        { "visualDirection": "Minimalist clean",              "characteristics": ["Lots of whitespace", "thin borders", "limited color palette"] },
      "social_dynamic": { "visualDirection": "Social media energetic",        "characteristics": ["Bright colors", "bold text", "fast cuts", "emoji/stickers"] },
      "cyberpunk":      { "visualDirection": "Cyberpunk/glitch",              "characteristics": ["Neon gradients", "scan lines", "glitch artifacts", "CRT effects"] },
      "editorial":      { "visualDirection": "Editorial/magazine",            "characteristics": ["Serif fonts", "columns", "pull quotes", "elegant composition"] },
      "dark":           { "visualDirection": "Dark theme",                    "characteristics": ["Dark backgrounds", "light text", "muted accents"] },
      "light":          { "visualDirection": "Light theme",                   "characteristics": ["Light backgrounds", "dark text", "airy feel"] },
      "premium":        { "visualDirection": "Premium/luxury",                "characteristics": ["Gold accents", "subtle animations", "refined typography"] },
      "news":           { "visualDirection": "News/broadcast",                "characteristics": ["Lower thirds", "breaking news bars", "professional color"] },
      "playful":        { "visualDirection": "Playful/fun",                   "characteristics": ["Bouncy animations", "rounded corners", "colorful"] },
      "retro":          { "visualDirection": "Retro/vintage",                 "characteristics": ["Grain", "scan lines", "limited color palettes", "period fonts"] }
    },
    "motionTags": {
      "reveal":          { "motionStyle": "Elements appear from hidden state",                "bestPairedWith": ["product_launch", "data_visualization"] },
      "zoom":            { "motionStyle": "Camera or element zooms in/out",                   "bestPairedWith": ["device_showcase", "cinematic"] },
      "staggered_reveal":{ "motionStyle": "Elements appear one after another",                "bestPairedWith": ["list features", "feature highlights"] },
      "blur":            { "motionStyle": "Motion blur, blur reveal",                          "bestPairedWith": ["cinematic", "transitions"] },
      "parallax":        { "motionStyle": "Multi-layer depth movement",                        "bestPairedWith": ["3D scenes", "atmospheric"] },
      "wipe":            { "motionStyle": "Wipe/scan transitions",                             "bestPairedWith": ["scene changes", "data transitions"] },
      "morph":           { "motionStyle": "Shape morphing transitions",                        "bestPairedWith": ["creative transitions"] },
      "glitch":          { "motionStyle": "Glitch/error artifacts",                            "bestPairedWith": ["cyberpunk", "tech aesthetic"] },
      "particle":        { "motionStyle": "Particle systems",                                  "bestPairedWith": ["atmosphere", "background"] },
      "slam":            { "motionStyle": "Impactful, sudden movements",                       "bestPairedWith": ["high-energy social", "product slam"] },
      "bounce":          { "motionStyle": "Bouncy, elastic motion",                            "bestPairedWith": ["playful", "social media"] },
      "scroll":          { "motionStyle": "Scrolling text or content",                         "bestPairedWith": ["credits", "code demos"] },
      "typing":          { "motionStyle": "Typewriter effect",                                 "bestPairedWith": ["code demos", "developer tools"] },
      "shader":          { "motionStyle": "WebGL shader effects",                              "bestPairedWith": ["advanced VFX", "transitions"] },
      "pan":             { "motionStyle": "Camera pan across scene",                           "bestPairedWith": ["panoramic", "wide scenes"] }
    }
  },

  "qualityGates": {
    "description": "Pre-render quality gates from Appendix B and Step 9. Required-pattern gates FAIL if missing. Forbidden-pattern gates FAIL if found. Warning gates are inspection-only. If any error-severity gate fails, DO NOT present for user validation — fix first.",
    "requiredPatternGates": [
      { "id": "has-fixed-width",         "severity": "error", "check": "data-width= attribute present on root element",           "regex": "data-width=\"\\d+\"" },
      { "id": "has-fixed-height",        "severity": "error", "check": "data-height= attribute present on root element",          "regex": "data-height=\"\\d+\"" },
      { "id": "has-composition-id",      "severity": "error", "check": "data-composition-id= attribute present",                  "regex": "data-composition-id=\"[^\"]+\"" },
      { "id": "has-paused-timeline",     "severity": "error", "check": "GSAP timeline created with paused:true",                  "regex": "gsap\\.timeline\\(\\{.*paused:\\s*true" },
      { "id": "has-timeline-registration","severity": "error", "check": "Timeline assigned to window.__timelines",                "regex": "window\\.__timelines" },
      { "id": "has-duration-coverage",   "severity": "error", "check": "data-duration= attribute present",                       "regex": "data-duration=\"\\d+\"" }
    ],
    "forbiddenPatternGates": [
      { "id": "no-date-now",       "severity": "error", "check": "No Date.now() for primary timing",           "regex": "Date\\.now\\(\\)" },
      { "id": "no-setinterval",    "severity": "error", "check": "No setInterval() for animation timing",     "regex": "setInterval\\(" },
      { "id": "no-paste-comments", "severity": "error", "check": "No unresolved <!-- paste from --> comments", "regex": "<!-- paste from " },
      { "id": "no-math-random",    "severity": "error", "check": "No Math.random() calls",                    "regex": "Math\\.random\\(\\)" }
    ],
    "warningGates": [
      { "id": "async-readiness-fonts",  "severity": "warning", "check": "document.fonts.ready used before timeline registration (recommended)" },
      { "id": "async-readiness-promise","severity": "warning", "check": "Promise.all for loading fonts/WebGL/assets before timeline (recommended for complex compositions)" },
      { "id": "no-stale-beat-path",     "severity": "warning", "check": "Verify beat(n) calls reference valid indices within __beats length — index beyond array produces NaN timing" },
      { "id": "has-beat-helper",        "severity": "warning", "check": "function beat helper present for beat-to-seconds conversion" },
      { "id": "beat-array-present",     "severity": "warning", "check": "var __beats timestamp array present for rhythm sync data" }
    ],
    "automatedChecker": "bash /Users/zhichao/.claude/skills/hyper-animator/scripts/validate-quality.sh <html-file> <generation-mode>"
  }
}
