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,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: interaction-designer
|
|
3
|
+
prefix: INTERACT
|
|
4
|
+
inner_loop: false
|
|
5
|
+
message_types: [state_update]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Interaction Blueprint Designer
|
|
9
|
+
|
|
10
|
+
Design complete interaction blueprints: state machines, event flows, gesture specifications, animation choreography, and input mapping tables. Consume research artifacts to produce blueprints for the builder role.
|
|
11
|
+
|
|
12
|
+
## Phase 2: Context & Artifact Loading
|
|
13
|
+
|
|
14
|
+
| Input | Source | Required |
|
|
15
|
+
|-------|--------|----------|
|
|
16
|
+
| Research artifacts | <session>/research/*.json | Yes |
|
|
17
|
+
| .msg/meta.json | <session>/wisdom/.msg/meta.json | Yes |
|
|
18
|
+
| Existing blueprints | <session>/interaction/blueprints/*.md | Only for INTERACT-002+ |
|
|
19
|
+
|
|
20
|
+
1. Extract session path from task description
|
|
21
|
+
2. Read research findings: interaction-inventory.json, browser-api-audit.json, pattern-reference.json
|
|
22
|
+
3. Detect task type from subject: "001" -> Primary blueprint, "002" -> Secondary/gallery blueprint
|
|
23
|
+
4. If INTERACT-002+: read existing blueprints for consistency with base component
|
|
24
|
+
|
|
25
|
+
## Phase 3: Design Execution
|
|
26
|
+
|
|
27
|
+
**Primary Blueprint (INTERACT-001)**:
|
|
28
|
+
|
|
29
|
+
For each target component, produce a blueprint document containing:
|
|
30
|
+
|
|
31
|
+
### State Machine
|
|
32
|
+
Define complete state diagram:
|
|
33
|
+
```
|
|
34
|
+
[idle] --(pointerenter)--> [hover]
|
|
35
|
+
[hover] --(pointerdown)--> [active]
|
|
36
|
+
[hover] --(pointerleave)--> [idle]
|
|
37
|
+
[active] --(pointermove)--> [dragging/animating]
|
|
38
|
+
[active] --(pointerup)--> [hover]
|
|
39
|
+
[dragging] --(pointerup)--> [settling]
|
|
40
|
+
[settling] --(transitionend)--> [idle]
|
|
41
|
+
[any] --(focus)--> [focused]
|
|
42
|
+
[focused] --(blur)--> [previous-state]
|
|
43
|
+
[any] --(keydown:Escape)--> [idle]
|
|
44
|
+
```
|
|
45
|
+
- All states must be reachable
|
|
46
|
+
- All states must have exit transitions
|
|
47
|
+
- Error/reset transitions from every state back to idle
|
|
48
|
+
|
|
49
|
+
### Event Flow Map
|
|
50
|
+
Map events to handlers to state transitions:
|
|
51
|
+
|
|
52
|
+
| Event | Source | Handler | State Transition | Side Effect |
|
|
53
|
+
|-------|--------|---------|-----------------|-------------|
|
|
54
|
+
| pointerdown | element | onPointerDown | idle->active | setPointerCapture, preventDefault |
|
|
55
|
+
| pointermove | document | onPointerMove | active->dragging | update position via lerp |
|
|
56
|
+
| pointerup | document | onPointerUp | dragging->settling | releasePointerCapture |
|
|
57
|
+
| keydown:ArrowLeft | element | onKeyDown | - | decrement value |
|
|
58
|
+
| keydown:ArrowRight | element | onKeyDown | - | increment value |
|
|
59
|
+
| keydown:Escape | element | onKeyDown | any->idle | reset to default |
|
|
60
|
+
| keydown:Enter/Space | element | onKeyDown | idle->active | toggle/activate |
|
|
61
|
+
|
|
62
|
+
### Gesture Specification
|
|
63
|
+
For pointer/touch interactions:
|
|
64
|
+
|
|
65
|
+
| Gesture | Detection | Parameters |
|
|
66
|
+
|---------|-----------|------------|
|
|
67
|
+
| Drag | pointerdown + pointermove > 3px | lerp speed: 0.15, axis: x/y/both |
|
|
68
|
+
| Swipe | pointerup with velocity > 0.5px/ms | direction: left/right/up/down |
|
|
69
|
+
| Pinch | 2+ touch points, distance change | scale factor, min/max zoom |
|
|
70
|
+
| Scroll snap | CSS scroll-snap-type: x mandatory | align: start/center, behavior: smooth |
|
|
71
|
+
|
|
72
|
+
- Lerp interpolation: `current += (target - current) * speed`
|
|
73
|
+
- Dead zone: ignore movements < 3px from start
|
|
74
|
+
- Velocity tracking: store last 3-5 pointer positions with timestamps
|
|
75
|
+
|
|
76
|
+
### Animation Choreography
|
|
77
|
+
Define animation sequences:
|
|
78
|
+
|
|
79
|
+
| Animation | Trigger | Properties | Duration | Easing | GPU |
|
|
80
|
+
|-----------|---------|------------|----------|--------|-----|
|
|
81
|
+
| Entry | mount/reveal | opacity 0->1, translateY 20px->0 | 400ms | cubic-bezier(0.16,1,0.3,1) | Yes |
|
|
82
|
+
| Exit | unmount/hide | opacity 1->0, translateY 0->-10px | 200ms | ease-in | Yes |
|
|
83
|
+
| Drag follow | pointermove | translateX via lerp | per-frame | linear (lerp) | Yes |
|
|
84
|
+
| Settle | pointerup | translateX to snap point | 300ms | cubic-bezier(0.16,1,0.3,1) | Yes |
|
|
85
|
+
| Hover | pointerenter | scale 1->1.02 | 200ms | ease-out | Yes |
|
|
86
|
+
| Focus ring | focus-visible | outline-offset 0->2px | 150ms | ease-out | No (outline) |
|
|
87
|
+
| Stagger | intersection | delay: index * 80ms | 400ms+delay | cubic-bezier(0.16,1,0.3,1) | Yes |
|
|
88
|
+
|
|
89
|
+
- ALL animations must use transform + opacity only (GPU-composited)
|
|
90
|
+
- Exception: outline for focus indicators
|
|
91
|
+
- Reduced motion: replace all motion with opacity-only crossfade (200ms)
|
|
92
|
+
|
|
93
|
+
### Input Mapping Table
|
|
94
|
+
Unified mapping across input methods:
|
|
95
|
+
|
|
96
|
+
| Action | Mouse | Touch | Keyboard | Screen Reader |
|
|
97
|
+
|--------|-------|-------|----------|--------------|
|
|
98
|
+
| Activate | click | tap | Enter/Space | Enter/Space |
|
|
99
|
+
| Navigate prev | - | swipe-right | ArrowLeft | ArrowLeft |
|
|
100
|
+
| Navigate next | - | swipe-left | ArrowRight | ArrowRight |
|
|
101
|
+
| Drag/adjust | pointerdown+move | pointerdown+move | Arrow keys (step) | Arrow keys (step) |
|
|
102
|
+
| Dismiss | click outside | tap outside | Escape | Escape |
|
|
103
|
+
| Focus | pointermove (hover) | - | Tab | Tab |
|
|
104
|
+
|
|
105
|
+
### Platform API Preference
|
|
106
|
+
|
|
107
|
+
When designing interaction blueprints, prefer native APIs over custom implementations:
|
|
108
|
+
|
|
109
|
+
| Need | Native API | Custom Fallback |
|
|
110
|
+
|------|-----------|-----------------|
|
|
111
|
+
| Modal dialog | `<dialog>` + `showModal()` | Custom with focus trap + inert |
|
|
112
|
+
| Tooltip/popover | Popover API (`popover` attribute) | Custom with click-outside listener |
|
|
113
|
+
| Dropdown positioning | CSS Anchor Positioning | `position: fixed` + JS coords |
|
|
114
|
+
| Focus trap | `<dialog>` built-in or `inert` attribute | Manual focus cycling with tabindex |
|
|
115
|
+
| Escape-to-close | Built into `<dialog>` and Popover | Manual keydown listener |
|
|
116
|
+
|
|
117
|
+
Document in blueprint: which native API to use, what the fallback is for unsupported browsers, and how to feature-detect.
|
|
118
|
+
|
|
119
|
+
**Gallery/Secondary Blueprint (INTERACT-002)**:
|
|
120
|
+
- Design scroll-snap container interaction
|
|
121
|
+
- Navigation controls (prev/next arrows, dots/indicators)
|
|
122
|
+
- Active item detection via IntersectionObserver
|
|
123
|
+
- Keyboard navigation within gallery (ArrowLeft/ArrowRight between items)
|
|
124
|
+
- Touch momentum and snap behavior
|
|
125
|
+
- Reference base component blueprint for consistency
|
|
126
|
+
|
|
127
|
+
Output: `<session>/interaction/blueprints/{component-name}.md`
|
|
128
|
+
|
|
129
|
+
## Phase 4: Self-Validation
|
|
130
|
+
|
|
131
|
+
| Check | Pass Criteria |
|
|
132
|
+
|-------|---------------|
|
|
133
|
+
| State machine complete | All states reachable, all states have exit |
|
|
134
|
+
| Event coverage | All events mapped to handlers |
|
|
135
|
+
| Keyboard complete | All interactive actions have keyboard equivalent |
|
|
136
|
+
| Touch parity | All mouse actions have touch equivalent |
|
|
137
|
+
| GPU-only animations | No width/height/top/left animations |
|
|
138
|
+
| Reduced motion | prefers-reduced-motion fallback defined |
|
|
139
|
+
| Screen reader path | All actions accessible via screen reader |
|
|
140
|
+
|
|
141
|
+
If any check fails, revise the blueprint before output.
|
|
142
|
+
|
|
143
|
+
Update `<session>/wisdom/.msg/meta.json` under `interaction-designer` namespace:
|
|
144
|
+
- Read existing -> merge `{ "interaction-designer": { task_type, components_designed, states_count, events_count, gestures } }` -> write back
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: researcher
|
|
3
|
+
prefix: RESEARCH
|
|
4
|
+
inner_loop: false
|
|
5
|
+
message_types: [state_update]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Interaction Pattern Researcher
|
|
9
|
+
|
|
10
|
+
Analyze existing interactive components, audit browser API usage, and collect reference patterns for target component types. Produce foundation data for downstream interaction-designer, builder, and a11y-tester roles.
|
|
11
|
+
|
|
12
|
+
## Phase 2: Context & Environment Detection
|
|
13
|
+
|
|
14
|
+
| Input | Source | Required |
|
|
15
|
+
|-------|--------|----------|
|
|
16
|
+
| Task description | From task subject/description | Yes |
|
|
17
|
+
| Session path | Extracted from task description | Yes |
|
|
18
|
+
| .msg/meta.json | <session>/wisdom/.msg/meta.json | No |
|
|
19
|
+
|
|
20
|
+
1. Extract session path and target scope from task description
|
|
21
|
+
2. Detect project structure and existing interactive patterns:
|
|
22
|
+
|
|
23
|
+
| File Pattern | Detected Pattern |
|
|
24
|
+
|--------------|-----------------|
|
|
25
|
+
| *.js with addEventListener | Event-driven components |
|
|
26
|
+
| IntersectionObserver usage | Scroll-triggered animations |
|
|
27
|
+
| ResizeObserver usage | Responsive layout components |
|
|
28
|
+
| pointer/mouse/touch events | Interactive drag/gesture components |
|
|
29
|
+
| scroll-snap in CSS | Scroll-snap gallery |
|
|
30
|
+
| backdrop-filter in CSS | Glass/frosted effects |
|
|
31
|
+
| clip-path in CSS | Reveal/mask animations |
|
|
32
|
+
|
|
33
|
+
3. Use CLI tools (e.g., `ccw cli -p "..." --tool gemini --mode analysis`) or direct tools (Glob, Grep) to scan for existing interactive components, animation patterns, event handling approaches
|
|
34
|
+
4. Read interaction type context from session config
|
|
35
|
+
|
|
36
|
+
## Phase 3: Research Execution
|
|
37
|
+
|
|
38
|
+
Execute 3 analysis streams:
|
|
39
|
+
|
|
40
|
+
**Stream 1 -- Interaction Inventory**:
|
|
41
|
+
- Search for existing interactive components (event listeners, observers, animation code)
|
|
42
|
+
- Identify interaction patterns in use (drag, scroll, overlay, reveal)
|
|
43
|
+
- Map component lifecycle (init, mount, resize, destroy)
|
|
44
|
+
- Find dependency patterns (any external libs vs vanilla)
|
|
45
|
+
- Catalog gesture handling approaches (pointer vs mouse+touch)
|
|
46
|
+
- Output: `<session>/research/interaction-inventory.json`
|
|
47
|
+
- Schema:
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"existing_components": [
|
|
51
|
+
{ "name": "", "type": "", "events": [], "observers": [], "file": "" }
|
|
52
|
+
],
|
|
53
|
+
"patterns": {
|
|
54
|
+
"event_handling": "",
|
|
55
|
+
"animation_approach": "",
|
|
56
|
+
"lifecycle": "",
|
|
57
|
+
"dependency_model": ""
|
|
58
|
+
},
|
|
59
|
+
"summary": { "total_interactive": 0, "vanilla_count": 0, "lib_count": 0 }
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Stream 2 -- Browser API Audit**:
|
|
64
|
+
- Check availability and usage of target browser APIs:
|
|
65
|
+
- IntersectionObserver (scroll triggers, lazy loading, visibility detection)
|
|
66
|
+
- ResizeObserver (responsive layout, container queries)
|
|
67
|
+
- Pointer Events (unified mouse/touch/pen input)
|
|
68
|
+
- Touch Events (gesture recognition, multi-touch)
|
|
69
|
+
- CSS scroll-snap (snap points, scroll behavior)
|
|
70
|
+
- CSS clip-path (shape masking, reveal animations)
|
|
71
|
+
- CSS backdrop-filter (blur, brightness, glass effects)
|
|
72
|
+
- Web Animations API (programmatic animation control)
|
|
73
|
+
- requestAnimationFrame (frame-synced updates)
|
|
74
|
+
- Identify polyfill needs for target browser support
|
|
75
|
+
- Output: `<session>/research/browser-api-audit.json`
|
|
76
|
+
- Schema:
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"apis": {
|
|
80
|
+
"<api-name>": {
|
|
81
|
+
"available": true,
|
|
82
|
+
"in_use": false,
|
|
83
|
+
"support": "baseline|modern|polyfill-needed",
|
|
84
|
+
"usage_count": 0,
|
|
85
|
+
"notes": ""
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"polyfill_needs": [],
|
|
89
|
+
"min_browser_target": ""
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Stream 3 -- Pattern Reference**:
|
|
94
|
+
- Collect reference patterns for each target component type
|
|
95
|
+
- For each component, document: state machine pattern, event flow, animation approach, touch handling, accessibility pattern
|
|
96
|
+
- Reference well-known implementations (e.g., scroll-snap gallery, split-view compare, lightbox overlay)
|
|
97
|
+
- Note performance considerations and gotchas per pattern
|
|
98
|
+
- Output: `<session>/research/pattern-reference.json`
|
|
99
|
+
- Schema:
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"patterns": [
|
|
103
|
+
{
|
|
104
|
+
"component_type": "",
|
|
105
|
+
"state_machine": { "states": [], "transitions": [] },
|
|
106
|
+
"events": { "primary": [], "fallback": [] },
|
|
107
|
+
"animation": { "approach": "", "gpu_only": true, "easing": "" },
|
|
108
|
+
"touch": { "gestures": [], "threshold_px": 0 },
|
|
109
|
+
"a11y": { "role": "", "aria_states": [], "keyboard": [] },
|
|
110
|
+
"performance": { "budget_ms": 0, "gotchas": [] }
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Compile research summary metrics: existing_interactive_count, vanilla_ratio, apis_available, polyfill_count, patterns_collected.
|
|
117
|
+
|
|
118
|
+
## Phase 4: Validation & Output
|
|
119
|
+
|
|
120
|
+
1. Verify all 3 output files exist and contain valid JSON with required fields:
|
|
121
|
+
|
|
122
|
+
| File | Required Fields |
|
|
123
|
+
|------|----------------|
|
|
124
|
+
| interaction-inventory.json | existing_components array, patterns object |
|
|
125
|
+
| browser-api-audit.json | apis object |
|
|
126
|
+
| pattern-reference.json | patterns array |
|
|
127
|
+
|
|
128
|
+
2. If any file missing or invalid, re-run corresponding stream
|
|
129
|
+
|
|
130
|
+
3. Update `<session>/wisdom/.msg/meta.json` under `researcher` namespace:
|
|
131
|
+
- Read existing -> merge `{ "researcher": { interactive_count, vanilla_ratio, apis_available, polyfill_needs, scope } }` -> write back
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# Interaction Pattern Catalog
|
|
2
|
+
|
|
3
|
+
Reference patterns for common interactive components. Each pattern defines the core interaction model, browser APIs, state machine, animation approach, and accessibility requirements.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Glass Terminal Pattern
|
|
8
|
+
|
|
9
|
+
Split-view layout with frosted glass effect, tab navigation, and command input simulation.
|
|
10
|
+
|
|
11
|
+
**Core Interaction**:
|
|
12
|
+
- Tab-based view switching (2-4 panels)
|
|
13
|
+
- Command input field with syntax-highlighted output
|
|
14
|
+
- Frosted glass background via `backdrop-filter: blur()`
|
|
15
|
+
- Resize-aware layout via ResizeObserver
|
|
16
|
+
|
|
17
|
+
**State Machine**:
|
|
18
|
+
```
|
|
19
|
+
[idle] --(tab-click)--> [switching]
|
|
20
|
+
[switching] --(transition-end)--> [idle]
|
|
21
|
+
[idle] --(input-focus)--> [input-active]
|
|
22
|
+
[input-active] --(Enter)--> [processing]
|
|
23
|
+
[processing] --(output-ready)--> [idle]
|
|
24
|
+
[input-active] --(Escape)--> [idle]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Browser APIs**: ResizeObserver, CSS backdrop-filter, CSS custom properties
|
|
28
|
+
|
|
29
|
+
**Animation**:
|
|
30
|
+
- Tab switch: opacity crossfade (200ms, ease-out), GPU-only
|
|
31
|
+
- Output appear: translateY(10px)->0 + opacity (300ms, ease-out)
|
|
32
|
+
- Cursor blink: CSS animation (1s steps(2))
|
|
33
|
+
|
|
34
|
+
**CSS Key Properties**:
|
|
35
|
+
```css
|
|
36
|
+
.glass-terminal {
|
|
37
|
+
backdrop-filter: blur(12px) saturate(180%);
|
|
38
|
+
-webkit-backdrop-filter: blur(12px) saturate(180%);
|
|
39
|
+
background: rgba(255, 255, 255, 0.1);
|
|
40
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Accessibility**:
|
|
45
|
+
- role="tablist" + role="tab" + role="tabpanel"
|
|
46
|
+
- aria-selected on active tab
|
|
47
|
+
- Arrow keys navigate tabs, Enter/Space activates
|
|
48
|
+
- Input field: role="textbox", aria-label
|
|
49
|
+
- Output: aria-live="polite" for new content
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Split Compare Pattern
|
|
54
|
+
|
|
55
|
+
Before/after overlay with draggable divider for visual comparison.
|
|
56
|
+
|
|
57
|
+
**Core Interaction**:
|
|
58
|
+
- Draggable vertical divider splits two overlapping images/views
|
|
59
|
+
- Pointer events for drag with Lerp interpolation (speed: 0.15)
|
|
60
|
+
- clip-path animation reveals before/after content
|
|
61
|
+
- Touch-friendly with full pointer event support
|
|
62
|
+
|
|
63
|
+
**State Machine**:
|
|
64
|
+
```
|
|
65
|
+
[idle] --(pointerenter)--> [hover]
|
|
66
|
+
[hover] --(pointerdown on divider)--> [dragging]
|
|
67
|
+
[hover] --(pointerleave)--> [idle]
|
|
68
|
+
[dragging] --(pointermove)--> [dragging] (update position)
|
|
69
|
+
[dragging] --(pointerup)--> [settling]
|
|
70
|
+
[settling] --(lerp-complete)--> [idle]
|
|
71
|
+
[any] --(focus + ArrowLeft/Right)--> [keyboard-adjusting]
|
|
72
|
+
[keyboard-adjusting] --(keyup)--> [idle]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Browser APIs**: Pointer Events, CSS clip-path, ResizeObserver, requestAnimationFrame
|
|
76
|
+
|
|
77
|
+
**Animation**:
|
|
78
|
+
- Divider follow: Lerp `current += (target - current) * 0.15` per frame
|
|
79
|
+
- Clip-path update: `clip-path: inset(0 0 0 ${position}%)` on after layer
|
|
80
|
+
- Settle: natural Lerp deceleration to final position
|
|
81
|
+
- Hover hint: divider scale(1.1) + glow (200ms, ease-out)
|
|
82
|
+
|
|
83
|
+
**CSS Key Properties**:
|
|
84
|
+
```css
|
|
85
|
+
.split-compare__after {
|
|
86
|
+
clip-path: inset(0 0 0 var(--split-position, 50%));
|
|
87
|
+
transition: none; /* JS-driven via lerp */
|
|
88
|
+
}
|
|
89
|
+
.split-compare__divider {
|
|
90
|
+
cursor: col-resize;
|
|
91
|
+
touch-action: none; /* prevent scroll during drag */
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Keyboard**:
|
|
96
|
+
- Tab to divider element (tabindex="0")
|
|
97
|
+
- ArrowLeft/ArrowRight: move divider 2% per keypress
|
|
98
|
+
- Home/End: move to 0%/100%
|
|
99
|
+
|
|
100
|
+
**Accessibility**:
|
|
101
|
+
- role="slider", aria-valuenow, aria-valuemin="0", aria-valuemax="100"
|
|
102
|
+
- aria-label="Image comparison slider"
|
|
103
|
+
- Keyboard step: 2%, large step (PageUp/PageDown): 10%
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Scroll-Snap Gallery Pattern
|
|
108
|
+
|
|
109
|
+
Horizontal scroll with CSS scroll-snap, navigation controls, and active item detection.
|
|
110
|
+
|
|
111
|
+
**Core Interaction**:
|
|
112
|
+
- CSS scroll-snap-type: x mandatory on container
|
|
113
|
+
- scroll-snap-align: start on children
|
|
114
|
+
- Touch-friendly: native momentum scrolling
|
|
115
|
+
- Navigation dots/arrows update with IntersectionObserver
|
|
116
|
+
- Keyboard: ArrowLeft/ArrowRight navigate between items
|
|
117
|
+
|
|
118
|
+
**State Machine**:
|
|
119
|
+
```
|
|
120
|
+
[idle] --(scroll-start)--> [scrolling]
|
|
121
|
+
[scrolling] --(scroll-end)--> [snapped]
|
|
122
|
+
[snapped] --(intersection-change)--> [idle] (update active)
|
|
123
|
+
[idle] --(arrow-click)--> [navigating]
|
|
124
|
+
[navigating] --(scrollTo-complete)--> [idle]
|
|
125
|
+
[idle] --(keyboard-arrow)--> [navigating]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Browser APIs**: CSS scroll-snap, IntersectionObserver, Element.scrollTo(), Pointer Events
|
|
129
|
+
|
|
130
|
+
**Animation**:
|
|
131
|
+
- Scroll: native CSS scroll-snap (browser-handled, smooth)
|
|
132
|
+
- Active dot: scale(1) -> scale(1.3) + opacity change (200ms, ease-out)
|
|
133
|
+
- Item entry: opacity 0->1 as intersection threshold crossed (CSS transition)
|
|
134
|
+
- Arrow hover: translateX(+-2px) (150ms, ease-out)
|
|
135
|
+
|
|
136
|
+
**CSS Key Properties**:
|
|
137
|
+
```css
|
|
138
|
+
.gallery__track {
|
|
139
|
+
display: flex;
|
|
140
|
+
overflow-x: auto;
|
|
141
|
+
scroll-snap-type: x mandatory;
|
|
142
|
+
scroll-behavior: smooth;
|
|
143
|
+
-webkit-overflow-scrolling: touch;
|
|
144
|
+
scrollbar-width: none; /* Firefox */
|
|
145
|
+
}
|
|
146
|
+
.gallery__track::-webkit-scrollbar { display: none; }
|
|
147
|
+
.gallery__item {
|
|
148
|
+
scroll-snap-align: start;
|
|
149
|
+
flex: 0 0 100%; /* or 80% for peek */
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**IntersectionObserver Config**:
|
|
154
|
+
```javascript
|
|
155
|
+
new IntersectionObserver(entries => {
|
|
156
|
+
entries.forEach(entry => {
|
|
157
|
+
if (entry.isIntersecting) updateActiveItem(entry.target);
|
|
158
|
+
});
|
|
159
|
+
}, { root: trackElement, threshold: 0.5 });
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Accessibility**:
|
|
163
|
+
- role="region", aria-label="Image gallery"
|
|
164
|
+
- role="group" on each item, aria-roledescription="slide"
|
|
165
|
+
- aria-label="Slide N of M" on each item
|
|
166
|
+
- Navigation: role="tablist" on dots, role="tab" on each dot
|
|
167
|
+
- ArrowLeft/ArrowRight between items, Home/End to first/last
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Scroll Reveal Pattern
|
|
172
|
+
|
|
173
|
+
Elements animate into view as user scrolls, using IntersectionObserver with staggered delays.
|
|
174
|
+
|
|
175
|
+
**Core Interaction**:
|
|
176
|
+
- IntersectionObserver with threshold: 0.1 triggers entry animation
|
|
177
|
+
- data-reveal attribute marks revealable elements
|
|
178
|
+
- Staggered delay: index * 80ms for grouped items
|
|
179
|
+
- GPU-only: translateY(20px)->0 + opacity 0->1
|
|
180
|
+
- One-shot: element stays visible after reveal
|
|
181
|
+
|
|
182
|
+
**State Machine**:
|
|
183
|
+
```
|
|
184
|
+
[hidden] --(intersection: entering)--> [revealing]
|
|
185
|
+
[revealing] --(animation-end)--> [visible]
|
|
186
|
+
[visible] -- (terminal state, no transition out)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Browser APIs**: IntersectionObserver, CSS transitions, requestAnimationFrame
|
|
190
|
+
|
|
191
|
+
**Animation**:
|
|
192
|
+
- Entry: translateY(20px) -> translateY(0) + opacity 0->1
|
|
193
|
+
- Duration: 400ms
|
|
194
|
+
- Easing: cubic-bezier(0.16, 1, 0.3, 1)
|
|
195
|
+
- Stagger: CSS custom property `--reveal-delay: calc(var(--reveal-index) * 80ms)`
|
|
196
|
+
- Reduced motion: opacity-only crossfade (200ms)
|
|
197
|
+
|
|
198
|
+
**CSS Key Properties**:
|
|
199
|
+
```css
|
|
200
|
+
[data-reveal] {
|
|
201
|
+
opacity: 0;
|
|
202
|
+
transform: translateY(20px);
|
|
203
|
+
transition: opacity 400ms cubic-bezier(0.16, 1, 0.3, 1),
|
|
204
|
+
transform 400ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
205
|
+
transition-delay: var(--reveal-delay, 0ms);
|
|
206
|
+
}
|
|
207
|
+
[data-reveal="visible"] {
|
|
208
|
+
opacity: 1;
|
|
209
|
+
transform: translateY(0);
|
|
210
|
+
}
|
|
211
|
+
@media (prefers-reduced-motion: reduce) {
|
|
212
|
+
[data-reveal] {
|
|
213
|
+
transform: none;
|
|
214
|
+
transition: opacity 200ms ease;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**IntersectionObserver Config**:
|
|
220
|
+
```javascript
|
|
221
|
+
new IntersectionObserver(entries => {
|
|
222
|
+
entries.forEach(entry => {
|
|
223
|
+
if (entry.isIntersecting) {
|
|
224
|
+
entry.target.dataset.reveal = 'visible';
|
|
225
|
+
observer.unobserve(entry.target); // one-shot
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}, { threshold: 0.1 });
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Accessibility**:
|
|
232
|
+
- Content must be accessible in DOM before reveal (no display:none)
|
|
233
|
+
- Use opacity + transform only (content readable by screen readers at all times)
|
|
234
|
+
- aria-hidden NOT used (content is always in accessibility tree)
|
|
235
|
+
- Stagger delay < 500ms total to avoid perception of broken page
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Lens/Overlay Pattern
|
|
240
|
+
|
|
241
|
+
Magnification overlay that follows pointer position over an image or content area.
|
|
242
|
+
|
|
243
|
+
**Core Interaction**:
|
|
244
|
+
- Circular/rectangular lens follows pointer over source content
|
|
245
|
+
- Magnified view rendered via CSS transform: scale() on background
|
|
246
|
+
- Lens positioned via transform: translate() (GPU-only)
|
|
247
|
+
- Toggle on click/tap, follow on pointermove
|
|
248
|
+
|
|
249
|
+
**State Machine**:
|
|
250
|
+
```
|
|
251
|
+
[inactive] --(click/tap on source)--> [active]
|
|
252
|
+
[active] --(pointermove)--> [active] (update lens position)
|
|
253
|
+
[active] --(click/tap)--> [inactive]
|
|
254
|
+
[active] --(pointerleave)--> [inactive]
|
|
255
|
+
[active] --(Escape)--> [inactive]
|
|
256
|
+
[inactive] --(Enter/Space on source)--> [active-keyboard]
|
|
257
|
+
[active-keyboard] --(Arrow keys)--> [active-keyboard] (move lens)
|
|
258
|
+
[active-keyboard] --(Escape)--> [inactive]
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Browser APIs**: Pointer Events, CSS transform, CSS clip-path/border-radius, requestAnimationFrame
|
|
262
|
+
|
|
263
|
+
**Animation**:
|
|
264
|
+
- Lens appear: opacity 0->1 + scale(0.8)->scale(1) (200ms, ease-out)
|
|
265
|
+
- Lens follow: Lerp position tracking (speed: 0.2)
|
|
266
|
+
- Lens dismiss: opacity 1->0 + scale(1)->scale(0.9) (150ms, ease-in)
|
|
267
|
+
|
|
268
|
+
**CSS Key Properties**:
|
|
269
|
+
```css
|
|
270
|
+
.lens__overlay {
|
|
271
|
+
position: absolute;
|
|
272
|
+
width: 150px;
|
|
273
|
+
height: 150px;
|
|
274
|
+
border-radius: 50%;
|
|
275
|
+
overflow: hidden;
|
|
276
|
+
pointer-events: none;
|
|
277
|
+
transform: translate(var(--lens-x), var(--lens-y));
|
|
278
|
+
will-change: transform;
|
|
279
|
+
}
|
|
280
|
+
.lens__magnified {
|
|
281
|
+
transform: scale(var(--lens-zoom, 2));
|
|
282
|
+
transform-origin: var(--lens-origin-x) var(--lens-origin-y);
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Accessibility**:
|
|
287
|
+
- Source: role="img" with descriptive aria-label
|
|
288
|
+
- Lens toggle: aria-expanded on source element
|
|
289
|
+
- Keyboard: Enter/Space to activate, Arrow keys to pan, Escape to dismiss
|
|
290
|
+
- Screen reader: aria-live="polite" announces zoom state changes
|
|
291
|
+
- Not essential content: decorative enhancement, base content always visible
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Lightbox Pattern
|
|
296
|
+
|
|
297
|
+
Full-viewport overlay for content viewing with background dim and entry animation.
|
|
298
|
+
|
|
299
|
+
**Core Interaction**:
|
|
300
|
+
- Click/tap thumbnail opens full-viewport overlay
|
|
301
|
+
- Background dim via backdrop-filter + background overlay
|
|
302
|
+
- Scale-up entry animation from thumbnail position
|
|
303
|
+
- Dismiss: click outside, Escape key, close button
|
|
304
|
+
- Focus trap: Tab cycles within lightbox
|
|
305
|
+
- Scroll lock on body while open
|
|
306
|
+
|
|
307
|
+
**State Machine**:
|
|
308
|
+
```
|
|
309
|
+
[closed] --(click thumbnail)--> [opening]
|
|
310
|
+
[opening] --(animation-end)--> [open]
|
|
311
|
+
[open] --(click-outside / Escape / close-btn)--> [closing]
|
|
312
|
+
[closing] --(animation-end)--> [closed]
|
|
313
|
+
[open] --(ArrowLeft)--> [navigating-prev]
|
|
314
|
+
[open] --(ArrowRight)--> [navigating-next]
|
|
315
|
+
[navigating-*] --(content-loaded)--> [open]
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Browser APIs**: CSS backdrop-filter, Focus trap (manual), CSS transitions, Pointer Events
|
|
319
|
+
|
|
320
|
+
**Animation**:
|
|
321
|
+
- Open: scale(0.85)->scale(1) + opacity 0->1 (300ms, cubic-bezier(0.16,1,0.3,1))
|
|
322
|
+
- Close: scale(1)->scale(0.95) + opacity 1->0 (200ms, ease-in)
|
|
323
|
+
- Backdrop: opacity 0->1 (250ms, ease-out)
|
|
324
|
+
- Navigation: translateX crossfade between items (250ms)
|
|
325
|
+
|
|
326
|
+
**CSS Key Properties**:
|
|
327
|
+
```css
|
|
328
|
+
.lightbox__backdrop {
|
|
329
|
+
position: fixed;
|
|
330
|
+
inset: 0;
|
|
331
|
+
background: rgba(0, 0, 0, 0.8);
|
|
332
|
+
backdrop-filter: blur(4px);
|
|
333
|
+
z-index: 1000;
|
|
334
|
+
}
|
|
335
|
+
.lightbox__content {
|
|
336
|
+
transform: scale(var(--lb-scale, 0.85));
|
|
337
|
+
opacity: var(--lb-opacity, 0);
|
|
338
|
+
transition: transform 300ms cubic-bezier(0.16, 1, 0.3, 1),
|
|
339
|
+
opacity 300ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
340
|
+
}
|
|
341
|
+
.lightbox--open .lightbox__content {
|
|
342
|
+
--lb-scale: 1;
|
|
343
|
+
--lb-opacity: 1;
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**Focus Trap Implementation**:
|
|
348
|
+
```javascript
|
|
349
|
+
// On open: store trigger, move focus to first focusable in lightbox
|
|
350
|
+
// On Tab: cycle within lightbox (first <-> last focusable)
|
|
351
|
+
// On close: restore focus to original trigger element
|
|
352
|
+
// Prevent body scroll: document.body.style.overflow = 'hidden'
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Accessibility**:
|
|
356
|
+
- role="dialog", aria-modal="true", aria-label="Image viewer"
|
|
357
|
+
- Close button: aria-label="Close lightbox"
|
|
358
|
+
- Focus trap: Tab cycles within dialog
|
|
359
|
+
- Escape dismisses
|
|
360
|
+
- ArrowLeft/ArrowRight for gallery navigation
|
|
361
|
+
- aria-live="polite" announces current item "Image N of M"
|
|
362
|
+
- Scroll lock: prevent background scroll while open
|