{
  "kind": "motion-grammar",
  "version": "2.0.0",
  "project": {
    "name": "Motion Lexicon",
    "releaseVersion": "2.0.0",
    "siteUrl": "https://motion-lexicon.pages.dev",
    "repositoryUrl": "https://github.com/Ryan-yang125/motion-lexicon",
    "skillCommand": "npx skills add Ryan-yang125/motion-lexicon --skill motion-lexicon"
  },
  "urls": {
    "zh": "https://motion-lexicon.pages.dev/zh/director/",
    "en": "https://motion-lexicon.pages.dev/en/director/"
  },
  "blueprintSchema": "https://motion-lexicon.pages.dev/data/v2/motion-blueprint.schema.json",
  "grammar": {
    "version": "2.0.0",
    "name": "Motion Grammar",
    "promise": {
      "zh": "让每个产品变化都有清楚的起点、过程和结果，并保持产品界面的克制感。",
      "en": "Give every product change a clear start, process, and outcome while preserving a calm interface."
    },
    "collections": {
      "primitives": {
        "count": 44,
        "title": {
          "zh": "动效基础",
          "en": "Motion Primitives"
        },
        "purpose": {
          "zh": "构成动作的底层语言。",
          "en": "The foundational language used to build motion."
        }
      },
      "moments": {
        "count": 28,
        "title": {
          "zh": "产品瞬间",
          "en": "Product Moments"
        },
        "purpose": {
          "zh": "把多个基础动作编排成真实的产品交互。",
          "en": "Composed interactions built from several motion primitives."
        }
      }
    },
    "material": {
      "bezel": {
        "zh": "页面基底承接环境与留白。",
        "en": "The page bezel carries environment and breathing room."
      },
      "panel": {
        "zh": "抬升面板承接当前任务和可操作内容。",
        "en": "A raised panel carries the active task and actionable content."
      },
      "well": {
        "zh": "内凹区域承接输入、预览、代码和局部状态。",
        "en": "A recessed well carries input, preview, code, and local state."
      },
      "rule": {
        "zh": "使用材质关系表达层级，让边框只负责必要的分隔。",
        "en": "Use material relationships to express hierarchy and reserve borders for essential separation."
      }
    },
    "timing": {
      "arrive": {
        "curve": "cubic-bezier(0.23, 1, 0.32, 1)",
        "rangeMs": [
          180,
          280
        ],
        "guidance": {
          "zh": "内容抵达时保持短促、方向明确的位移与淡入。",
          "en": "Arriving content uses short, directional travel with an opacity cue."
        }
      },
      "leave": {
        "curve": "cubic-bezier(0.4, 0, 1, 1)",
        "rangeMs": [
          110,
          180
        ],
        "guidance": {
          "zh": "离场节奏略快，让焦点尽快回到下一状态。",
          "en": "Leaving motion resolves slightly faster so focus returns to the next state quickly."
        }
      },
      "feedback": {
        "rangeMs": [
          100,
          160
        ],
        "guidance": {
          "zh": "按压、选择和数值确认保持紧凑，服务于输入反馈。",
          "en": "Press, selection, and value confirmation stay compact and serve input feedback."
        }
      },
      "linear": {
        "curve": "linear",
        "rangeMs": [
          160,
          600
        ],
        "guidance": {
          "zh": "进度与连续数值变化使用匀速节奏，避免伪造完成感。",
          "en": "Progress and continuous value changes use a linear rhythm without implying a result that has not arrived."
        }
      },
      "spring": {
        "curve": "cubic-bezier(0.34, 1.28, 0.64, 1)",
        "rangeMs": [
          180,
          320
        ],
        "guidance": {
          "zh": "弹性只服务于直接操控后的落点确认，避免用于普通状态提示。",
          "en": "Spring motion is reserved for settling after direct manipulation, keeping routine state feedback restrained."
        }
      }
    },
    "invariants": [
      {
        "zh": "每个状态都预留空间，内容变化不推挤相邻界面。",
        "en": "Every state reserves space so a change does not shove adjacent UI."
      },
      {
        "zh": "动效由用户事件或真实系统进度触发。",
        "en": "Motion is triggered by a user event or real system progress."
      },
      {
        "zh": "每一段交互都允许中断、重复触发或恢复。",
        "en": "Every interaction can be interrupted, repeated, or recovered."
      },
      {
        "zh": "减弱动效保留状态信息与操作路径。",
        "en": "Reduced motion preserves state information and the action path."
      },
      {
        "zh": "键盘、指针和触摸获得同等的状态反馈。",
        "en": "Keyboard, pointer, and touch receive equivalent state feedback."
      },
      {
        "zh": "优先使用 transform 与 opacity，避免布局属性参与关键帧。",
        "en": "Prefer transform and opacity, keeping layout properties out of keyframes."
      }
    ],
    "composition": {
      "primaryActorLimit": 1,
      "auxiliaryActorLimit": 2,
      "stages": [
        "brief",
        "state graph",
        "actors",
        "beats",
        "accessibility",
        "delivery",
        "provenance"
      ],
      "rule": {
        "zh": "一个瞬间聚焦一个主要视觉角色，辅助角色只负责建立因果和空间关系。",
        "en": "One moment focuses on one primary visual actor; auxiliary actors establish cause and spatial context."
      }
    },
    "implementation": {
      "preferredDelivery": [
        "html",
        "css",
        "js"
      ],
      "rule": {
        "zh": "用语义 HTML、局部 CSS 和少量 JavaScript 交付；代码与状态图保持同源。",
        "en": "Deliver with semantic HTML, local CSS, and small JavaScript; keep the code aligned with the state graph."
      }
    }
  },
  "modes": [
    {
      "id": "recommend",
      "title": {
        "zh": "推荐",
        "en": "Recommend"
      },
      "description": {
        "zh": "把一句产品需求收敛为一组有理由的动效候选。",
        "en": "Turn a product brief into a reasoned set of motion candidates."
      },
      "deliverable": {
        "zh": "候选、适用场景与取舍",
        "en": "Candidates, fit, and tradeoffs"
      }
    },
    {
      "id": "compose",
      "title": {
        "zh": "编排",
        "en": "Compose"
      },
      "description": {
        "zh": "用状态图、角色和节拍组织一段完整产品瞬间。",
        "en": "Use states, actors, and beats to organise one complete product moment."
      },
      "deliverable": {
        "zh": "Motion Blueprint",
        "en": "Motion Blueprint"
      }
    },
    {
      "id": "implement",
      "title": {
        "zh": "实现",
        "en": "Implement"
      },
      "description": {
        "zh": "产出贴合现有界面的 HTML、CSS 和必要的交互 JavaScript。",
        "en": "Produce HTML, CSS, and the small amount of interaction JavaScript that fits the interface."
      },
      "deliverable": {
        "zh": "可接入实现",
        "en": "Integration-ready implementation"
      }
    },
    {
      "id": "review",
      "title": {
        "zh": "评审",
        "en": "Review"
      },
      "description": {
        "zh": "检查状态含义、节奏、可中断性、性能和减弱动效。",
        "en": "Check state meaning, timing, interruption, performance, and reduced motion."
      },
      "deliverable": {
        "zh": "按优先级排序的修改清单",
        "en": "Prioritised revision list"
      }
    },
    {
      "id": "contribute",
      "title": {
        "zh": "贡献",
        "en": "Contribute"
      },
      "description": {
        "zh": "把成熟方案整理为可验证候选，进入公开内容的审核流程。",
        "en": "Turn a mature solution into a verifiable candidate for the public-content review flow."
      },
      "deliverable": {
        "zh": "候选规范与验证记录",
        "en": "Candidate specification and validation record"
      }
    }
  ],
  "examples": [
    {
      "version": "2.0",
      "locale": "en",
      "intent": {
        "productGoal": "Publish a completed update",
        "userIntent": "Confirm that the request was received and show each approver's next state.",
        "feeling": "Clear, grounded confirmation"
      },
      "scope": {
        "surface": "Release-note approval panel",
        "framework": "HTML, CSS, and JavaScript",
        "input": [
          "pointer",
          "keyboard",
          "touch"
        ]
      },
      "stateGraph": {
        "initial": "ready",
        "states": [
          {
            "id": "ready",
            "label": "Ready",
            "role": "initial"
          },
          {
            "id": "sending",
            "label": "Sending",
            "role": "pending"
          },
          {
            "id": "awaiting",
            "label": "Awaiting response",
            "role": "success"
          },
          {
            "id": "failed",
            "label": "Retry available",
            "role": "failure"
          }
        ],
        "transitions": [
          {
            "event": "SEND",
            "from": "ready",
            "to": "sending",
            "interrupt": "settle"
          },
          {
            "event": "RESOLVE",
            "from": "sending",
            "to": "awaiting",
            "interrupt": "settle"
          },
          {
            "event": "REJECT",
            "from": "sending",
            "to": "failed",
            "interrupt": "settle"
          },
          {
            "event": "RETRY",
            "from": "failed",
            "to": "sending",
            "interrupt": "replace"
          }
        ]
      },
      "actors": [
        {
          "id": "send",
          "role": "primary",
          "kind": "trigger",
          "element": "Send request button"
        },
        {
          "id": "summary",
          "role": "supporting",
          "kind": "status",
          "element": "Approval summary"
        },
        {
          "id": "approvers",
          "role": "supporting",
          "kind": "record",
          "element": "Approver records"
        }
      ],
      "beats": [
        {
          "id": "acknowledge-send",
          "at": 0,
          "actor": "send",
          "purpose": "confirm",
          "primitive": "press-tap-feedback",
          "from": "Available",
          "to": "Sending",
          "durationMs": 140,
          "easing": "feedback",
          "properties": [
            "transform",
            "color"
          ]
        },
        {
          "id": "confirm-summary",
          "at": 150,
          "actor": "summary",
          "purpose": "confirm",
          "primitive": "crossfade",
          "from": "Draft",
          "to": "Sent · 2 approvers",
          "durationMs": 180,
          "easing": "arrive",
          "properties": [
            "opacity",
            "color"
          ]
        },
        {
          "id": "reveal-approvers",
          "at": 190,
          "actor": "approvers",
          "purpose": "reveal",
          "primitive": "stagger",
          "from": "Ready",
          "to": "Awaiting response",
          "durationMs": 220,
          "easing": "arrive",
          "properties": [
            "transform",
            "opacity"
          ]
        }
      ],
      "accessibility": {
        "reducedMotion": "Switch the action, summary, and approver states directly without travel.",
        "focus": "Keep focus on Send until the request resolves; expose Retry on failure.",
        "aria": "Announce the approval summary with polite priority.",
        "keyboard": "Enter and Space trigger Send; Escape preserves the current settled state."
      },
      "delivery": {
        "formats": [
          "html",
          "css",
          "js"
        ],
        "integration": "Drive data-state from the real request lifecycle and keep each visual result in the existing layout slot."
      },
      "provenance": {
        "status": "published",
        "foundations": [
          "press-tap-feedback",
          "fade-in-fade-out",
          "crossfade",
          "stagger"
        ],
        "moments": [
          "approval-request"
        ],
        "confidence": "high",
        "evidence": "Published Product Moment with a stable preview and reduced-motion treatment."
      }
    }
  ]
}
