claude-code-workflow 7.2.27 → 7.2.28
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/.ccw/specs/architecture-constraints.md +5 -0
- package/.claude/skills/_shared/SKILL-DESIGN-SPEC.md +140 -0
- package/.claude/skills/investigate/SKILL.md +110 -0
- package/.claude/skills/investigate/phases/01-root-cause-investigation.md +132 -0
- package/.claude/skills/investigate/phases/02-pattern-analysis.md +126 -0
- package/.claude/skills/investigate/phases/03-hypothesis-testing.md +177 -0
- package/.claude/skills/investigate/phases/04-implementation.md +139 -0
- package/.claude/skills/investigate/phases/05-verification-report.md +153 -0
- package/.claude/skills/investigate/specs/debug-report-format.md +226 -0
- package/.claude/skills/investigate/specs/iron-law.md +101 -0
- package/.claude/skills/security-audit/SKILL.md +125 -0
- package/.claude/skills/security-audit/phases/01-supply-chain-scan.md +139 -0
- package/.claude/skills/security-audit/phases/02-owasp-review.md +156 -0
- package/.claude/skills/security-audit/phases/03-threat-modeling.md +180 -0
- package/.claude/skills/security-audit/phases/04-report-tracking.md +177 -0
- package/.claude/skills/security-audit/specs/owasp-checklist.md +442 -0
- package/.claude/skills/security-audit/specs/scoring-gates.md +141 -0
- package/.claude/skills/ship/SKILL.md +105 -0
- package/.claude/skills/ship/phases/01-preflight-checks.md +121 -0
- package/.claude/skills/ship/phases/02-code-review.md +137 -0
- package/.claude/skills/ship/phases/03-version-bump.md +171 -0
- package/.claude/skills/ship/phases/04-changelog-commit.md +167 -0
- package/.claude/skills/ship/phases/05-pr-creation.md +163 -0
- package/.claude/skills/skill-generator/templates/sequential-phase.md +10 -0
- package/.claude/skills/skill-generator/templates/skill-md.md +4 -0
- package/.claude/skills/team-interactive-craft/SKILL.md +127 -0
- package/.claude/skills/team-interactive-craft/roles/a11y-tester/role.md +159 -0
- package/.claude/skills/team-interactive-craft/roles/builder/role.md +216 -0
- package/.claude/skills/team-interactive-craft/roles/coordinator/commands/analyze.md +71 -0
- package/.claude/skills/team-interactive-craft/roles/coordinator/commands/dispatch.md +192 -0
- package/.claude/skills/team-interactive-craft/roles/coordinator/commands/monitor.md +183 -0
- package/.claude/skills/team-interactive-craft/roles/coordinator/role.md +166 -0
- package/.claude/skills/team-interactive-craft/roles/interaction-designer/role.md +144 -0
- package/.claude/skills/team-interactive-craft/roles/researcher/role.md +131 -0
- package/.claude/skills/team-interactive-craft/specs/interaction-patterns.md +362 -0
- package/.claude/skills/team-interactive-craft/specs/pipelines.md +85 -0
- package/.claude/skills/team-interactive-craft/specs/team-config.json +105 -0
- package/.claude/skills/team-interactive-craft/specs/vanilla-constraints.md +83 -0
- package/.claude/skills/team-motion-design/SKILL.md +129 -0
- package/.claude/skills/team-motion-design/roles/animator/role.md +194 -0
- package/.claude/skills/team-motion-design/roles/choreographer/role.md +164 -0
- package/.claude/skills/team-motion-design/roles/coordinator/commands/analyze.md +64 -0
- package/.claude/skills/team-motion-design/roles/coordinator/commands/dispatch.md +203 -0
- package/.claude/skills/team-motion-design/roles/coordinator/commands/monitor.md +184 -0
- package/.claude/skills/team-motion-design/roles/coordinator/role.md +167 -0
- package/.claude/skills/team-motion-design/roles/motion-researcher/role.md +115 -0
- package/.claude/skills/team-motion-design/roles/motion-tester/role.md +175 -0
- package/.claude/skills/team-motion-design/specs/gpu-constraints.md +114 -0
- package/.claude/skills/team-motion-design/specs/motion-tokens.md +128 -0
- package/.claude/skills/team-motion-design/specs/pipelines.md +74 -0
- package/.claude/skills/team-motion-design/specs/reduced-motion.md +129 -0
- package/.claude/skills/team-motion-design/specs/team-config.json +99 -0
- package/.claude/skills/team-ui-polish/SKILL.md +127 -0
- package/.claude/skills/team-ui-polish/roles/coordinator/commands/analyze.md +77 -0
- package/.claude/skills/team-ui-polish/roles/coordinator/commands/dispatch.md +194 -0
- package/.claude/skills/team-ui-polish/roles/coordinator/commands/monitor.md +180 -0
- package/.claude/skills/team-ui-polish/roles/coordinator/role.md +170 -0
- package/.claude/skills/team-ui-polish/roles/diagnostician/role.md +160 -0
- package/.claude/skills/team-ui-polish/roles/optimizer/role.md +225 -0
- package/.claude/skills/team-ui-polish/roles/scanner/role.md +356 -0
- package/.claude/skills/team-ui-polish/roles/verifier/role.md +142 -0
- package/.claude/skills/team-ui-polish/specs/anti-patterns.md +141 -0
- package/.claude/skills/team-ui-polish/specs/design-standards.md +356 -0
- package/.claude/skills/team-ui-polish/specs/fix-strategies.md +235 -0
- package/.claude/skills/team-ui-polish/specs/pipelines.md +81 -0
- package/.claude/skills/team-ui-polish/specs/scoring-guide.md +162 -0
- package/.claude/skills/team-ui-polish/specs/team-config.json +73 -0
- package/.claude/skills/team-uidesign/SKILL.md +6 -1
- package/.claude/skills/team-uidesign/roles/designer/role.md +28 -4
- package/.claude/skills/team-uidesign/roles/implementer/role.md +25 -3
- package/.claude/skills/team-uidesign/roles/researcher/role.md +21 -2
- package/.claude/skills/team-uidesign/roles/reviewer/role.md +19 -17
- package/.claude/skills/team-uidesign/specs/anti-patterns.md +211 -0
- package/.claude/skills/team-uidesign/specs/design-standards.md +329 -0
- package/.claude/skills/team-uidesign/specs/scoring-guide.md +114 -0
- package/.claude/skills/team-uidesign/specs/team-config.json +1 -1
- package/.claude/skills/team-uidesign/specs/ux-writing.md +86 -0
- package/.claude/skills/team-ux-improve/SKILL.md +3 -0
- package/.claude/skills/team-ux-improve/roles/designer/role.md +30 -0
- package/.claude/skills/team-ux-improve/roles/diagnoser/role.md +16 -1
- package/.claude/skills/team-ux-improve/roles/scanner/role.md +43 -1
- package/.claude/skills/team-ux-improve/specs/anti-patterns.md +103 -0
- package/.claude/skills/team-ux-improve/specs/design-standards.md +54 -0
- package/.claude/skills/team-ux-improve/specs/heuristics.md +88 -0
- package/.claude/skills/team-ux-improve/wisdom/anti-patterns/common-ux-pitfalls.md +40 -8
- package/.claude/skills/team-ux-improve/wisdom/patterns/state-management.md +32 -12
- package/.claude/skills/team-ux-improve/wisdom/patterns/ui-feedback.md +35 -11
- package/.claude/skills/team-ux-improve/wisdom/principles/general-ux.md +36 -9
- package/.claude/skills/team-visual-a11y/SKILL.md +143 -0
- package/.claude/skills/team-visual-a11y/roles/color-auditor/role.md +178 -0
- package/.claude/skills/team-visual-a11y/roles/coordinator/commands/analyze.md +72 -0
- package/.claude/skills/team-visual-a11y/roles/coordinator/commands/dispatch.md +250 -0
- package/.claude/skills/team-visual-a11y/roles/coordinator/commands/monitor.md +204 -0
- package/.claude/skills/team-visual-a11y/roles/coordinator/role.md +169 -0
- package/.claude/skills/team-visual-a11y/roles/fix-implementer/role.md +246 -0
- package/.claude/skills/team-visual-a11y/roles/focus-auditor/role.md +222 -0
- package/.claude/skills/team-visual-a11y/roles/remediation-planner/role.md +206 -0
- package/.claude/skills/team-visual-a11y/roles/typo-auditor/role.md +185 -0
- package/.claude/skills/team-visual-a11y/specs/focus-patterns.md +325 -0
- package/.claude/skills/team-visual-a11y/specs/oklch-standards.md +130 -0
- package/.claude/skills/team-visual-a11y/specs/pipelines.md +98 -0
- package/.claude/skills/team-visual-a11y/specs/team-config.json +109 -0
- package/.claude/skills/team-visual-a11y/specs/typography-scale.md +165 -0
- package/.claude/skills/team-visual-a11y/specs/wcag-matrix.md +133 -0
- package/.codex/skills/investigate/agents/investigator.md +392 -0
- package/.codex/skills/investigate/orchestrator.md +362 -0
- package/.codex/skills/investigate/phases/01-root-cause-investigation.md +212 -0
- package/.codex/skills/investigate/phases/02-pattern-analysis.md +181 -0
- package/.codex/skills/investigate/phases/03-hypothesis-testing.md +214 -0
- package/.codex/skills/investigate/phases/04-implementation.md +195 -0
- package/.codex/skills/investigate/phases/05-verification-report.md +240 -0
- package/.codex/skills/security-audit/agents/security-auditor.md +341 -0
- package/.codex/skills/security-audit/orchestrator.md +384 -0
- package/.codex/skills/security-audit/phases/01-supply-chain-scan.md +226 -0
- package/.codex/skills/security-audit/phases/02-owasp-review.md +232 -0
- package/.codex/skills/security-audit/phases/03-threat-modeling.md +249 -0
- package/.codex/skills/security-audit/phases/04-report-tracking.md +300 -0
- package/.codex/skills/ship/agents/ship-operator.md +318 -0
- package/.codex/skills/ship/orchestrator.md +426 -0
- package/.codex/skills/ship/phases/01-preflight-checks.md +198 -0
- package/.codex/skills/ship/phases/02-code-review.md +228 -0
- package/.codex/skills/ship/phases/03-version-bump.md +259 -0
- package/.codex/skills/ship/phases/04-changelog-commit.md +263 -0
- package/.codex/skills/ship/phases/05-pr-creation.md +280 -0
- package/.codex/skills/team-interactive-craft/SKILL.md +220 -0
- package/.codex/skills/team-interactive-craft/roles/a11y-tester/role.md +159 -0
- package/.codex/skills/team-interactive-craft/roles/builder/role.md +216 -0
- package/.codex/skills/team-interactive-craft/roles/coordinator/commands/analyze.md +71 -0
- package/.codex/skills/team-interactive-craft/roles/coordinator/commands/dispatch.md +162 -0
- package/.codex/skills/team-interactive-craft/roles/coordinator/commands/monitor.md +233 -0
- package/.codex/skills/team-interactive-craft/roles/coordinator/role.md +209 -0
- package/.codex/skills/team-interactive-craft/roles/interaction-designer/role.md +144 -0
- package/.codex/skills/team-interactive-craft/roles/researcher/role.md +131 -0
- package/.codex/skills/team-interactive-craft/specs/interaction-patterns.md +362 -0
- package/.codex/skills/team-interactive-craft/specs/pipelines.md +85 -0
- package/.codex/skills/team-interactive-craft/specs/team-config.json +105 -0
- package/.codex/skills/team-interactive-craft/specs/vanilla-constraints.md +83 -0
- package/.codex/skills/team-motion-design/SKILL.md +222 -0
- package/.codex/skills/team-motion-design/roles/animator/role.md +194 -0
- package/.codex/skills/team-motion-design/roles/choreographer/role.md +164 -0
- package/.codex/skills/team-motion-design/roles/coordinator/commands/analyze.md +64 -0
- package/.codex/skills/team-motion-design/roles/coordinator/commands/dispatch.md +168 -0
- package/.codex/skills/team-motion-design/roles/coordinator/commands/monitor.md +242 -0
- package/.codex/skills/team-motion-design/roles/coordinator/role.md +210 -0
- package/.codex/skills/team-motion-design/roles/motion-researcher/role.md +115 -0
- package/.codex/skills/team-motion-design/roles/motion-tester/role.md +175 -0
- package/.codex/skills/team-motion-design/specs/gpu-constraints.md +114 -0
- package/.codex/skills/team-motion-design/specs/motion-tokens.md +128 -0
- package/.codex/skills/team-motion-design/specs/pipelines.md +74 -0
- package/.codex/skills/team-motion-design/specs/reduced-motion.md +129 -0
- package/.codex/skills/team-motion-design/specs/team-config.json +99 -0
- package/.codex/skills/team-ui-polish/SKILL.md +218 -0
- package/.codex/skills/team-ui-polish/roles/coordinator/commands/analyze.md +77 -0
- package/.codex/skills/team-ui-polish/roles/coordinator/commands/dispatch.md +167 -0
- package/.codex/skills/team-ui-polish/roles/coordinator/commands/monitor.md +230 -0
- package/.codex/skills/team-ui-polish/roles/coordinator/role.md +213 -0
- package/.codex/skills/team-ui-polish/roles/diagnostician/role.md +164 -0
- package/.codex/skills/team-ui-polish/roles/optimizer/role.md +229 -0
- package/.codex/skills/team-ui-polish/roles/scanner/role.md +360 -0
- package/.codex/skills/team-ui-polish/roles/verifier/role.md +142 -0
- package/.codex/skills/team-ui-polish/specs/anti-patterns.md +141 -0
- package/.codex/skills/team-ui-polish/specs/design-standards.md +356 -0
- package/.codex/skills/team-ui-polish/specs/fix-strategies.md +235 -0
- package/.codex/skills/team-ui-polish/specs/pipelines.md +81 -0
- package/.codex/skills/team-ui-polish/specs/scoring-guide.md +162 -0
- package/.codex/skills/team-ui-polish/specs/team-config.json +73 -0
- package/.codex/skills/team-visual-a11y/SKILL.md +319 -0
- package/.codex/skills/team-visual-a11y/roles/color-auditor/role.md +178 -0
- package/.codex/skills/team-visual-a11y/roles/coordinator/commands/analyze.md +72 -0
- package/.codex/skills/team-visual-a11y/roles/coordinator/commands/dispatch.md +188 -0
- package/.codex/skills/team-visual-a11y/roles/coordinator/commands/monitor.md +281 -0
- package/.codex/skills/team-visual-a11y/roles/coordinator/role.md +213 -0
- package/.codex/skills/team-visual-a11y/roles/fix-implementer/role.md +246 -0
- package/.codex/skills/team-visual-a11y/roles/focus-auditor/role.md +222 -0
- package/.codex/skills/team-visual-a11y/roles/remediation-planner/role.md +206 -0
- package/.codex/skills/team-visual-a11y/roles/typo-auditor/role.md +185 -0
- package/.codex/skills/team-visual-a11y/specs/focus-patterns.md +325 -0
- package/.codex/skills/team-visual-a11y/specs/oklch-standards.md +130 -0
- package/.codex/skills/team-visual-a11y/specs/pipelines.md +98 -0
- package/.codex/skills/team-visual-a11y/specs/team-config.json +109 -0
- package/.codex/skills/team-visual-a11y/specs/typography-scale.md +165 -0
- package/.codex/skills/team-visual-a11y/specs/wcag-matrix.md +133 -0
- package/README.md +8 -0
- package/ccw/dist/core/hooks/hook-templates.d.ts.map +1 -1
- package/ccw/dist/core/hooks/hook-templates.js +114 -1
- package/ccw/dist/core/hooks/hook-templates.js.map +1 -1
- package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/cli-routes.js +34 -0
- package/ccw/dist/core/routes/cli-routes.js.map +1 -1
- package/ccw/dist/core/routes/system-routes.js +2 -2
- package/ccw/dist/core/routes/system-routes.js.map +1 -1
- package/ccw/frontend/dist/assets/{AlertDialog-Bf1jdqax.js → AlertDialog-BjP1ydDR.js} +2 -2
- package/ccw/frontend/dist/assets/{AlertDialog-Bf1jdqax.js.map → AlertDialog-BjP1ydDR.js.map} +1 -1
- package/ccw/frontend/dist/assets/{AnalysisPage-C8niKdp4.js → AnalysisPage-CAX3xqMf.js} +2 -2
- package/ccw/frontend/dist/assets/{AnalysisPage-C8niKdp4.js.map → AnalysisPage-CAX3xqMf.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ApiSettingsPage-BL2c3UNS.js → ApiSettingsPage-CtWlmztq.js} +2 -2
- package/ccw/frontend/dist/assets/{ApiSettingsPage-BL2c3UNS.js.map → ApiSettingsPage-CtWlmztq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliModeToggle-BePBFynD.js → CliModeToggle-hR4a-eLX.js} +2 -2
- package/ccw/frontend/dist/assets/{CliModeToggle-BePBFynD.js.map → CliModeToggle-hR4a-eLX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliSessionSharePage-7cYtX6FT.js → CliSessionSharePage-DzNPkFN9.js} +2 -2
- package/ccw/frontend/dist/assets/{CliSessionSharePage-7cYtX6FT.js.map → CliSessionSharePage-DzNPkFN9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliViewerPage-CBwg1mPL.js → CliViewerPage-BPEGN4TT.js} +2 -2
- package/ccw/frontend/dist/assets/{CliViewerPage-CBwg1mPL.js.map → CliViewerPage-BPEGN4TT.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CodexLensPage-Bt74xORP.js → CodexLensPage-Cf0r2RHY.js} +2 -2
- package/ccw/frontend/dist/assets/{CodexLensPage-Bt74xORP.js.map → CodexLensPage-Cf0r2RHY.js.map} +1 -1
- package/ccw/frontend/dist/assets/{Collapsible-Wrs87QT7.js → Collapsible-DEm1rJ4h.js} +2 -2
- package/ccw/frontend/dist/assets/{Collapsible-Wrs87QT7.js.map → Collapsible-DEm1rJ4h.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CommandsManagerPage-ChQjmPWZ.js → CommandsManagerPage-BpeWw8HO.js} +2 -2
- package/ccw/frontend/dist/assets/{CommandsManagerPage-ChQjmPWZ.js.map → CommandsManagerPage-BpeWw8HO.js.map} +1 -1
- package/ccw/frontend/dist/assets/{DeepWikiPage-dEO5wi6X.js → DeepWikiPage-BEsmh2vF.js} +2 -2
- package/ccw/frontend/dist/assets/{DeepWikiPage-dEO5wi6X.js.map → DeepWikiPage-BEsmh2vF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{EndpointsPage-4zq269xY.js → EndpointsPage-B30SFdtU.js} +2 -2
- package/ccw/frontend/dist/assets/{EndpointsPage-4zq269xY.js.map → EndpointsPage-B30SFdtU.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ExplorerPage-B0YTENhA.js → ExplorerPage-BVvMpg1O.js} +2 -2
- package/ccw/frontend/dist/assets/{ExplorerPage-B0YTENhA.js.map → ExplorerPage-BVvMpg1O.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FixSessionPage-CwGs6dhz.js → FixSessionPage-CL73dHbh.js} +2 -2
- package/ccw/frontend/dist/assets/{FixSessionPage-CwGs6dhz.js.map → FixSessionPage-CL73dHbh.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-COZRBslc.js → FloatingFileBrowser-BL-28lMZ.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-COZRBslc.js.map → FloatingFileBrowser-BL-28lMZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingPanel-DYvgQZRD.js → FloatingPanel-BzZDciHZ.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingPanel-DYvgQZRD.js.map → FloatingPanel-BzZDciHZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{GraphExplorerPage-ewMHQGem.js → GraphExplorerPage-CDp6-d8P.js} +2 -2
- package/ccw/frontend/dist/assets/{GraphExplorerPage-ewMHQGem.js.map → GraphExplorerPage-CDp6-d8P.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HistoryPage-BMeR0PrK.js → HistoryPage-fZY_7O9n.js} +2 -2
- package/ccw/frontend/dist/assets/{HistoryPage-BMeR0PrK.js.map → HistoryPage-fZY_7O9n.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HookManagerPage-DBW2LnRm.js → HookManagerPage-4LJeC9bq.js} +2 -2
- package/ccw/frontend/dist/assets/{HookManagerPage-DBW2LnRm.js.map → HookManagerPage-4LJeC9bq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{InstallationsPage--pMj0QEH.js → InstallationsPage-Bpigrbhw.js} +2 -2
- package/ccw/frontend/dist/assets/{InstallationsPage--pMj0QEH.js.map → InstallationsPage-Bpigrbhw.js.map} +1 -1
- package/ccw/frontend/dist/assets/{IssueHubPage-C_QMpQSR.js → IssueHubPage-BP0zJc1R.js} +2 -2
- package/ccw/frontend/dist/assets/{IssueHubPage-C_QMpQSR.js.map → IssueHubPage-BP0zJc1R.js.map} +1 -1
- package/ccw/frontend/dist/assets/{LiteTasksPage-CSWFdQ2-.js → LiteTasksPage-CSt2oVKQ.js} +2 -2
- package/ccw/frontend/dist/assets/{LiteTasksPage-CSWFdQ2-.js.map → LiteTasksPage-CSt2oVKQ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{McpManagerPage-Dvv8NtGy.js → McpManagerPage-B-xaMA0w.js} +2 -2
- package/ccw/frontend/dist/assets/{McpManagerPage-Dvv8NtGy.js.map → McpManagerPage-B-xaMA0w.js.map} +1 -1
- package/ccw/frontend/dist/assets/{MemoryPage-YO8WZzZO.js → MemoryPage-CJqo_7DY.js} +2 -2
- package/ccw/frontend/dist/assets/{MemoryPage-YO8WZzZO.js.map → MemoryPage-CJqo_7DY.js.map} +1 -1
- package/ccw/frontend/dist/assets/{NotFoundPage-quUJw0CD.js → NotFoundPage-ibZeQA-Y.js} +2 -2
- package/ccw/frontend/dist/assets/{NotFoundPage-quUJw0CD.js.map → NotFoundPage-ibZeQA-Y.js.map} +1 -1
- package/ccw/frontend/dist/assets/{OrchestratorPage-tuThWPID.js → OrchestratorPage-DgJ4ctPQ.js} +2 -2
- package/ccw/frontend/dist/assets/{OrchestratorPage-tuThWPID.js.map → OrchestratorPage-DgJ4ctPQ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-shTilwiT.js → ProjectOverviewPage-Cit0Yq0D.js} +2 -2
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-shTilwiT.js.map → ProjectOverviewPage-Cit0Yq0D.js.map} +1 -1
- package/ccw/frontend/dist/assets/{PromptHistoryPage-6rQnsI8l.js → PromptHistoryPage-Ce1HDIK0.js} +2 -2
- package/ccw/frontend/dist/assets/{PromptHistoryPage-6rQnsI8l.js.map → PromptHistoryPage-Ce1HDIK0.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ReviewSessionPage-JOmzjVbT.js → ReviewSessionPage-J1KikNrk.js} +2 -2
- package/ccw/frontend/dist/assets/{ReviewSessionPage-JOmzjVbT.js.map → ReviewSessionPage-J1KikNrk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{RulesManagerPage-Cayfywqi.js → RulesManagerPage-CdBjTmth.js} +2 -2
- package/ccw/frontend/dist/assets/{RulesManagerPage-Cayfywqi.js.map → RulesManagerPage-CdBjTmth.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionDetailPage-iMn0k84i.js → SessionDetailPage-B9ZK7LvX.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionDetailPage-iMn0k84i.js.map → SessionDetailPage-B9ZK7LvX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionsPage-Ciqjy9kz.js → SessionsPage-CW_nS5UR.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionsPage-Ciqjy9kz.js.map → SessionsPage-CW_nS5UR.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SettingsPage-BPDbXPSM.js → SettingsPage-B2PYzSoO.js} +35 -35
- package/ccw/frontend/dist/assets/SettingsPage-B2PYzSoO.js.map +1 -0
- package/ccw/frontend/dist/assets/{SkillsManagerPage-D3LzbpJY.js → SkillsManagerPage-CTnWrrwp.js} +2 -2
- package/ccw/frontend/dist/assets/{SkillsManagerPage-D3LzbpJY.js.map → SkillsManagerPage-CTnWrrwp.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-BpkJctzo.js → SpecsSettingsPage-DJpi9XQL.js} +2 -2
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-BpkJctzo.js.map → SpecsSettingsPage-DJpi9XQL.js.map} +1 -1
- package/ccw/frontend/dist/assets/{Switch-BpB9h__9.js → Switch-Ac6Ov7uy.js} +2 -2
- package/ccw/frontend/dist/assets/{Switch-BpB9h__9.js.map → Switch-Ac6Ov7uy.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TabsNavigation-BGsKy7DO.js → TabsNavigation-DZAAspqR.js} +2 -2
- package/ccw/frontend/dist/assets/{TabsNavigation-BGsKy7DO.js.map → TabsNavigation-DZAAspqR.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TaskDrawer-bYIlbM0Q.js → TaskDrawer-BJkwfhIZ.js} +2 -2
- package/ccw/frontend/dist/assets/{TaskDrawer-bYIlbM0Q.js.map → TaskDrawer-BJkwfhIZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TeamPage-CihtQ6LQ.js → TeamPage-BJgjxBgb.js} +2 -2
- package/ccw/frontend/dist/assets/{TeamPage-CihtQ6LQ.js.map → TeamPage-BJgjxBgb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-BDnNF_ud.js → TerminalDashboardPage-D1WekoOy.js} +2 -2
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-BDnNF_ud.js.map → TerminalDashboardPage-D1WekoOy.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-CQJ86bQp.js → archive-DxemgIhF.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-CQJ86bQp.js.map → archive-DxemgIhF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-restore-BhTfDbPU.js → archive-restore-CjS83f1V.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-restore-BhTfDbPU.js.map → archive-restore-CjS83f1V.js.map} +1 -1
- package/ccw/frontend/dist/assets/{arrow-right-eUAZnT9C.js → arrow-right-B5PUcn8I.js} +2 -2
- package/ccw/frontend/dist/assets/{arrow-right-eUAZnT9C.js.map → arrow-right-B5PUcn8I.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bookmark-plus-ilF5-V-k.js → bookmark-plus-DCc9aPbb.js} +2 -2
- package/ccw/frontend/dist/assets/{bookmark-plus-ilF5-V-k.js.map → bookmark-plus-DCc9aPbb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bot-BLkaQscs.js → bot-DOwFtzak.js} +2 -2
- package/ccw/frontend/dist/assets/{bot-BLkaQscs.js.map → bot-DOwFtzak.js.map} +1 -1
- package/ccw/frontend/dist/assets/{braces-D9HdgsO6.js → braces-96qH3aFh.js} +2 -2
- package/ccw/frontend/dist/assets/{braces-D9HdgsO6.js.map → braces-96qH3aFh.js.map} +1 -1
- package/ccw/frontend/dist/assets/{circle-stop-C3ZF1okQ.js → circle-stop-CCxSuil1.js} +2 -2
- package/ccw/frontend/dist/assets/{circle-stop-C3ZF1okQ.js.map → circle-stop-CCxSuil1.js.map} +1 -1
- package/ccw/frontend/dist/assets/{cpu-B-QjaSjm.js → cpu-CZNSJFdq.js} +2 -2
- package/ccw/frontend/dist/assets/{cpu-B-QjaSjm.js.map → cpu-CZNSJFdq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ellipsis-vertical-CbNlw2gS.js → ellipsis-vertical-h8xtvw2_.js} +2 -2
- package/ccw/frontend/dist/assets/{ellipsis-vertical-CbNlw2gS.js.map → ellipsis-vertical-h8xtvw2_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-yAy69Cnn.js → eye-D3NY0bm6.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-yAy69Cnn.js.map → eye-D3NY0bm6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-off-D5uzLZyP.js → eye-off-Cy2vkc8p.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-off-D5uzLZyP.js.map → eye-off-Cy2vkc8p.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-json-rwo1NowL.js → file-json-Bzq3U1Mx.js} +2 -2
- package/ccw/frontend/dist/assets/{file-json-rwo1NowL.js.map → file-json-Bzq3U1Mx.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-text-DRkrjie9.js → file-text-DwuwPDPi.js} +2 -2
- package/ccw/frontend/dist/assets/{file-text-DRkrjie9.js.map → file-text-DwuwPDPi.js.map} +1 -1
- package/ccw/frontend/dist/assets/{filter-BOe-OTu1.js → filter-q9g-bknU.js} +2 -2
- package/ccw/frontend/dist/assets/{filter-BOe-OTu1.js.map → filter-q9g-bknU.js.map} +1 -1
- package/ccw/frontend/dist/assets/{folder-BaWZWn_r.js → folder-CL6vb42J.js} +2 -2
- package/ccw/frontend/dist/assets/{folder-BaWZWn_r.js.map → folder-CL6vb42J.js.map} +1 -1
- package/ccw/frontend/dist/assets/{gauge-kazFexTr.js → gauge-BkrcQBly.js} +2 -2
- package/ccw/frontend/dist/assets/{gauge-kazFexTr.js.map → gauge-BkrcQBly.js.map} +1 -1
- package/ccw/frontend/dist/assets/{globe-BuHeEjxd.js → globe-BQbwyNeV.js} +2 -2
- package/ccw/frontend/dist/assets/{globe-BuHeEjxd.js.map → globe-BQbwyNeV.js.map} +1 -1
- package/ccw/frontend/dist/assets/{grid-3x3-DbhuUu4V.js → grid-3x3-x5_7DrN7.js} +2 -2
- package/ccw/frontend/dist/assets/{grid-3x3-DbhuUu4V.js.map → grid-3x3-x5_7DrN7.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hard-drive-AoLGL0z4.js → hard-drive-DTyWXwzf.js} +2 -2
- package/ccw/frontend/dist/assets/{hard-drive-AoLGL0z4.js.map → hard-drive-DTyWXwzf.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hash-Dpo1exMB.js → hash-80O0kJO7.js} +2 -2
- package/ccw/frontend/dist/assets/{hash-Dpo1exMB.js.map → hash-80O0kJO7.js.map} +1 -1
- package/ccw/frontend/dist/assets/{history-ujQnmMC9.js → history-DDlN2Bwa.js} +2 -2
- package/ccw/frontend/dist/assets/{history-ujQnmMC9.js.map → history-DDlN2Bwa.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-CxzXz6o1.js → index-B9A3Hnrk.js} +2 -2
- package/ccw/frontend/dist/assets/{index-CxzXz6o1.js.map → index-B9A3Hnrk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-B76AGix5.js → index-Bs80iCX0.js} +2 -2
- package/ccw/frontend/dist/assets/{index-B76AGix5.js.map → index-Bs80iCX0.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-C_Yf5fZ4.js → index-mbeo62f8.js} +2 -2
- package/ccw/frontend/dist/assets/{index-C_Yf5fZ4.js.map → index-mbeo62f8.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-Dff4bg3u.js → index-rLgoBCfV.js} +3 -3
- package/ccw/frontend/dist/assets/{index-Dff4bg3u.js.map → index-rLgoBCfV.js.map} +1 -1
- package/ccw/frontend/dist/assets/{layout-grid-CBdE4K8h.js → layout-grid-C1niOWJx.js} +2 -2
- package/ccw/frontend/dist/assets/{layout-grid-CBdE4K8h.js.map → layout-grid-C1niOWJx.js.map} +1 -1
- package/ccw/frontend/dist/assets/{lightbulb-B9K6ZgRp.js → lightbulb-BTmI7SUg.js} +2 -2
- package/ccw/frontend/dist/assets/{lightbulb-B9K6ZgRp.js.map → lightbulb-BTmI7SUg.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-2-Oea4xHJl.js → link-2-CB9HKeuZ.js} +2 -2
- package/ccw/frontend/dist/assets/{link-2-Oea4xHJl.js.map → link-2-CB9HKeuZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-5yXdZBch.js → link-koEYiemK.js} +2 -2
- package/ccw/frontend/dist/assets/{link-5yXdZBch.js.map → link-koEYiemK.js.map} +1 -1
- package/ccw/frontend/dist/assets/{list-9lHhC_U_.js → list-v2_GaLdC.js} +2 -2
- package/ccw/frontend/dist/assets/{list-9lHhC_U_.js.map → list-v2_GaLdC.js.map} +1 -1
- package/ccw/frontend/dist/assets/{map-pin-B6Io5kmB.js → map-pin-BQNfAqG_.js} +2 -2
- package/ccw/frontend/dist/assets/{map-pin-B6Io5kmB.js.map → map-pin-BQNfAqG_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{messages-square-BT000aD3.js → messages-square-Dzq5LGg9.js} +2 -2
- package/ccw/frontend/dist/assets/{messages-square-BT000aD3.js.map → messages-square-Dzq5LGg9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{minimize-2-DO-zbT3a.js → minimize-2-CtkoJXcz.js} +2 -2
- package/ccw/frontend/dist/assets/{minimize-2-DO-zbT3a.js.map → minimize-2-CtkoJXcz.js.map} +1 -1
- package/ccw/frontend/dist/assets/{package-BjOw1ldU.js → package-CH3smL37.js} +2 -2
- package/ccw/frontend/dist/assets/{package-BjOw1ldU.js.map → package-CH3smL37.js.map} +1 -1
- package/ccw/frontend/dist/assets/{plug-9dAARpE1.js → plug-CZ0aL_yF.js} +2 -2
- package/ccw/frontend/dist/assets/{plug-9dAARpE1.js.map → plug-CZ0aL_yF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{power-K2S39x7f.js → power-F2A_J4l6.js} +2 -2
- package/ccw/frontend/dist/assets/{power-K2S39x7f.js.map → power-F2A_J4l6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{save-D9-CoT3x.js → save-Byxot0YU.js} +2 -2
- package/ccw/frontend/dist/assets/{save-D9-CoT3x.js.map → save-Byxot0YU.js.map} +1 -1
- package/ccw/frontend/dist/assets/{send-Bunw9NtC.js → send-JjqhUkpw.js} +2 -2
- package/ccw/frontend/dist/assets/{send-Bunw9NtC.js.map → send-JjqhUkpw.js.map} +1 -1
- package/ccw/frontend/dist/assets/{settings-2-osl4EXFf.js → settings-2--SuN9rAt.js} +2 -2
- package/ccw/frontend/dist/assets/{settings-2-osl4EXFf.js.map → settings-2--SuN9rAt.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-check-big-Dl5gYkjR.js → square-check-big-BbngGB2h.js} +2 -2
- package/ccw/frontend/dist/assets/{square-check-big-Dl5gYkjR.js.map → square-check-big-BbngGB2h.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-pen-Bue1chJR.js → square-pen-CgrHgZSl.js} +2 -2
- package/ccw/frontend/dist/assets/{square-pen-Bue1chJR.js.map → square-pen-CgrHgZSl.js.map} +1 -1
- package/ccw/frontend/dist/assets/{star-Bk7EC7FB.js → star-BU3TQr7Z.js} +2 -2
- package/ccw/frontend/dist/assets/{star-Bk7EC7FB.js.map → star-BU3TQr7Z.js.map} +1 -1
- package/ccw/frontend/dist/assets/{style-BbREPmRj.js → style-CKs7nnn3.js} +2 -2
- package/ccw/frontend/dist/assets/{style-BbREPmRj.js.map → style-CKs7nnn3.js.map} +1 -1
- package/ccw/frontend/dist/assets/{target-CElrCVhR.js → target-DW5tsDW6.js} +2 -2
- package/ccw/frontend/dist/assets/{target-CElrCVhR.js.map → target-DW5tsDW6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{test-tube-wciJaoas.js → test-tube-BHm7w3ON.js} +2 -2
- package/ccw/frontend/dist/assets/{test-tube-wciJaoas.js.map → test-tube-BHm7w3ON.js.map} +1 -1
- package/ccw/frontend/dist/assets/{upload-BD1F07wG.js → upload-DYR7PWwt.js} +2 -2
- package/ccw/frontend/dist/assets/{upload-BD1F07wG.js.map → upload-DYR7PWwt.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useApiSettings-D23HVEt8.js → useApiSettings-D0TVgQD_.js} +2 -2
- package/ccw/frontend/dist/assets/{useApiSettings-D23HVEt8.js.map → useApiSettings-D0TVgQD_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCli-BGDd_lXD.js → useCli-DfY8mAP8.js} +2 -2
- package/ccw/frontend/dist/assets/{useCli-BGDd_lXD.js.map → useCli-DfY8mAP8.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCommands-B-m_HxPB.js → useCommands-CGusDp0F.js} +2 -2
- package/ccw/frontend/dist/assets/{useCommands-B-m_HxPB.js.map → useCommands-CGusDp0F.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useDebounce-Z18-PHZr.js → useDebounce-CIwh0fF1.js} +2 -2
- package/ccw/frontend/dist/assets/{useDebounce-Z18-PHZr.js.map → useDebounce-CIwh0fF1.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useFileExplorer-D4gPp-LB.js → useFileExplorer-FMyFv39K.js} +2 -2
- package/ccw/frontend/dist/assets/{useFileExplorer-D4gPp-LB.js.map → useFileExplorer-FMyFv39K.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useLocale-DJ62jjFa.js → useLocale-B2qhsoTb.js} +2 -2
- package/ccw/frontend/dist/assets/{useLocale-DJ62jjFa.js.map → useLocale-B2qhsoTb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSkills-B8NPs9__.js → useSkills-cxKXMBm3.js} +3 -3
- package/ccw/frontend/dist/assets/{useSkills-B8NPs9__.js.map → useSkills-cxKXMBm3.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSystemSettings-CVi7nKGJ.js → useSystemSettings-B-xUT_z-.js} +2 -2
- package/ccw/frontend/dist/assets/{useSystemSettings-CVi7nKGJ.js.map → useSystemSettings-B-xUT_z-.js.map} +1 -1
- package/ccw/frontend/dist/assets/{wand-sparkles-CLjPiU5w.js → wand-sparkles-DZV_3lPr.js} +2 -2
- package/ccw/frontend/dist/assets/{wand-sparkles-CLjPiU5w.js.map → wand-sparkles-DZV_3lPr.js.map} +1 -1
- package/ccw/frontend/dist/index.html +1 -1
- package/package.json +105 -105
- package/ccw/frontend/dist/assets/SettingsPage-BPDbXPSM.js.map +0 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: motion-tester
|
|
3
|
+
prefix: MTEST
|
|
4
|
+
inner_loop: false
|
|
5
|
+
message_types: [state_update]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Motion Performance Tester
|
|
9
|
+
|
|
10
|
+
Test animation performance via Chrome DevTools performance traces and static code analysis. Verify compositor-only animations, measure FPS, detect layout thrashing, and validate prefers-reduced-motion accessibility compliance. Act as Critic in the animator<->motion-tester Generator-Critic loop.
|
|
11
|
+
|
|
12
|
+
## Phase 2: Context & Artifact Loading
|
|
13
|
+
|
|
14
|
+
| Input | Source | Required |
|
|
15
|
+
|-------|--------|----------|
|
|
16
|
+
| Animation files | <session>/animations/keyframes/*.css | Yes |
|
|
17
|
+
| JS orchestrators | <session>/animations/orchestrators/*.js | Yes |
|
|
18
|
+
| Motion tokens | <session>/choreography/motion-tokens.json | Yes |
|
|
19
|
+
| Choreography sequences | <session>/choreography/sequences/*.md | Yes (component/page) |
|
|
20
|
+
| GPU constraints | specs/gpu-constraints.md | Yes |
|
|
21
|
+
| Reduced motion spec | specs/reduced-motion.md | Yes |
|
|
22
|
+
| .msg/meta.json | <session>/wisdom/.msg/meta.json | Yes |
|
|
23
|
+
|
|
24
|
+
1. Extract session path from task description
|
|
25
|
+
2. Read all animation CSS files from animations/keyframes/
|
|
26
|
+
3. Read all JS orchestrator files from animations/orchestrators/
|
|
27
|
+
4. Read motion tokens for reference values
|
|
28
|
+
5. Read choreography sequences for expected behavior
|
|
29
|
+
6. Read GPU constraints and reduced motion specs for validation rules
|
|
30
|
+
|
|
31
|
+
## Phase 3: Test Execution
|
|
32
|
+
|
|
33
|
+
### Test 1: Compositor-Only Verification
|
|
34
|
+
|
|
35
|
+
Scan all CSS @keyframes and transition properties for unsafe values:
|
|
36
|
+
|
|
37
|
+
**SAFE** (compositor thread, no repaint):
|
|
38
|
+
- `transform` (translate, scale, rotate, skew)
|
|
39
|
+
- `opacity`
|
|
40
|
+
- `filter` (blur, brightness, contrast)
|
|
41
|
+
- `backdrop-filter`
|
|
42
|
+
|
|
43
|
+
**UNSAFE** (trigger layout/paint):
|
|
44
|
+
- `width`, `height`, `top`, `left`, `right`, `bottom`
|
|
45
|
+
- `margin`, `padding`, `border`
|
|
46
|
+
- `font-size`, `color`, `background-color`
|
|
47
|
+
- `box-shadow` (partial -- expensive paint)
|
|
48
|
+
|
|
49
|
+
For each animation file:
|
|
50
|
+
1. Parse @keyframes blocks, extract animated properties
|
|
51
|
+
2. Parse transition declarations, extract properties
|
|
52
|
+
3. Flag any UNSAFE property with file:line reference
|
|
53
|
+
4. Score: `safe_percentage = safe_count / total_count * 100`
|
|
54
|
+
|
|
55
|
+
### Test 2: Frame Rate Analysis
|
|
56
|
+
|
|
57
|
+
**If Chrome DevTools MCP available**:
|
|
58
|
+
1. `mcp__chrome-devtools__performance_start_trace()` -- start recording
|
|
59
|
+
2. `mcp__chrome-devtools__evaluate_script({ expression: "/* trigger animations */" })` -- trigger
|
|
60
|
+
3. `mcp__chrome-devtools__performance_stop_trace()` -- stop recording
|
|
61
|
+
4. `mcp__chrome-devtools__performance_analyze_insight()` -- analyze
|
|
62
|
+
5. Extract: average FPS, minimum FPS, frame drops, long frames (>16.67ms)
|
|
63
|
+
6. Target: average >= 60fps, minimum >= 45fps, no consecutive drops
|
|
64
|
+
|
|
65
|
+
**If Chrome DevTools unavailable** (static analysis fallback):
|
|
66
|
+
1. Count total animated properties per frame (concurrent animations)
|
|
67
|
+
2. Estimate frame budget: < 5ms style+layout, < 5ms paint+composite
|
|
68
|
+
3. Flag: >10 concurrent animations, nested animations, forced synchronous layouts
|
|
69
|
+
4. Mark `_source: "static-analysis"` and note limitations
|
|
70
|
+
|
|
71
|
+
### Test 3: Layout Thrashing Detection
|
|
72
|
+
|
|
73
|
+
Scan JS orchestrators for read-write-read patterns:
|
|
74
|
+
|
|
75
|
+
**Thrashing patterns** (DOM read -> write -> read in same frame):
|
|
76
|
+
- `offsetHeight` / `offsetWidth` read followed by style write followed by read
|
|
77
|
+
- `getBoundingClientRect()` interleaved with style mutations
|
|
78
|
+
- `getComputedStyle()` followed by DOM writes
|
|
79
|
+
|
|
80
|
+
For each JS file:
|
|
81
|
+
1. Parse for DOM read APIs: `offsetHeight`, `offsetWidth`, `clientHeight`, `getBoundingClientRect`, `getComputedStyle`, `scrollTop`, `scrollHeight`
|
|
82
|
+
2. Check if style writes (`.style.*`, `.classList.*`, `.setAttribute`) occur between reads
|
|
83
|
+
3. Flag thrashing sequences with file:line references
|
|
84
|
+
|
|
85
|
+
### Test 4: will-change Audit
|
|
86
|
+
|
|
87
|
+
1. Count elements with `will-change` in CSS
|
|
88
|
+
2. Flag if count > 4 (memory cost)
|
|
89
|
+
3. Check for `will-change: auto` on collections (anti-pattern)
|
|
90
|
+
4. Verify will-change is removed after animation completes (in JS orchestrators)
|
|
91
|
+
5. Check for missing will-change on heavily animated elements
|
|
92
|
+
|
|
93
|
+
### Test 5: Reduced Motion Compliance
|
|
94
|
+
|
|
95
|
+
1. Verify `@media (prefers-reduced-motion: reduce)` block exists
|
|
96
|
+
2. Check all animation-duration and transition-duration are overridden
|
|
97
|
+
3. Verify scroll-behavior set to auto
|
|
98
|
+
4. Check JS for `matchMedia('(prefers-reduced-motion: reduce)')` detection
|
|
99
|
+
5. Verify parallax effects disabled in reduced motion
|
|
100
|
+
6. Verify no auto-playing or infinite loop animations in reduced motion
|
|
101
|
+
|
|
102
|
+
### Perceived Performance Checks
|
|
103
|
+
| Check | Pass Criteria |
|
|
104
|
+
|-------|---------------|
|
|
105
|
+
| Preemptive animation start | Hover/click animations start on pointerdown, not click |
|
|
106
|
+
| No height/width animation | Grid-template-rows trick used instead of height transitions |
|
|
107
|
+
| Ease-in for progress | Progress indicators use ease-in (compresses perceived wait) |
|
|
108
|
+
| Ease-out for entrances | Content entrances use ease-out (natural settle) |
|
|
109
|
+
|
|
110
|
+
**Scoring**:
|
|
111
|
+
|
|
112
|
+
| Check | Weight | Criteria |
|
|
113
|
+
|-------|--------|----------|
|
|
114
|
+
| Compositor-only | 30% | 100% safe = 10, each unsafe -2 |
|
|
115
|
+
| Frame rate | 25% | >= 60fps = 10, 50-59 = 7, 40-49 = 4, < 40 = 1 |
|
|
116
|
+
| Layout thrashing | 20% | 0 instances = 10, each instance -3 |
|
|
117
|
+
| will-change budget | 10% | <= 4 = 10, 5-6 = 7, 7+ = 3 |
|
|
118
|
+
| Reduced motion | 15% | All 5 checks pass = 10, each miss -2 |
|
|
119
|
+
|
|
120
|
+
**Overall score**: `round(compositor*0.30 + fps*0.25 + thrashing*0.20 + willchange*0.10 + reducedmotion*0.15)`
|
|
121
|
+
|
|
122
|
+
**Signal determination**:
|
|
123
|
+
|
|
124
|
+
| Condition | Signal |
|
|
125
|
+
|-----------|--------|
|
|
126
|
+
| Score >= 8 AND no layout thrashing AND FPS >= 60 | `perf_passed` (GATE PASSED) |
|
|
127
|
+
| Score >= 6 AND no critical issues | `perf_warning` (REVISION SUGGESTED) |
|
|
128
|
+
| Score < 6 OR layout thrashing OR FPS < 60 | `fix_required` (CRITICAL FIX NEEDED) |
|
|
129
|
+
|
|
130
|
+
## Phase 4: Report & Output
|
|
131
|
+
|
|
132
|
+
1. Write performance report to `<session>/testing/reports/perf-report-{NNN}.md`:
|
|
133
|
+
```markdown
|
|
134
|
+
# Performance Report {NNN}
|
|
135
|
+
|
|
136
|
+
## Summary
|
|
137
|
+
- Overall Score: X/10
|
|
138
|
+
- Signal: perf_passed|perf_warning|fix_required
|
|
139
|
+
- Source: chrome-devtools|static-analysis
|
|
140
|
+
|
|
141
|
+
## Compositor-Only Verification
|
|
142
|
+
- Safe: X/Y properties (Z%)
|
|
143
|
+
- Unsafe properties found:
|
|
144
|
+
- [file:line] property: suggestion
|
|
145
|
+
|
|
146
|
+
## Frame Rate
|
|
147
|
+
- Average FPS: X
|
|
148
|
+
- Minimum FPS: X
|
|
149
|
+
- Frame drops: X
|
|
150
|
+
- Long frames (>16.67ms): X
|
|
151
|
+
|
|
152
|
+
## Layout Thrashing
|
|
153
|
+
- Instances found: X
|
|
154
|
+
- Details:
|
|
155
|
+
- [file:line] pattern: description
|
|
156
|
+
|
|
157
|
+
## will-change Audit
|
|
158
|
+
- Elements with will-change: X
|
|
159
|
+
- Budget status: OK|OVER
|
|
160
|
+
- Issues:
|
|
161
|
+
- [file:line] issue: description
|
|
162
|
+
|
|
163
|
+
## Reduced Motion Compliance
|
|
164
|
+
- @media query present: yes|no
|
|
165
|
+
- Duration override: yes|no
|
|
166
|
+
- JS detection: yes|no
|
|
167
|
+
- Parallax disabled: yes|no|N/A
|
|
168
|
+
- No infinite loops: yes|no
|
|
169
|
+
|
|
170
|
+
## Recommendations
|
|
171
|
+
1. [Priority] Description
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
2. Update `<session>/wisdom/.msg/meta.json` under `motion-tester` namespace:
|
|
175
|
+
- Read existing -> merge `{ "motion-tester": { report_id, score, signal, fps_average, safe_percentage, thrashing_count, will_change_count, reduced_motion_complete } }` -> write back
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# GPU Constraints
|
|
2
|
+
|
|
3
|
+
Compositor-only animation rules for 60fps performance.
|
|
4
|
+
|
|
5
|
+
## Property Classification
|
|
6
|
+
|
|
7
|
+
### SAFE Properties (Compositor Thread, No Repaint)
|
|
8
|
+
|
|
9
|
+
These properties are handled by the GPU compositor thread and do not trigger layout or paint:
|
|
10
|
+
|
|
11
|
+
| Property | Examples | Notes |
|
|
12
|
+
|----------|---------|-------|
|
|
13
|
+
| `transform` | `translate()`, `scale()`, `rotate()`, `skew()` | Primary animation property |
|
|
14
|
+
| `opacity` | `0` to `1` | Cheap compositor operation |
|
|
15
|
+
| `filter` | `blur()`, `brightness()`, `contrast()`, `saturate()` | GPU-accelerated in modern browsers |
|
|
16
|
+
| `backdrop-filter` | `blur()`, `brightness()` | Composited separately |
|
|
17
|
+
|
|
18
|
+
### UNSAFE Properties (Trigger Layout/Paint)
|
|
19
|
+
|
|
20
|
+
**NEVER animate these properties** -- they force layout recalculation and/or paint:
|
|
21
|
+
|
|
22
|
+
| Property | Impact | Alternative |
|
|
23
|
+
|----------|--------|-------------|
|
|
24
|
+
| `width` | Layout | `transform: scaleX()` |
|
|
25
|
+
| `height` | Layout | `transform: scaleY()` |
|
|
26
|
+
| `top` | Layout | `transform: translateY()` |
|
|
27
|
+
| `left` | Layout | `transform: translateX()` |
|
|
28
|
+
| `right` | Layout | `transform: translateX()` (negative) |
|
|
29
|
+
| `bottom` | Layout | `transform: translateY()` (negative) |
|
|
30
|
+
| `margin` | Layout | `transform: translate()` |
|
|
31
|
+
| `padding` | Layout | Use inner element with transform |
|
|
32
|
+
| `border` | Layout + Paint | `outline` (no layout) or `box-shadow` |
|
|
33
|
+
| `font-size` | Layout | `transform: scale()` |
|
|
34
|
+
| `color` | Paint | Overlay with `opacity` |
|
|
35
|
+
| `background-color` | Paint | Overlay element with `opacity` |
|
|
36
|
+
| `box-shadow` | Paint | Use `filter: drop-shadow()` or pre-rendered layers |
|
|
37
|
+
|
|
38
|
+
## will-change Budget
|
|
39
|
+
|
|
40
|
+
### Rules
|
|
41
|
+
|
|
42
|
+
1. **Max 3-4 elements** with `will-change` simultaneously
|
|
43
|
+
2. **Remove after animation completes** -- do not leave permanent will-change
|
|
44
|
+
3. **Never use `will-change: auto`** on collections or many elements
|
|
45
|
+
4. **Explicit properties only**: `will-change: transform` or `will-change: opacity`, not `will-change: all`
|
|
46
|
+
|
|
47
|
+
### Implementation Pattern
|
|
48
|
+
|
|
49
|
+
```css
|
|
50
|
+
/* Static: no will-change */
|
|
51
|
+
.element {
|
|
52
|
+
transition: transform var(--duration-base) var(--ease-out);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Add will-change just before animation via JS */
|
|
56
|
+
.element.will-animate {
|
|
57
|
+
will-change: transform;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Or via CSS for hover-triggered animations */
|
|
61
|
+
.element:hover {
|
|
62
|
+
will-change: transform;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
// JS: add before, remove after
|
|
68
|
+
element.style.willChange = 'transform';
|
|
69
|
+
element.addEventListener('transitionend', () => {
|
|
70
|
+
element.style.willChange = 'auto';
|
|
71
|
+
}, { once: true });
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Layer Promotion
|
|
75
|
+
|
|
76
|
+
- `transform: translateZ(0)` or `will-change: transform` promotes to own compositor layer
|
|
77
|
+
- Each layer costs GPU memory (~width * height * 4 bytes)
|
|
78
|
+
- Avoid promoting too many layers -- profile with Chrome DevTools Layers panel
|
|
79
|
+
- Use sparingly: hero elements, frequently animated elements, scroll-linked elements
|
|
80
|
+
|
|
81
|
+
## Performance Targets
|
|
82
|
+
|
|
83
|
+
| Metric | Target | Budget |
|
|
84
|
+
|--------|--------|--------|
|
|
85
|
+
| Frame rate | 60fps | 16.67ms per frame |
|
|
86
|
+
| Style + Layout | < 5ms | ~30% of frame budget |
|
|
87
|
+
| Paint + Composite | < 5ms | ~30% of frame budget |
|
|
88
|
+
| JavaScript | < 5ms | ~30% of frame budget |
|
|
89
|
+
| Idle buffer | ~1.67ms | Headroom for GC, etc. |
|
|
90
|
+
|
|
91
|
+
## Measurement
|
|
92
|
+
|
|
93
|
+
### Chrome DevTools Performance Panel
|
|
94
|
+
1. Record performance trace during animation
|
|
95
|
+
2. Check "Frames" section for frame drops (red/yellow bars)
|
|
96
|
+
3. Check "Main" thread for long tasks during animation
|
|
97
|
+
4. Check "Compositor" thread for smooth operation
|
|
98
|
+
5. Look for "Layout" and "Paint" events during animation (should be minimal)
|
|
99
|
+
|
|
100
|
+
### Key Indicators of Problems
|
|
101
|
+
- Purple "Layout" bars during animation = layout-triggering property
|
|
102
|
+
- Green "Paint" bars during animation = paint-triggering property
|
|
103
|
+
- Red frame markers = dropped frames (>16.67ms)
|
|
104
|
+
- "Forced reflow" warnings = layout thrashing in JS
|
|
105
|
+
|
|
106
|
+
## Quick Reference Card
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
ANIMATE: transform, opacity, filter
|
|
110
|
+
AVOID: width, height, top, left, margin, padding, color, background-color
|
|
111
|
+
BUDGET: will-change on max 3-4 elements, remove after use
|
|
112
|
+
TARGET: 60fps = 16.67ms per frame
|
|
113
|
+
MEASURE: Chrome DevTools Performance panel
|
|
114
|
+
```
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Motion Token Schema
|
|
2
|
+
|
|
3
|
+
Animation token system for consistent motion design. Derived from Impeccable design principles.
|
|
4
|
+
|
|
5
|
+
## Easing Functions
|
|
6
|
+
|
|
7
|
+
| Token | Value | Use Case |
|
|
8
|
+
|-------|-------|----------|
|
|
9
|
+
| ease-out | `cubic-bezier(0.16, 1, 0.3, 1)` | Emphasis exit, deceleration. Elements entering view. |
|
|
10
|
+
| ease-in-out | `cubic-bezier(0.65, 0, 0.35, 1)` | Smooth symmetrical. State changes, toggles. |
|
|
11
|
+
| ease-spring | `cubic-bezier(0.34, 1.56, 0.64, 1)` | Overshoot bounce. Playful interactions, notifications. |
|
|
12
|
+
|
|
13
|
+
**Usage guidelines**:
|
|
14
|
+
- `ease-out` is the default for most animations (content reveals, transitions)
|
|
15
|
+
- `ease-in-out` for reversible state changes (expand/collapse, toggle)
|
|
16
|
+
- `ease-spring` sparingly for emphasis (new item added, attention-grabbing)
|
|
17
|
+
- Never use `ease-in` alone (feels sluggish for UI)
|
|
18
|
+
|
|
19
|
+
## Duration Scale
|
|
20
|
+
|
|
21
|
+
| Token | Value | Use Case |
|
|
22
|
+
|-------|-------|----------|
|
|
23
|
+
| fast | `0.15s` | Micro-interactions: button press, toggle, checkbox |
|
|
24
|
+
| base | `0.3s` | Standard transitions: hover, focus, dropdown |
|
|
25
|
+
| slow | `0.6s` | Content reveals: card entry, panel slide, accordion |
|
|
26
|
+
| slower | `0.8s` | Page transitions: route change, large element moves |
|
|
27
|
+
| slowest | `1.2s` | Hero animations: splash screen, onboarding, first load |
|
|
28
|
+
|
|
29
|
+
**Guidelines**:
|
|
30
|
+
- Faster for small elements, slower for large elements
|
|
31
|
+
- Faster for frequent interactions, slower for infrequent
|
|
32
|
+
- Never exceed 1.2s for any single animation
|
|
33
|
+
- Total page animation sequence should complete within 2s
|
|
34
|
+
|
|
35
|
+
## Stagger Formula
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
delay = base_delay + (index * stagger_increment)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
| Parameter | Typical Value | Range |
|
|
42
|
+
|-----------|---------------|-------|
|
|
43
|
+
| base_delay | `0s` | 0-0.1s |
|
|
44
|
+
| stagger_increment | `0.05s` | 0.03-0.1s |
|
|
45
|
+
| max visible stagger | 8 items | -- |
|
|
46
|
+
|
|
47
|
+
**Guidelines**:
|
|
48
|
+
- Max 8 items in a stagger sequence (avoid >0.8s total delay)
|
|
49
|
+
- For >8 items: batch into groups of 4-6 with group-level stagger
|
|
50
|
+
- Stagger increment scales with duration: fast animations use smaller increments
|
|
51
|
+
- First item always has 0 delay (no waiting)
|
|
52
|
+
|
|
53
|
+
## CSS Custom Property Format
|
|
54
|
+
|
|
55
|
+
```css
|
|
56
|
+
:root {
|
|
57
|
+
/* Easing functions */
|
|
58
|
+
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
|
|
59
|
+
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
|
|
60
|
+
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
61
|
+
|
|
62
|
+
/* Duration scale */
|
|
63
|
+
--duration-fast: 0.15s;
|
|
64
|
+
--duration-base: 0.3s;
|
|
65
|
+
--duration-slow: 0.6s;
|
|
66
|
+
--duration-slower: 0.8s;
|
|
67
|
+
--duration-slowest: 1.2s;
|
|
68
|
+
|
|
69
|
+
/* Stagger */
|
|
70
|
+
--stagger-increment: 0.05s;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Token Consumption Pattern
|
|
75
|
+
|
|
76
|
+
```css
|
|
77
|
+
/* Correct: consume tokens via custom properties */
|
|
78
|
+
.card-enter {
|
|
79
|
+
animation: fade-up var(--duration-slow) var(--ease-out) both;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Correct: stagger via inline style or calc */
|
|
83
|
+
.card-enter:nth-child(n) {
|
|
84
|
+
animation-delay: calc(var(--stagger-increment) * var(--stagger-index, 0));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* WRONG: hardcoded values */
|
|
88
|
+
.card-enter {
|
|
89
|
+
animation: fade-up 0.6s cubic-bezier(0.16, 1, 0.3, 1) both; /* BAD */
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## JSON Token Format
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"easing": {
|
|
98
|
+
"ease-out": {
|
|
99
|
+
"value": "cubic-bezier(0.16, 1, 0.3, 1)",
|
|
100
|
+
"use": "exit emphasis, deceleration",
|
|
101
|
+
"css_property": "--ease-out"
|
|
102
|
+
},
|
|
103
|
+
"ease-in-out": {
|
|
104
|
+
"value": "cubic-bezier(0.65, 0, 0.35, 1)",
|
|
105
|
+
"use": "smooth symmetrical",
|
|
106
|
+
"css_property": "--ease-in-out"
|
|
107
|
+
},
|
|
108
|
+
"ease-spring": {
|
|
109
|
+
"value": "cubic-bezier(0.34, 1.56, 0.64, 1)",
|
|
110
|
+
"use": "overshoot bounce",
|
|
111
|
+
"css_property": "--ease-spring"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"duration": {
|
|
115
|
+
"fast": { "value": "0.15s", "use": "micro-interactions", "css_property": "--duration-fast" },
|
|
116
|
+
"base": { "value": "0.3s", "use": "standard transitions", "css_property": "--duration-base" },
|
|
117
|
+
"slow": { "value": "0.6s", "use": "content reveals", "css_property": "--duration-slow" },
|
|
118
|
+
"slower": { "value": "0.8s", "use": "page transitions", "css_property": "--duration-slower" },
|
|
119
|
+
"slowest": { "value": "1.2s", "use": "hero animations", "css_property": "--duration-slowest" }
|
|
120
|
+
},
|
|
121
|
+
"stagger": {
|
|
122
|
+
"base_delay": "0s",
|
|
123
|
+
"increment": "0.05s",
|
|
124
|
+
"max_items": 8,
|
|
125
|
+
"css_property": "--stagger-increment"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Pipeline Definitions
|
|
2
|
+
|
|
3
|
+
Motion design pipeline modes and task registry.
|
|
4
|
+
|
|
5
|
+
## Pipeline Modes
|
|
6
|
+
|
|
7
|
+
| Mode | Description | Task Count |
|
|
8
|
+
|------|-------------|------------|
|
|
9
|
+
| tokens | Animation token system: research -> choreography -> animation -> test | 4 tasks |
|
|
10
|
+
| component | Component animation with GC loop for performance | 4 tasks (+fix) |
|
|
11
|
+
| page | Full page scroll choreography with parallel animations | 4+N tasks |
|
|
12
|
+
|
|
13
|
+
## Tokens Pipeline Task Registry
|
|
14
|
+
|
|
15
|
+
| Task ID | Role | blockedBy | Description |
|
|
16
|
+
|---------|------|-----------|-------------|
|
|
17
|
+
| MRESEARCH-001 | motion-researcher | [] | Audit existing animations, measure perf baseline, catalog easing patterns |
|
|
18
|
+
| CHOREO-001 | choreographer | [MRESEARCH-001] | Design motion token system (easing, duration, stagger, reduced-motion) |
|
|
19
|
+
| ANIM-001 | animator | [CHOREO-001] | Implement CSS custom properties, utility animations, reduced-motion overrides |
|
|
20
|
+
| MTEST-001 | motion-tester | [ANIM-001] | Verify compositor-only, FPS, will-change budget, reduced-motion compliance |
|
|
21
|
+
|
|
22
|
+
## Component Pipeline Task Registry
|
|
23
|
+
|
|
24
|
+
| Task ID | Role | blockedBy | Description |
|
|
25
|
+
|---------|------|-----------|-------------|
|
|
26
|
+
| MRESEARCH-001 | motion-researcher | [] | Audit target component animations, measure perf baseline |
|
|
27
|
+
| CHOREO-001 | choreographer | [MRESEARCH-001] | Design tokens + transition state diagrams + scroll sequences |
|
|
28
|
+
| ANIM-001 | animator | [CHOREO-001] | Implement component animations: @keyframes, IntersectionObserver, rAF |
|
|
29
|
+
| MTEST-001 | motion-tester | [ANIM-001] | Performance gate: FPS, compositor-only, layout thrashing, reduced-motion |
|
|
30
|
+
|
|
31
|
+
GC loop: MTEST-001 -> ANIM-fix-1 -> MTEST-002 (max 2 rounds)
|
|
32
|
+
|
|
33
|
+
## Page Pipeline Task Registry
|
|
34
|
+
|
|
35
|
+
| Task ID | Role | blockedBy | Description |
|
|
36
|
+
|---------|------|-----------|-------------|
|
|
37
|
+
| MRESEARCH-001 | motion-researcher | [] | Full page animation audit, scroll section inventory |
|
|
38
|
+
| CHOREO-001 | choreographer | [MRESEARCH-001] | Page-level motion tokens + scroll choreography per section |
|
|
39
|
+
| ANIM-001..N | animator | [CHOREO-001] | Parallel: one ANIM task per scroll section (CP-3 Fan-out) |
|
|
40
|
+
| MTEST-001 | motion-tester | [ANIM-001..N] | Full page performance validation after all sections complete |
|
|
41
|
+
|
|
42
|
+
## Performance Gate (Sync Point)
|
|
43
|
+
|
|
44
|
+
| Checkpoint | Task | Condition | Action |
|
|
45
|
+
|------------|------|-----------|--------|
|
|
46
|
+
| PERF-001: Performance Gate | MTEST-* completes | FPS >= 60, no thrashing, reduced-motion OK | Pipeline complete |
|
|
47
|
+
| PERF-001: GC Loop | MTEST-* completes | FPS < 60 or thrashing | Create ANIM-fix task, new MTEST task (max 2 rounds) |
|
|
48
|
+
|
|
49
|
+
## GC Loop Behavior
|
|
50
|
+
|
|
51
|
+
| Signal | Condition | Action |
|
|
52
|
+
|--------|-----------|--------|
|
|
53
|
+
| perf_passed | Score >= 8, FPS >= 60, no thrashing | Performance gate passed -> pipeline complete |
|
|
54
|
+
| perf_warning | Score 6-7, minor issues | gc_rounds < max -> create ANIM-fix task |
|
|
55
|
+
| fix_required | Score < 6 or FPS < 60 or thrashing | gc_rounds < max -> create ANIM-fix task (CRITICAL) |
|
|
56
|
+
| Any | gc_rounds >= max | Escalate to user: accept / try one more / terminate |
|
|
57
|
+
|
|
58
|
+
## Parallel Spawn Rules
|
|
59
|
+
|
|
60
|
+
| Mode | After | Spawn Behavior |
|
|
61
|
+
|------|-------|----------------|
|
|
62
|
+
| tokens | Sequential | One task at a time |
|
|
63
|
+
| component | Sequential | One task at a time, GC loop on MTEST |
|
|
64
|
+
| page | CHOREO-001 | Spawn ANIM-001..N in parallel (CP-3 Fan-out) |
|
|
65
|
+
| page | All ANIM complete | Spawn MTEST-001 |
|
|
66
|
+
|
|
67
|
+
## Output Artifacts
|
|
68
|
+
|
|
69
|
+
| Task | Output Path |
|
|
70
|
+
|------|-------------|
|
|
71
|
+
| MRESEARCH-001 | <session>/research/*.json |
|
|
72
|
+
| CHOREO-001 | <session>/choreography/motion-tokens.json + sequences/*.md |
|
|
73
|
+
| ANIM-* | <session>/animations/keyframes/*.css + orchestrators/*.js |
|
|
74
|
+
| MTEST-* | <session>/testing/reports/perf-report-{NNN}.md |
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Reduced Motion Accessibility
|
|
2
|
+
|
|
3
|
+
Implementation guidelines for `prefers-reduced-motion` compliance.
|
|
4
|
+
|
|
5
|
+
## Strategy
|
|
6
|
+
|
|
7
|
+
Wrap all motion in `@media` query, provide instant fallback. Users who prefer reduced motion should still perceive state changes but without disorienting movement.
|
|
8
|
+
|
|
9
|
+
## CSS Implementation
|
|
10
|
+
|
|
11
|
+
### Global Override
|
|
12
|
+
|
|
13
|
+
```css
|
|
14
|
+
@media (prefers-reduced-motion: reduce) {
|
|
15
|
+
*,
|
|
16
|
+
*::before,
|
|
17
|
+
*::after {
|
|
18
|
+
animation-duration: 0.01ms !important;
|
|
19
|
+
animation-iteration-count: 1 !important;
|
|
20
|
+
transition-duration: 0.01ms !important;
|
|
21
|
+
scroll-behavior: auto !important;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Per-Component Override (Preferred)
|
|
27
|
+
|
|
28
|
+
```css
|
|
29
|
+
.card-enter {
|
|
30
|
+
animation: fade-up var(--duration-slow) var(--ease-out) both;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@media (prefers-reduced-motion: reduce) {
|
|
34
|
+
.card-enter {
|
|
35
|
+
animation: fade-in 0.01ms linear both; /* opacity only, instant */
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Parallax Disable
|
|
41
|
+
|
|
42
|
+
```css
|
|
43
|
+
.parallax-element {
|
|
44
|
+
transform: translateY(calc(var(--scroll-y) * 0.5));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@media (prefers-reduced-motion: reduce) {
|
|
48
|
+
.parallax-element {
|
|
49
|
+
transform: none !important;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## JavaScript Detection
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
// Check preference
|
|
58
|
+
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
59
|
+
|
|
60
|
+
// Use in animation logic
|
|
61
|
+
if (prefersReducedMotion.matches) {
|
|
62
|
+
// Skip parallax
|
|
63
|
+
// Disable spring/bounce animations
|
|
64
|
+
// Use instant transitions
|
|
65
|
+
// Skip scroll-linked transforms
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Listen for changes (user toggles setting)
|
|
69
|
+
prefersReducedMotion.addEventListener('change', (event) => {
|
|
70
|
+
if (event.matches) {
|
|
71
|
+
disableMotion();
|
|
72
|
+
} else {
|
|
73
|
+
enableMotion();
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Allowed in Reduced Motion
|
|
79
|
+
|
|
80
|
+
These subtle effects are acceptable and help maintain usability:
|
|
81
|
+
|
|
82
|
+
| Effect | Duration | Notes |
|
|
83
|
+
|--------|----------|-------|
|
|
84
|
+
| Opacity fades | < 0.15s | Short, non-directional |
|
|
85
|
+
| Color transitions | < 0.15s | Subtle state indicator |
|
|
86
|
+
| Essential state indicators | Instant | Focus rings, selection highlights |
|
|
87
|
+
| Progress indicators | N/A | Spinner -> static progress bar |
|
|
88
|
+
|
|
89
|
+
## Disallowed in Reduced Motion
|
|
90
|
+
|
|
91
|
+
These effects must be completely disabled:
|
|
92
|
+
|
|
93
|
+
| Effect | Reason | Fallback |
|
|
94
|
+
|--------|--------|----------|
|
|
95
|
+
| Parallax scrolling | Vestibular triggers | Static positioning |
|
|
96
|
+
| Scroll-linked transforms | Continuous motion | No transform |
|
|
97
|
+
| Bouncing/spring animations | Overshoot causes discomfort | Instant state change |
|
|
98
|
+
| Auto-playing content | Unexpected motion | Pause by default |
|
|
99
|
+
| Infinite loop animations | Continuous distraction | Single iteration or static |
|
|
100
|
+
| Large-scale movements | Disorienting | Opacity fade only |
|
|
101
|
+
| Zoom/scale animations | Vestibular triggers | Opacity fade |
|
|
102
|
+
| Rotating animations | Vestibular triggers | Static or opacity |
|
|
103
|
+
|
|
104
|
+
## Testing Checklist
|
|
105
|
+
|
|
106
|
+
| Check | Method | Expected |
|
|
107
|
+
|-------|--------|----------|
|
|
108
|
+
| `@media` query present | Grep CSS for `prefers-reduced-motion` | At least one global override |
|
|
109
|
+
| Duration override | Check `animation-duration` and `transition-duration` | Set to `0.01ms` |
|
|
110
|
+
| Scroll behavior | Check `scroll-behavior` | Set to `auto` |
|
|
111
|
+
| JS detection | Grep JS for `matchMedia.*reduced-motion` | Present with listener |
|
|
112
|
+
| Parallax disabled | Check parallax elements in reduced motion | `transform: none` |
|
|
113
|
+
| No infinite loops | Check `animation-iteration-count` | Set to `1` |
|
|
114
|
+
| No auto-play | Check auto-playing animations | Paused or removed |
|
|
115
|
+
|
|
116
|
+
## Implementation Order
|
|
117
|
+
|
|
118
|
+
1. Add global CSS override first (catches everything)
|
|
119
|
+
2. Add per-component overrides for nuanced fallbacks
|
|
120
|
+
3. Add JS detection for runtime animation control
|
|
121
|
+
4. Test with browser setting toggled ON
|
|
122
|
+
5. Verify no motion remains except allowed effects
|
|
123
|
+
|
|
124
|
+
## Browser Support
|
|
125
|
+
|
|
126
|
+
- `prefers-reduced-motion: reduce` -- supported in all modern browsers
|
|
127
|
+
- Safari 10.1+, Chrome 74+, Firefox 63+, Edge 79+
|
|
128
|
+
- iOS Safari 10.3+ (respects system Accessibility settings)
|
|
129
|
+
- Android Chrome 74+ (respects system Accessibility settings)
|