claude-code-workflow 7.2.27 → 7.2.29
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/brainstorm/SKILL.md +3 -3
- package/.codex/skills/clean/SKILL.md +3 -3
- 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/issue-discover/SKILL.md +13 -13
- package/.codex/skills/issue-discover/phases/02-discover.md +4 -4
- package/.codex/skills/issue-discover/phases/03-discover-by-prompt.md +3 -3
- package/.codex/skills/parallel-dev-cycle/SKILL.md +4 -4
- package/.codex/skills/parallel-dev-cycle/phases/02-agent-execution.md +6 -6
- package/.codex/skills/parallel-dev-cycle/phases/03-result-aggregation.md +10 -10
- package/.codex/skills/review-cycle/SKILL.md +10 -10
- package/.codex/skills/review-cycle/phases/02-parallel-review.md +6 -6
- package/.codex/skills/review-cycle/phases/04-iterative-deep-dive.md +4 -4
- package/.codex/skills/review-cycle/phases/07-fix-parallel-planning.md +4 -4
- package/.codex/skills/review-cycle/phases/08-fix-execution.md +2 -2
- package/.codex/skills/roadmap-with-file/SKILL.md +14 -14
- 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/spec-generator/README.md +1 -1
- package/.codex/skills/spec-generator/SKILL.md +184 -88
- package/.codex/skills/spec-generator/phases/01-5-requirement-clarification.md +4 -7
- package/.codex/skills/spec-generator/phases/01-discovery.md +30 -11
- package/.codex/skills/spec-generator/phases/02-product-brief.md +2 -5
- package/.codex/skills/spec-generator/phases/03-requirements.md +4 -6
- package/.codex/skills/spec-generator/phases/04-architecture.md +4 -6
- package/.codex/skills/spec-generator/phases/05-epics-stories.md +4 -6
- package/.codex/skills/spec-generator/phases/06-5-auto-fix.md +4 -5
- package/.codex/skills/spec-generator/phases/06-readiness-check.md +8 -8
- package/.codex/skills/spec-generator/phases/07-issue-export.md +2 -2
- package/.codex/skills/spec-setup/SKILL.md +4 -4
- 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/.codex/skills/workflow-plan/SKILL.md +6 -6
- package/.codex/skills/workflow-tdd-plan/SKILL.md +5 -5
- package/.codex/skills/workflow-test-fix-cycle/SKILL.md +19 -19
- package/.codex/skills/workflow-test-fix-cycle/phases/01-test-fix-gen.md +5 -5
- package/.codex/skills/workflow-test-fix-cycle/phases/02-test-cycle-execute.md +5 -5
- 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-exlTDW81.js} +3 -3
- package/ccw/frontend/dist/assets/{AlertDialog-Bf1jdqax.js.map → AlertDialog-exlTDW81.js.map} +1 -1
- package/ccw/frontend/dist/assets/{AnalysisPage-C8niKdp4.js → AnalysisPage-cgV9LfAI.js} +2 -2
- package/ccw/frontend/dist/assets/{AnalysisPage-C8niKdp4.js.map → AnalysisPage-cgV9LfAI.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ApiSettingsPage-BL2c3UNS.js → ApiSettingsPage-Dk5jJdWt.js} +2 -2
- package/ccw/frontend/dist/assets/{ApiSettingsPage-BL2c3UNS.js.map → ApiSettingsPage-Dk5jJdWt.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliModeToggle-BePBFynD.js → CliModeToggle-Be9xsPiv.js} +2 -2
- package/ccw/frontend/dist/assets/{CliModeToggle-BePBFynD.js.map → CliModeToggle-Be9xsPiv.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliSessionSharePage-7cYtX6FT.js → CliSessionSharePage-Bh9jBtPI.js} +2 -2
- package/ccw/frontend/dist/assets/{CliSessionSharePage-7cYtX6FT.js.map → CliSessionSharePage-Bh9jBtPI.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliViewerPage-CBwg1mPL.js → CliViewerPage-BrE-oyEq.js} +2 -2
- package/ccw/frontend/dist/assets/{CliViewerPage-CBwg1mPL.js.map → CliViewerPage-BrE-oyEq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CodexLensPage-Bt74xORP.js → CodexLensPage-Cd3nrC93.js} +2 -2
- package/ccw/frontend/dist/assets/{CodexLensPage-Bt74xORP.js.map → CodexLensPage-Cd3nrC93.js.map} +1 -1
- package/ccw/frontend/dist/assets/{Collapsible-Wrs87QT7.js → Collapsible-DXFl3VKF.js} +2 -2
- package/ccw/frontend/dist/assets/{Collapsible-Wrs87QT7.js.map → Collapsible-DXFl3VKF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CommandsManagerPage-ChQjmPWZ.js → CommandsManagerPage-IV8zpjgX.js} +2 -2
- package/ccw/frontend/dist/assets/{CommandsManagerPage-ChQjmPWZ.js.map → CommandsManagerPage-IV8zpjgX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{DeepWikiPage-dEO5wi6X.js → DeepWikiPage-CpDxtmRX.js} +2 -2
- package/ccw/frontend/dist/assets/{DeepWikiPage-dEO5wi6X.js.map → DeepWikiPage-CpDxtmRX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{EndpointsPage-4zq269xY.js → EndpointsPage-BchjWe7s.js} +2 -2
- package/ccw/frontend/dist/assets/{EndpointsPage-4zq269xY.js.map → EndpointsPage-BchjWe7s.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ExplorerPage-B0YTENhA.js → ExplorerPage-CbWvaJ0y.js} +2 -2
- package/ccw/frontend/dist/assets/{ExplorerPage-B0YTENhA.js.map → ExplorerPage-CbWvaJ0y.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FixSessionPage-CwGs6dhz.js → FixSessionPage-YMjVRiCk.js} +2 -2
- package/ccw/frontend/dist/assets/{FixSessionPage-CwGs6dhz.js.map → FixSessionPage-YMjVRiCk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-COZRBslc.js → FloatingFileBrowser-JW2ehYY_.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-COZRBslc.js.map → FloatingFileBrowser-JW2ehYY_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingPanel-DYvgQZRD.js → FloatingPanel-BtqzqDVq.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingPanel-DYvgQZRD.js.map → FloatingPanel-BtqzqDVq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{GraphExplorerPage-ewMHQGem.js → GraphExplorerPage-BsJL_W4d.js} +3 -3
- package/ccw/frontend/dist/assets/{GraphExplorerPage-ewMHQGem.js.map → GraphExplorerPage-BsJL_W4d.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HistoryPage-BMeR0PrK.js → HistoryPage-BuWpQ7k5.js} +2 -2
- package/ccw/frontend/dist/assets/{HistoryPage-BMeR0PrK.js.map → HistoryPage-BuWpQ7k5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HookManagerPage-DBW2LnRm.js → HookManagerPage-D0BtMIWy.js} +2 -2
- package/ccw/frontend/dist/assets/{HookManagerPage-DBW2LnRm.js.map → HookManagerPage-D0BtMIWy.js.map} +1 -1
- package/ccw/frontend/dist/assets/{InstallationsPage--pMj0QEH.js → InstallationsPage-C7dwsAKG.js} +2 -2
- package/ccw/frontend/dist/assets/{InstallationsPage--pMj0QEH.js.map → InstallationsPage-C7dwsAKG.js.map} +1 -1
- package/ccw/frontend/dist/assets/{IssueHubPage-C_QMpQSR.js → IssueHubPage-D0nCNaeB.js} +2 -2
- package/ccw/frontend/dist/assets/{IssueHubPage-C_QMpQSR.js.map → IssueHubPage-D0nCNaeB.js.map} +1 -1
- package/ccw/frontend/dist/assets/{LiteTasksPage-CSWFdQ2-.js → LiteTasksPage-B5c2Kb9r.js} +3 -3
- package/ccw/frontend/dist/assets/{LiteTasksPage-CSWFdQ2-.js.map → LiteTasksPage-B5c2Kb9r.js.map} +1 -1
- package/ccw/frontend/dist/assets/{McpManagerPage-Dvv8NtGy.js → McpManagerPage-C-S5CehM.js} +2 -2
- package/ccw/frontend/dist/assets/{McpManagerPage-Dvv8NtGy.js.map → McpManagerPage-C-S5CehM.js.map} +1 -1
- package/ccw/frontend/dist/assets/{MemoryPage-YO8WZzZO.js → MemoryPage-P_B0JVUQ.js} +2 -2
- package/ccw/frontend/dist/assets/{MemoryPage-YO8WZzZO.js.map → MemoryPage-P_B0JVUQ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{NotFoundPage-quUJw0CD.js → NotFoundPage-S4Jn9LUE.js} +2 -2
- package/ccw/frontend/dist/assets/{NotFoundPage-quUJw0CD.js.map → NotFoundPage-S4Jn9LUE.js.map} +1 -1
- package/ccw/frontend/dist/assets/{OrchestratorPage-tuThWPID.js → OrchestratorPage-C2Zlr7AC.js} +2 -2
- package/ccw/frontend/dist/assets/{OrchestratorPage-tuThWPID.js.map → OrchestratorPage-C2Zlr7AC.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-shTilwiT.js → ProjectOverviewPage-CMVfz8s5.js} +2 -2
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-shTilwiT.js.map → ProjectOverviewPage-CMVfz8s5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{PromptHistoryPage-6rQnsI8l.js → PromptHistoryPage-YEMjFARX.js} +3 -3
- package/ccw/frontend/dist/assets/{PromptHistoryPage-6rQnsI8l.js.map → PromptHistoryPage-YEMjFARX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ReviewSessionPage-JOmzjVbT.js → ReviewSessionPage-DnTm55nG.js} +2 -2
- package/ccw/frontend/dist/assets/{ReviewSessionPage-JOmzjVbT.js.map → ReviewSessionPage-DnTm55nG.js.map} +1 -1
- package/ccw/frontend/dist/assets/{RulesManagerPage-Cayfywqi.js → RulesManagerPage-CUwebtO2.js} +2 -2
- package/ccw/frontend/dist/assets/{RulesManagerPage-Cayfywqi.js.map → RulesManagerPage-CUwebtO2.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionDetailPage-iMn0k84i.js → SessionDetailPage-0qyH1Z5P.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionDetailPage-iMn0k84i.js.map → SessionDetailPage-0qyH1Z5P.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionsPage-Ciqjy9kz.js → SessionsPage-BpgP4087.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionsPage-Ciqjy9kz.js.map → SessionsPage-BpgP4087.js.map} +1 -1
- package/ccw/frontend/dist/assets/SettingsPage-C3SJajeT.js +150 -0
- package/ccw/frontend/dist/assets/SettingsPage-C3SJajeT.js.map +1 -0
- package/ccw/frontend/dist/assets/SkillsManagerPage-vD9PTsmy.js +7 -0
- package/ccw/frontend/dist/assets/SkillsManagerPage-vD9PTsmy.js.map +1 -0
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-BpkJctzo.js → SpecsSettingsPage-DT-yTVkD.js} +4 -4
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-BpkJctzo.js.map → SpecsSettingsPage-DT-yTVkD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{Switch-BpB9h__9.js → Switch-CYSPdqWk.js} +2 -2
- package/ccw/frontend/dist/assets/{Switch-BpB9h__9.js.map → Switch-CYSPdqWk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TabsNavigation-BGsKy7DO.js → TabsNavigation-CPh6Zor1.js} +2 -2
- package/ccw/frontend/dist/assets/{TabsNavigation-BGsKy7DO.js.map → TabsNavigation-CPh6Zor1.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TaskDrawer-bYIlbM0Q.js → TaskDrawer-Ds-8830B.js} +2 -2
- package/ccw/frontend/dist/assets/{TaskDrawer-bYIlbM0Q.js.map → TaskDrawer-Ds-8830B.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TeamPage-CihtQ6LQ.js → TeamPage-CJODUxBk.js} +2 -2
- package/ccw/frontend/dist/assets/{TeamPage-CihtQ6LQ.js.map → TeamPage-CJODUxBk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-BDnNF_ud.js → TerminalDashboardPage-Cn3fGUuO.js} +3 -3
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-BDnNF_ud.js.map → TerminalDashboardPage-Cn3fGUuO.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-CQJ86bQp.js → archive-CjwVpw6k.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-CQJ86bQp.js.map → archive-CjwVpw6k.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-restore-BhTfDbPU.js → archive-restore-2vZa9Ic3.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-restore-BhTfDbPU.js.map → archive-restore-2vZa9Ic3.js.map} +1 -1
- package/ccw/frontend/dist/assets/{arrow-right-eUAZnT9C.js → arrow-right-CUU5XDgT.js} +2 -2
- package/ccw/frontend/dist/assets/{arrow-right-eUAZnT9C.js.map → arrow-right-CUU5XDgT.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bookmark-plus-ilF5-V-k.js → bookmark-plus-Cc3nKRZ5.js} +2 -2
- package/ccw/frontend/dist/assets/{bookmark-plus-ilF5-V-k.js.map → bookmark-plus-Cc3nKRZ5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bot-BLkaQscs.js → bot-BwpSRDUa.js} +2 -2
- package/ccw/frontend/dist/assets/{bot-BLkaQscs.js.map → bot-BwpSRDUa.js.map} +1 -1
- package/ccw/frontend/dist/assets/{braces-D9HdgsO6.js → braces-DBzUW1XC.js} +2 -2
- package/ccw/frontend/dist/assets/{braces-D9HdgsO6.js.map → braces-DBzUW1XC.js.map} +1 -1
- package/ccw/frontend/dist/assets/{circle-stop-C3ZF1okQ.js → circle-stop-CGNNsjvE.js} +2 -2
- package/ccw/frontend/dist/assets/{circle-stop-C3ZF1okQ.js.map → circle-stop-CGNNsjvE.js.map} +1 -1
- package/ccw/frontend/dist/assets/{cpu-B-QjaSjm.js → cpu-D27G86Ul.js} +2 -2
- package/ccw/frontend/dist/assets/{cpu-B-QjaSjm.js.map → cpu-D27G86Ul.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ellipsis-vertical-CbNlw2gS.js → ellipsis-vertical-C1Ij47Yz.js} +2 -2
- package/ccw/frontend/dist/assets/{ellipsis-vertical-CbNlw2gS.js.map → ellipsis-vertical-C1Ij47Yz.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-yAy69Cnn.js → eye-C6MOB7Au.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-yAy69Cnn.js.map → eye-C6MOB7Au.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-off-D5uzLZyP.js → eye-off-BxfBlZ26.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-off-D5uzLZyP.js.map → eye-off-BxfBlZ26.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-json-rwo1NowL.js → file-json-NI237wA-.js} +2 -2
- package/ccw/frontend/dist/assets/{file-json-rwo1NowL.js.map → file-json-NI237wA-.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-text-DRkrjie9.js → file-text-Byn2_2v6.js} +2 -2
- package/ccw/frontend/dist/assets/{file-text-DRkrjie9.js.map → file-text-Byn2_2v6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{filter-BOe-OTu1.js → filter-D-7PhZjx.js} +2 -2
- package/ccw/frontend/dist/assets/{filter-BOe-OTu1.js.map → filter-D-7PhZjx.js.map} +1 -1
- package/ccw/frontend/dist/assets/{folder-BaWZWn_r.js → folder-BoAsK_FL.js} +2 -2
- package/ccw/frontend/dist/assets/{folder-BaWZWn_r.js.map → folder-BoAsK_FL.js.map} +1 -1
- package/ccw/frontend/dist/assets/{gauge-kazFexTr.js → gauge-DCSxJIS4.js} +2 -2
- package/ccw/frontend/dist/assets/{gauge-kazFexTr.js.map → gauge-DCSxJIS4.js.map} +1 -1
- package/ccw/frontend/dist/assets/{globe-BuHeEjxd.js → globe-CHS3prza.js} +2 -2
- package/ccw/frontend/dist/assets/{globe-BuHeEjxd.js.map → globe-CHS3prza.js.map} +1 -1
- package/ccw/frontend/dist/assets/{grid-3x3-DbhuUu4V.js → grid-3x3-D7K35U7S.js} +2 -2
- package/ccw/frontend/dist/assets/{grid-3x3-DbhuUu4V.js.map → grid-3x3-D7K35U7S.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hard-drive-AoLGL0z4.js → hard-drive-eq9xE07G.js} +2 -2
- package/ccw/frontend/dist/assets/{hard-drive-AoLGL0z4.js.map → hard-drive-eq9xE07G.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hash-Dpo1exMB.js → hash-C1DMpBua.js} +2 -2
- package/ccw/frontend/dist/assets/{hash-Dpo1exMB.js.map → hash-C1DMpBua.js.map} +1 -1
- package/ccw/frontend/dist/assets/{history-ujQnmMC9.js → history-Di5SBCY-.js} +2 -2
- package/ccw/frontend/dist/assets/{history-ujQnmMC9.js.map → history-Di5SBCY-.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-C_Yf5fZ4.js → index--_R7COnA.js} +2 -2
- package/ccw/frontend/dist/assets/{index-C_Yf5fZ4.js.map → index--_R7COnA.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-Dff4bg3u.js → index-BUol9HDD.js} +3 -3
- package/ccw/frontend/dist/assets/{index-Dff4bg3u.js.map → index-BUol9HDD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-B76AGix5.js → index-CT9oykfw.js} +2 -2
- package/ccw/frontend/dist/assets/{index-B76AGix5.js.map → index-CT9oykfw.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-CxzXz6o1.js → index-Ddwvf87H.js} +2 -2
- package/ccw/frontend/dist/assets/{index-CxzXz6o1.js.map → index-Ddwvf87H.js.map} +1 -1
- package/ccw/frontend/dist/assets/{layout-grid-CBdE4K8h.js → layout-grid-LiX0qZbN.js} +2 -2
- package/ccw/frontend/dist/assets/{layout-grid-CBdE4K8h.js.map → layout-grid-LiX0qZbN.js.map} +1 -1
- package/ccw/frontend/dist/assets/{lightbulb-B9K6ZgRp.js → lightbulb-CL3DVEwb.js} +2 -2
- package/ccw/frontend/dist/assets/{lightbulb-B9K6ZgRp.js.map → lightbulb-CL3DVEwb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-2-Oea4xHJl.js → link-2-CC5cFeq6.js} +2 -2
- package/ccw/frontend/dist/assets/{link-2-Oea4xHJl.js.map → link-2-CC5cFeq6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-5yXdZBch.js → link-ngFQ9bs0.js} +2 -2
- package/ccw/frontend/dist/assets/{link-5yXdZBch.js.map → link-ngFQ9bs0.js.map} +1 -1
- package/ccw/frontend/dist/assets/{list-9lHhC_U_.js → list-BEU6I0KK.js} +2 -2
- package/ccw/frontend/dist/assets/{list-9lHhC_U_.js.map → list-BEU6I0KK.js.map} +1 -1
- package/ccw/frontend/dist/assets/{map-pin-B6Io5kmB.js → map-pin-BWZdLA6y.js} +2 -2
- package/ccw/frontend/dist/assets/{map-pin-B6Io5kmB.js.map → map-pin-BWZdLA6y.js.map} +1 -1
- package/ccw/frontend/dist/assets/{messages-square-BT000aD3.js → messages-square-K6_Chm7n.js} +2 -2
- package/ccw/frontend/dist/assets/{messages-square-BT000aD3.js.map → messages-square-K6_Chm7n.js.map} +1 -1
- package/ccw/frontend/dist/assets/{minimize-2-DO-zbT3a.js → minimize-2-CWkphauf.js} +2 -2
- package/ccw/frontend/dist/assets/{minimize-2-DO-zbT3a.js.map → minimize-2-CWkphauf.js.map} +1 -1
- package/ccw/frontend/dist/assets/{package-BjOw1ldU.js → package-DrNgkamn.js} +2 -2
- package/ccw/frontend/dist/assets/{package-BjOw1ldU.js.map → package-DrNgkamn.js.map} +1 -1
- package/ccw/frontend/dist/assets/{plug-9dAARpE1.js → plug-CMo3sw5_.js} +2 -2
- package/ccw/frontend/dist/assets/{plug-9dAARpE1.js.map → plug-CMo3sw5_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{power-K2S39x7f.js → power-DppNTW5e.js} +2 -2
- package/ccw/frontend/dist/assets/{power-K2S39x7f.js.map → power-DppNTW5e.js.map} +1 -1
- package/ccw/frontend/dist/assets/{save-D9-CoT3x.js → save-CD8aPMbZ.js} +2 -2
- package/ccw/frontend/dist/assets/{save-D9-CoT3x.js.map → save-CD8aPMbZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{send-Bunw9NtC.js → send-B4z90fQD.js} +2 -2
- package/ccw/frontend/dist/assets/{send-Bunw9NtC.js.map → send-B4z90fQD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{settings-2-osl4EXFf.js → settings-2-CAKRU_QC.js} +2 -2
- package/ccw/frontend/dist/assets/{settings-2-osl4EXFf.js.map → settings-2-CAKRU_QC.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-check-big-Dl5gYkjR.js → square-check-big-KhI3HrzX.js} +2 -2
- package/ccw/frontend/dist/assets/{square-check-big-Dl5gYkjR.js.map → square-check-big-KhI3HrzX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-pen-Bue1chJR.js → square-pen-BtdGIpuq.js} +2 -2
- package/ccw/frontend/dist/assets/{square-pen-Bue1chJR.js.map → square-pen-BtdGIpuq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{star-Bk7EC7FB.js → star-ZoBUkXoD.js} +2 -2
- package/ccw/frontend/dist/assets/{star-Bk7EC7FB.js.map → star-ZoBUkXoD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{style-BbREPmRj.js → style-CltxQP-P.js} +2 -2
- package/ccw/frontend/dist/assets/{style-BbREPmRj.js.map → style-CltxQP-P.js.map} +1 -1
- package/ccw/frontend/dist/assets/{target-CElrCVhR.js → target-C32OUSGf.js} +2 -2
- package/ccw/frontend/dist/assets/{target-CElrCVhR.js.map → target-C32OUSGf.js.map} +1 -1
- package/ccw/frontend/dist/assets/{test-tube-wciJaoas.js → test-tube-0IxoyAVZ.js} +2 -2
- package/ccw/frontend/dist/assets/{test-tube-wciJaoas.js.map → test-tube-0IxoyAVZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{upload-BD1F07wG.js → upload-4eKCkyBn.js} +2 -2
- package/ccw/frontend/dist/assets/{upload-BD1F07wG.js.map → upload-4eKCkyBn.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useApiSettings-D23HVEt8.js → useApiSettings-zLTUWqhi.js} +2 -2
- package/ccw/frontend/dist/assets/{useApiSettings-D23HVEt8.js.map → useApiSettings-zLTUWqhi.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCli-BGDd_lXD.js → useCli-BtN2vpOX.js} +2 -2
- package/ccw/frontend/dist/assets/{useCli-BGDd_lXD.js.map → useCli-BtN2vpOX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCommands-B-m_HxPB.js → useCommands-_spj49qL.js} +2 -2
- package/ccw/frontend/dist/assets/{useCommands-B-m_HxPB.js.map → useCommands-_spj49qL.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useDebounce-Z18-PHZr.js → useDebounce-Bm9KFZvd.js} +2 -2
- package/ccw/frontend/dist/assets/{useDebounce-Z18-PHZr.js.map → useDebounce-Bm9KFZvd.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useFileExplorer-D4gPp-LB.js → useFileExplorer-DOmpm6v9.js} +2 -2
- package/ccw/frontend/dist/assets/{useFileExplorer-D4gPp-LB.js.map → useFileExplorer-DOmpm6v9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useLocale-DJ62jjFa.js → useLocale-D2rj4rea.js} +2 -2
- package/ccw/frontend/dist/assets/{useLocale-DJ62jjFa.js.map → useLocale-D2rj4rea.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSkills-B8NPs9__.js → useSkills-OskEpomF.js} +3 -3
- package/ccw/frontend/dist/assets/{useSkills-B8NPs9__.js.map → useSkills-OskEpomF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSystemSettings-CVi7nKGJ.js → useSystemSettings-BjMgsNSF.js} +2 -2
- package/ccw/frontend/dist/assets/{useSystemSettings-CVi7nKGJ.js.map → useSystemSettings-BjMgsNSF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{wand-sparkles-CLjPiU5w.js → wand-sparkles-CLhyYWa7.js} +2 -2
- package/ccw/frontend/dist/assets/{wand-sparkles-CLjPiU5w.js.map → wand-sparkles-CLhyYWa7.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 +0 -150
- package/ccw/frontend/dist/assets/SettingsPage-BPDbXPSM.js.map +0 -1
- package/ccw/frontend/dist/assets/SkillsManagerPage-D3LzbpJY.js +0 -7
- package/ccw/frontend/dist/assets/SkillsManagerPage-D3LzbpJY.js.map +0 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: typo-auditor
|
|
3
|
+
prefix: TYPO
|
|
4
|
+
inner_loop: false
|
|
5
|
+
message_types: [state_update]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Typography Readability Auditor
|
|
9
|
+
|
|
10
|
+
Typography accessibility audit across all viewports. Font sizes at breakpoints, line-height ratios, clamp() validation, reading width measurement, font loading strategy assessment. Produce detailed typography report with breakpoint-by-breakpoint analysis.
|
|
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
|
+
| Target (URL or file paths) | From task description CONTEXT | Yes |
|
|
19
|
+
| WCAG level (AA/AAA) | From task description CONTEXT | Yes |
|
|
20
|
+
| .msg/meta.json | <session>/.msg/meta.json | No |
|
|
21
|
+
|
|
22
|
+
1. Extract session path, target, and WCAG level from task description
|
|
23
|
+
2. Identify target:
|
|
24
|
+
- URL -> use Chrome DevTools for rendered typography (navigate_page, resize_page, screenshot)
|
|
25
|
+
- File paths -> read CSS/SCSS files directly for typography definitions
|
|
26
|
+
- Full site -> enumerate stylesheets from HTML entry points
|
|
27
|
+
3. Read typography standards from specs/typography-scale.md for reference thresholds
|
|
28
|
+
|
|
29
|
+
## Phase 3: Typography Audit Execution
|
|
30
|
+
|
|
31
|
+
### Step 1: Typography Definition Extraction
|
|
32
|
+
|
|
33
|
+
**Static analysis** (always):
|
|
34
|
+
- Glob for CSS/SCSS/Tailwind files -> extract typography definitions
|
|
35
|
+
- Extract: font-family, font-size, line-height, letter-spacing, font-weight, font-display
|
|
36
|
+
- Parse clamp() functions: `clamp(min, preferred, max)` -> validate min/max bounds
|
|
37
|
+
- Parse @media queries for responsive breakpoints
|
|
38
|
+
- Record source location (file:line) for each rule
|
|
39
|
+
|
|
40
|
+
**Runtime analysis** (if Chrome DevTools available):
|
|
41
|
+
- Navigate to target URL
|
|
42
|
+
- For each breakpoint (320px, 768px, 1024px, 1400px):
|
|
43
|
+
- `mcp__chrome-devtools__resize_page({ width: <breakpoint>, height: 900 })`
|
|
44
|
+
- `mcp__chrome-devtools__evaluate_script({ expression: "..." })` to measure:
|
|
45
|
+
- Computed font-size on body, headings (h1-h6), paragraphs, captions
|
|
46
|
+
- Computed line-height on same elements
|
|
47
|
+
- Container width and character count per line
|
|
48
|
+
- `mcp__chrome-devtools__take_screenshot({})` -> save to `<session>/evidence/typo-{breakpoint}px.png`
|
|
49
|
+
|
|
50
|
+
### Step 2: Font Size Audit
|
|
51
|
+
|
|
52
|
+
| Breakpoint | Element | Minimum Size | Standard |
|
|
53
|
+
|-----------|---------|-------------|----------|
|
|
54
|
+
| 320px (mobile) | Body text | 16px | WCAG 1.4.4 |
|
|
55
|
+
| 320px (mobile) | Small/caption | 14px | Best practice |
|
|
56
|
+
| 768px (tablet) | Body text | 16px | WCAG 1.4.4 |
|
|
57
|
+
| 1024px (desktop) | Body text | 16px | WCAG 1.4.4 |
|
|
58
|
+
| 1400px (wide) | Body text | 16px | WCAG 1.4.4 |
|
|
59
|
+
|
|
60
|
+
**clamp() validation**:
|
|
61
|
+
- Minimum value >= 14px (absolute floor)
|
|
62
|
+
- Maximum value reasonable for element type (headings: max ~72px, body: max ~20px)
|
|
63
|
+
- Preferred value uses viewport unit (vw) for fluid scaling
|
|
64
|
+
- Check: `clamp(min, preferred, max)` where min >= 14px for any text
|
|
65
|
+
|
|
66
|
+
**200% zoom check** (WCAG 1.4.4):
|
|
67
|
+
- At 200% zoom, no content should be clipped or lost
|
|
68
|
+
- Text should reflow without horizontal scrolling
|
|
69
|
+
|
|
70
|
+
### Step 3: Line Height Audit
|
|
71
|
+
|
|
72
|
+
| Element Type | Expected Range | Standard |
|
|
73
|
+
|-------------|---------------|----------|
|
|
74
|
+
| Body text | 1.5 - 1.75 | WCAG 1.4.12, readability |
|
|
75
|
+
| Headings | 1.1 - 1.3 | Visual impact |
|
|
76
|
+
| Code blocks | 1.5 - 1.7 | Scanning readability |
|
|
77
|
+
| Buttons/labels | 1.2 - 1.5 | UI element |
|
|
78
|
+
|
|
79
|
+
Check for unitless line-height (preferred over px/em for inheritance).
|
|
80
|
+
|
|
81
|
+
### Step 4: Letter Spacing Audit
|
|
82
|
+
|
|
83
|
+
| Element Type | Expected Range | Standard |
|
|
84
|
+
|-------------|---------------|----------|
|
|
85
|
+
| Display headings | -0.02em to 0 | Tight for visual |
|
|
86
|
+
| Body text | 0 (default) | Normal |
|
|
87
|
+
| Uppercase labels | 0.05em - 0.1em | Legibility |
|
|
88
|
+
| Monospace code | 0.08em - 0.15em | Wide for scanning |
|
|
89
|
+
|
|
90
|
+
**WCAG 1.4.12 override test**: Text must remain readable when user overrides:
|
|
91
|
+
- Line height to at least 1.5x font size
|
|
92
|
+
- Letter spacing to at least 0.12em
|
|
93
|
+
- Word spacing to at least 0.16em
|
|
94
|
+
|
|
95
|
+
### Step 5: Reading Width Audit
|
|
96
|
+
|
|
97
|
+
Measure characters per line for body text containers:
|
|
98
|
+
|
|
99
|
+
| Metric | Optimal | Acceptable | Flag |
|
|
100
|
+
|--------|---------|-----------|------|
|
|
101
|
+
| Characters per line | 66ch | 45-75ch | < 45 or > 75 |
|
|
102
|
+
| Max container width | 65ch-75ch | Up to 900px | > 900px without column |
|
|
103
|
+
|
|
104
|
+
Check: `max-width` or `width` on body text containers.
|
|
105
|
+
|
|
106
|
+
### Step 6: Font Loading Strategy
|
|
107
|
+
|
|
108
|
+
| Property | Good | Acceptable | Poor |
|
|
109
|
+
|----------|------|-----------|------|
|
|
110
|
+
| Body font | `font-display: swap` | `font-display: fallback` | `font-display: block` or missing |
|
|
111
|
+
| Display font | `font-display: optional` | `font-display: swap` | `font-display: block` |
|
|
112
|
+
| Preload | Critical fonts preloaded | Some preloaded | None preloaded |
|
|
113
|
+
| Fallback stack | System font fallback defined | Generic fallback | No fallback |
|
|
114
|
+
|
|
115
|
+
Check for FOUT (Flash of Unstyled Text) / FOIT (Flash of Invisible Text) risks.
|
|
116
|
+
|
|
117
|
+
## Phase 4: Report Generation & Output
|
|
118
|
+
|
|
119
|
+
1. Write audit report to `<session>/audits/typography/typo-audit-{NNN}.md`:
|
|
120
|
+
|
|
121
|
+
```markdown
|
|
122
|
+
# Typography Accessibility Audit - {NNN}
|
|
123
|
+
[typo-auditor]
|
|
124
|
+
|
|
125
|
+
## Summary
|
|
126
|
+
- **Total typography rules audited**: {count}
|
|
127
|
+
- **Pass**: {pass_count} | **Fail**: {fail_count}
|
|
128
|
+
- **WCAG Level**: {AA|AAA}
|
|
129
|
+
- **Critical issues**: {count}
|
|
130
|
+
- **High issues**: {count}
|
|
131
|
+
|
|
132
|
+
## Font Size by Breakpoint
|
|
133
|
+
| Breakpoint | Element | Computed Size | Min Required | Status |
|
|
134
|
+
|-----------|---------|--------------|-------------|--------|
|
|
135
|
+
| 320px | body | Xpx | 16px | PASS/FAIL |
|
|
136
|
+
| 320px | h1 | Xpx | -- | OK |
|
|
137
|
+
| ... | ... | ... | ... | ... |
|
|
138
|
+
|
|
139
|
+
## clamp() Validation
|
|
140
|
+
| Rule | clamp() Value | Min | Max | Status |
|
|
141
|
+
|------|--------------|-----|-----|--------|
|
|
142
|
+
| .body | clamp(1rem, 2vw, 1.25rem) | 16px | 20px | PASS/FAIL |
|
|
143
|
+
| ... | ... | ... | ... | ... |
|
|
144
|
+
|
|
145
|
+
## Line Height Audit
|
|
146
|
+
| Element | Current | Expected Range | Status |
|
|
147
|
+
|---------|---------|---------------|--------|
|
|
148
|
+
| body | 1.6 | 1.5-1.75 | PASS |
|
|
149
|
+
| h1 | 1.2 | 1.1-1.3 | PASS |
|
|
150
|
+
| ... | ... | ... | ... |
|
|
151
|
+
|
|
152
|
+
## Letter Spacing Audit
|
|
153
|
+
| Element | Current | Expected Range | Status |
|
|
154
|
+
|---------|---------|---------------|--------|
|
|
155
|
+
| ... | ... | ... | ... |
|
|
156
|
+
|
|
157
|
+
## Reading Width
|
|
158
|
+
| Container | Width | Chars/Line | Optimal (45-75) | Status |
|
|
159
|
+
|-----------|-------|-----------|-----------------|--------|
|
|
160
|
+
| .content | 700px | ~68ch | Yes | PASS |
|
|
161
|
+
| ... | ... | ... | ... | ... |
|
|
162
|
+
|
|
163
|
+
## Font Loading
|
|
164
|
+
| Font | font-display | Preload | Fallback | Status |
|
|
165
|
+
|------|-------------|---------|----------|--------|
|
|
166
|
+
| ... | swap | yes/no | system | PASS/FAIL |
|
|
167
|
+
|
|
168
|
+
## Text Spacing Override Test (WCAG 1.4.12)
|
|
169
|
+
| Override | Applied | Content Readable | Status |
|
|
170
|
+
|---------|---------|-----------------|--------|
|
|
171
|
+
| line-height: 1.5x | Yes | Yes/No | PASS/FAIL |
|
|
172
|
+
| letter-spacing: 0.12em | Yes | Yes/No | PASS/FAIL |
|
|
173
|
+
| word-spacing: 0.16em | Yes | Yes/No | PASS/FAIL |
|
|
174
|
+
|
|
175
|
+
## Issues (by severity)
|
|
176
|
+
### Critical
|
|
177
|
+
- ...
|
|
178
|
+
### High
|
|
179
|
+
- ...
|
|
180
|
+
### Medium
|
|
181
|
+
- ...
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
2. Update `<session>/.msg/meta.json` under `typo-auditor` namespace:
|
|
185
|
+
- Read existing -> merge `{ "typo-auditor": { audit_id, total_rules, pass_count, fail_count, critical_count, high_count, breakpoints_tested, timestamp } }` -> write back
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# Focus Management Patterns
|
|
2
|
+
|
|
3
|
+
Reference guide for focus indicator styles, skip links, focus traps, and ARIA patterns. Used by focus-auditor and fix-implementer roles.
|
|
4
|
+
|
|
5
|
+
## Focus Indicator Style
|
|
6
|
+
|
|
7
|
+
### Recommended Pattern
|
|
8
|
+
|
|
9
|
+
```css
|
|
10
|
+
/* Keyboard focus: visible outline */
|
|
11
|
+
:focus-visible {
|
|
12
|
+
outline: 2px solid var(--color-accent);
|
|
13
|
+
outline-offset: 2px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* Mouse click: no outline */
|
|
17
|
+
:focus:not(:focus-visible) {
|
|
18
|
+
outline: none;
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Requirements
|
|
23
|
+
|
|
24
|
+
| Property | Minimum | Rationale |
|
|
25
|
+
|----------|---------|-----------|
|
|
26
|
+
| outline-width | 2px | Visibility at distance |
|
|
27
|
+
| outline-style | solid | Consistent rendering |
|
|
28
|
+
| outline-offset | 2px | Separation from element edge |
|
|
29
|
+
| Contrast vs adjacent | >= 3:1 | WCAG 2.4.11 |
|
|
30
|
+
|
|
31
|
+
### Anti-Patterns (Do NOT)
|
|
32
|
+
|
|
33
|
+
```css
|
|
34
|
+
/* BAD: Removes all focus indicators */
|
|
35
|
+
*:focus { outline: none; }
|
|
36
|
+
|
|
37
|
+
/* BAD: Removes focus without alternative */
|
|
38
|
+
button:focus { outline: 0; }
|
|
39
|
+
|
|
40
|
+
/* BAD: Only uses box-shadow (invisible in high contrast mode) */
|
|
41
|
+
:focus-visible { outline: none; box-shadow: 0 0 0 2px blue; }
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Correct Alternative Indicator
|
|
45
|
+
|
|
46
|
+
```css
|
|
47
|
+
/* If not using outline, MUST provide visible alternative */
|
|
48
|
+
:focus-visible {
|
|
49
|
+
outline: 2px solid transparent; /* For Windows high contrast mode */
|
|
50
|
+
box-shadow: 0 0 0 2px var(--color-accent);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Skip Link
|
|
55
|
+
|
|
56
|
+
### HTML
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<body>
|
|
60
|
+
<a href="#main" class="skip-link">Skip to main content</a>
|
|
61
|
+
<!-- navigation, header, etc. -->
|
|
62
|
+
<main id="main" tabindex="-1">
|
|
63
|
+
<!-- main content -->
|
|
64
|
+
</main>
|
|
65
|
+
</body>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### CSS
|
|
69
|
+
|
|
70
|
+
```css
|
|
71
|
+
.skip-link {
|
|
72
|
+
position: absolute;
|
|
73
|
+
left: -9999px;
|
|
74
|
+
top: auto;
|
|
75
|
+
width: 1px;
|
|
76
|
+
height: 1px;
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
z-index: -1;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.skip-link:focus {
|
|
82
|
+
position: fixed;
|
|
83
|
+
left: 16px;
|
|
84
|
+
top: 16px;
|
|
85
|
+
width: auto;
|
|
86
|
+
height: auto;
|
|
87
|
+
overflow: visible;
|
|
88
|
+
z-index: 9999;
|
|
89
|
+
background: var(--color-paper, #fff);
|
|
90
|
+
color: var(--color-ink, #000);
|
|
91
|
+
padding: 8px 16px;
|
|
92
|
+
border: 2px solid var(--color-ink, #000);
|
|
93
|
+
border-radius: 4px;
|
|
94
|
+
font-size: 1rem;
|
|
95
|
+
text-decoration: underline;
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Requirements
|
|
100
|
+
|
|
101
|
+
| Check | Requirement |
|
|
102
|
+
|-------|-------------|
|
|
103
|
+
| Position | First focusable element in DOM |
|
|
104
|
+
| Default state | Visually hidden (not display:none or visibility:hidden) |
|
|
105
|
+
| Focus state | Visible, fixed position, high z-index |
|
|
106
|
+
| Target | Points to main content area with valid ID |
|
|
107
|
+
| Contrast | Link text meets 4.5:1 contrast against background |
|
|
108
|
+
|
|
109
|
+
## Focus Trap (Modals/Dialogs)
|
|
110
|
+
|
|
111
|
+
### Implementation Pattern
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
function trapFocus(dialog) {
|
|
115
|
+
const focusableSelector = [
|
|
116
|
+
'a[href]', 'button:not([disabled])', 'input:not([disabled])',
|
|
117
|
+
'select:not([disabled])', 'textarea:not([disabled])',
|
|
118
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
119
|
+
].join(', ');
|
|
120
|
+
|
|
121
|
+
const focusableElements = dialog.querySelectorAll(focusableSelector);
|
|
122
|
+
const firstFocusable = focusableElements[0];
|
|
123
|
+
const lastFocusable = focusableElements[focusableElements.length - 1];
|
|
124
|
+
|
|
125
|
+
// Store trigger for focus restore
|
|
126
|
+
const trigger = document.activeElement;
|
|
127
|
+
|
|
128
|
+
// Move focus to first element
|
|
129
|
+
firstFocusable.focus();
|
|
130
|
+
|
|
131
|
+
dialog.addEventListener('keydown', function(e) {
|
|
132
|
+
if (e.key === 'Escape') {
|
|
133
|
+
closeDialog(dialog);
|
|
134
|
+
trigger.focus(); // Restore focus
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (e.key !== 'Tab') return;
|
|
139
|
+
|
|
140
|
+
if (e.shiftKey) {
|
|
141
|
+
// Shift+Tab at first element -> wrap to last
|
|
142
|
+
if (document.activeElement === firstFocusable) {
|
|
143
|
+
e.preventDefault();
|
|
144
|
+
lastFocusable.focus();
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
// Tab at last element -> wrap to first
|
|
148
|
+
if (document.activeElement === lastFocusable) {
|
|
149
|
+
e.preventDefault();
|
|
150
|
+
firstFocusable.focus();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Dialog HTML Pattern
|
|
158
|
+
|
|
159
|
+
```html
|
|
160
|
+
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
|
|
161
|
+
<h2 id="dialog-title">Dialog Title</h2>
|
|
162
|
+
<div class="dialog-content">
|
|
163
|
+
<!-- content -->
|
|
164
|
+
</div>
|
|
165
|
+
<div class="dialog-actions">
|
|
166
|
+
<button type="button">Cancel</button>
|
|
167
|
+
<button type="button">Confirm</button>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Requirements
|
|
173
|
+
|
|
174
|
+
| Step | Action | Detail |
|
|
175
|
+
|------|--------|--------|
|
|
176
|
+
| Open | Store trigger | `const trigger = document.activeElement` |
|
|
177
|
+
| Open | Move focus | Focus first focusable element in dialog |
|
|
178
|
+
| Open | Lock background | `document.body.style.overflow = 'hidden'` or `inert` attribute |
|
|
179
|
+
| Open | Set ARIA | `aria-modal="true"` on dialog |
|
|
180
|
+
| Tab | Cycle within | Tab/Shift+Tab wrap within dialog focusable elements |
|
|
181
|
+
| Escape | Close + restore | Close dialog, restore focus to trigger |
|
|
182
|
+
| Close | Unlock background | Remove scroll lock / inert |
|
|
183
|
+
|
|
184
|
+
## ARIA Patterns
|
|
185
|
+
|
|
186
|
+
### Button Patterns
|
|
187
|
+
|
|
188
|
+
```html
|
|
189
|
+
<!-- Standard button -->
|
|
190
|
+
<button type="button">Save</button>
|
|
191
|
+
|
|
192
|
+
<!-- Icon-only button (needs aria-label) -->
|
|
193
|
+
<button type="button" aria-label="Close dialog">
|
|
194
|
+
<svg><!-- X icon --></svg>
|
|
195
|
+
</button>
|
|
196
|
+
|
|
197
|
+
<!-- Toggle button -->
|
|
198
|
+
<button type="button" aria-pressed="false">Bold</button>
|
|
199
|
+
|
|
200
|
+
<!-- Disclosure button -->
|
|
201
|
+
<button type="button" aria-expanded="false" aria-controls="panel-1">
|
|
202
|
+
Show details
|
|
203
|
+
</button>
|
|
204
|
+
<div id="panel-1" hidden>Details content</div>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Dialog Pattern
|
|
208
|
+
|
|
209
|
+
```html
|
|
210
|
+
<div role="dialog" aria-modal="true" aria-labelledby="dlg-title" aria-describedby="dlg-desc">
|
|
211
|
+
<h2 id="dlg-title">Confirm Action</h2>
|
|
212
|
+
<p id="dlg-desc">Are you sure you want to proceed?</p>
|
|
213
|
+
<button type="button">Cancel</button>
|
|
214
|
+
<button type="button">Confirm</button>
|
|
215
|
+
</div>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Live Region Patterns
|
|
219
|
+
|
|
220
|
+
```html
|
|
221
|
+
<!-- Status updates (polite) -->
|
|
222
|
+
<div role="status" aria-live="polite">
|
|
223
|
+
3 items in cart
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<!-- Error messages (assertive) -->
|
|
227
|
+
<div role="alert" aria-live="assertive">
|
|
228
|
+
Email address is invalid
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
<!-- Log/chat (polite, additions only) -->
|
|
232
|
+
<div role="log" aria-live="polite" aria-relevant="additions">
|
|
233
|
+
<!-- new messages appended here -->
|
|
234
|
+
</div>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Navigation Pattern
|
|
238
|
+
|
|
239
|
+
```html
|
|
240
|
+
<!-- Primary navigation -->
|
|
241
|
+
<nav aria-label="Primary">
|
|
242
|
+
<ul role="menubar">
|
|
243
|
+
<li role="none"><a role="menuitem" href="/">Home</a></li>
|
|
244
|
+
<li role="none"><a role="menuitem" href="/about">About</a></li>
|
|
245
|
+
</ul>
|
|
246
|
+
</nav>
|
|
247
|
+
|
|
248
|
+
<!-- Breadcrumb -->
|
|
249
|
+
<nav aria-label="Breadcrumb">
|
|
250
|
+
<ol>
|
|
251
|
+
<li><a href="/">Home</a></li>
|
|
252
|
+
<li><a href="/products">Products</a></li>
|
|
253
|
+
<li aria-current="page">Widget</li>
|
|
254
|
+
</ol>
|
|
255
|
+
</nav>
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Tab Pattern
|
|
259
|
+
|
|
260
|
+
```html
|
|
261
|
+
<div role="tablist" aria-label="Settings">
|
|
262
|
+
<button role="tab" aria-selected="true" aria-controls="panel-general" id="tab-general">
|
|
263
|
+
General
|
|
264
|
+
</button>
|
|
265
|
+
<button role="tab" aria-selected="false" aria-controls="panel-security" id="tab-security" tabindex="-1">
|
|
266
|
+
Security
|
|
267
|
+
</button>
|
|
268
|
+
</div>
|
|
269
|
+
<div role="tabpanel" id="panel-general" aria-labelledby="tab-general">
|
|
270
|
+
General settings content
|
|
271
|
+
</div>
|
|
272
|
+
<div role="tabpanel" id="panel-security" aria-labelledby="tab-security" hidden>
|
|
273
|
+
Security settings content
|
|
274
|
+
</div>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**Keyboard**: Arrow Left/Right to switch tabs, Tab to move into panel content.
|
|
278
|
+
|
|
279
|
+
### Form Error Pattern
|
|
280
|
+
|
|
281
|
+
```html
|
|
282
|
+
<label for="email">Email</label>
|
|
283
|
+
<input
|
|
284
|
+
type="email"
|
|
285
|
+
id="email"
|
|
286
|
+
aria-required="true"
|
|
287
|
+
aria-invalid="true"
|
|
288
|
+
aria-describedby="email-error"
|
|
289
|
+
>
|
|
290
|
+
<div id="email-error" role="alert">
|
|
291
|
+
Please enter a valid email address
|
|
292
|
+
</div>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Keyboard Navigation Reference
|
|
296
|
+
|
|
297
|
+
| Component | Key | Action |
|
|
298
|
+
|-----------|-----|--------|
|
|
299
|
+
| Link | Enter | Activate |
|
|
300
|
+
| Button | Enter, Space | Activate |
|
|
301
|
+
| Checkbox | Space | Toggle |
|
|
302
|
+
| Radio group | Arrow Up/Down | Select previous/next |
|
|
303
|
+
| Tab list | Arrow Left/Right | Switch tab |
|
|
304
|
+
| Menu | Arrow Up/Down | Navigate items |
|
|
305
|
+
| Menu | Enter | Select item |
|
|
306
|
+
| Menu | Escape | Close menu |
|
|
307
|
+
| Dialog | Escape | Close dialog |
|
|
308
|
+
| Slider | Arrow Left/Right | Decrease/increase |
|
|
309
|
+
| Combobox | Arrow Down | Open dropdown |
|
|
310
|
+
| Combobox | Enter | Select highlighted |
|
|
311
|
+
| Combobox | Escape | Close dropdown |
|
|
312
|
+
| Tree | Arrow Up/Down | Navigate siblings |
|
|
313
|
+
| Tree | Arrow Right | Expand / enter child |
|
|
314
|
+
| Tree | Arrow Left | Collapse / go to parent |
|
|
315
|
+
|
|
316
|
+
## Target Size Reference
|
|
317
|
+
|
|
318
|
+
| Standard | Minimum Size | Notes |
|
|
319
|
+
|----------|-------------|-------|
|
|
320
|
+
| WCAG 2.5.8 (AA) | 24x24px CSS pixels | Or adequate spacing between targets |
|
|
321
|
+
| WCAG 2.5.5 (AAA) | 44x44px CSS pixels | Recommended for touch interfaces |
|
|
322
|
+
| Apple HIG | 44x44pt | iOS touch targets |
|
|
323
|
+
| Material Design | 48x48dp | Android touch targets |
|
|
324
|
+
|
|
325
|
+
**Exceptions**: Inline links within text, browser default controls, essential fixed-size elements.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# OKLCH Color Accessibility Standards
|
|
2
|
+
|
|
3
|
+
Reference guide for OKLCH-based perceptual color analysis. Used by color-auditor and fix-implementer roles.
|
|
4
|
+
|
|
5
|
+
## OKLCH Basics
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
oklch(Lightness% Chroma Hue)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
- **Lightness (L)**: 0% (black) to 100% (white) -- perceptually uniform
|
|
12
|
+
- **Chroma (C)**: 0 (achromatic/gray) to ~0.37 (maximum saturation) -- perceptual colorfulness
|
|
13
|
+
- **Hue (H)**: 0-360 degrees -- color wheel angle
|
|
14
|
+
|
|
15
|
+
OKLCH is perceptually uniform: equal numeric changes produce equal perceived changes, unlike HSL/RGB.
|
|
16
|
+
|
|
17
|
+
## Lightness Guidelines
|
|
18
|
+
|
|
19
|
+
| Element | L Range | Rationale |
|
|
20
|
+
|---------|---------|-----------|
|
|
21
|
+
| Dark text on light background | L <= 40% | Ensures sufficient contrast against light surfaces |
|
|
22
|
+
| Light background for text | L >= 90% | Provides clean reading surface |
|
|
23
|
+
| Accent colors (interactive) | L 50-65% | Vibrant but readable |
|
|
24
|
+
| Disabled/muted elements | L 55-70% | Intentionally reduced contrast (with care) |
|
|
25
|
+
| Dark mode text | L >= 85% | Light text on dark background |
|
|
26
|
+
| Dark mode background | L <= 20% | Dark surface for light text |
|
|
27
|
+
|
|
28
|
+
## Chroma Guidelines
|
|
29
|
+
|
|
30
|
+
| Use Case | C Range | Notes |
|
|
31
|
+
|----------|---------|-------|
|
|
32
|
+
| Neutral/text colors | C = 0 | Pure achromatic for maximum readability |
|
|
33
|
+
| Subtle warm/cool tint | C = 0.005-0.02 | Adds warmth without color distraction |
|
|
34
|
+
| Standard accent | C = 0.1-0.15 | Good balance of color and readability |
|
|
35
|
+
| Vibrant accent | C = 0.2-0.25 | Use sparingly, max 1-2 per palette |
|
|
36
|
+
| Maximum saturation | C > 0.25 | Avoid for text; OK for decorative only |
|
|
37
|
+
|
|
38
|
+
## Impeccable Palette Reference
|
|
39
|
+
|
|
40
|
+
```css
|
|
41
|
+
/* Neutrals */
|
|
42
|
+
--color-ink: oklch(10% 0 0); /* Primary text */
|
|
43
|
+
--color-paper: oklch(98% 0 0); /* Primary background */
|
|
44
|
+
--color-cream: oklch(96% 0.005 350); /* Warm background variant */
|
|
45
|
+
--color-charcoal: oklch(25% 0 0); /* Secondary text */
|
|
46
|
+
--color-ash: oklch(55% 0 0); /* Muted/disabled text */
|
|
47
|
+
--color-mist: oklch(92% 0 0); /* Border/divider */
|
|
48
|
+
|
|
49
|
+
/* Accent */
|
|
50
|
+
--color-accent: oklch(60% 0.25 350); /* Primary action */
|
|
51
|
+
--color-accent-hover: oklch(52% 0.25 350); /* Hover state (darker) */
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Palette Analysis
|
|
55
|
+
|
|
56
|
+
| Name | L | C | H | Role | Contrast vs paper (98%) |
|
|
57
|
+
|------|---|---|---|------|------------------------|
|
|
58
|
+
| ink | 10% | 0 | 0 | Body text | ~15.4:1 (AAA) |
|
|
59
|
+
| charcoal | 25% | 0 | 0 | Secondary text | ~9.5:1 (AAA) |
|
|
60
|
+
| ash | 55% | 0 | 0 | Muted text | ~3.8:1 (AA large only) |
|
|
61
|
+
| accent | 60% | 0.25 | 350 | Interactive | ~3.4:1 (large text / non-text only) |
|
|
62
|
+
| accent-hover | 52% | 0.25 | 350 | Hover state | ~4.6:1 (AA) |
|
|
63
|
+
|
|
64
|
+
## Contrast Verification Methods
|
|
65
|
+
|
|
66
|
+
### WCAG 2.1 Contrast Ratio
|
|
67
|
+
|
|
68
|
+
Formula: `(L1 + 0.05) / (L2 + 0.05)` where L1, L2 are relative luminances (L1 > L2).
|
|
69
|
+
|
|
70
|
+
Convert OKLCH -> sRGB -> linear RGB -> relative luminance:
|
|
71
|
+
`L_rel = 0.2126 * R_linear + 0.7152 * G_linear + 0.0722 * B_linear`
|
|
72
|
+
|
|
73
|
+
| Text Type | AA | AAA |
|
|
74
|
+
|-----------|-----|-----|
|
|
75
|
+
| Normal text (< 18pt / < 14pt bold) | >= 4.5:1 | >= 7:1 |
|
|
76
|
+
| Large text (>= 18pt / >= 14pt bold) | >= 3:1 | >= 4.5:1 |
|
|
77
|
+
| Non-text (UI components, icons) | >= 3:1 | >= 3:1 |
|
|
78
|
+
|
|
79
|
+
### APCA Contrast (Advanced)
|
|
80
|
+
|
|
81
|
+
APCA (Accessible Perceptual Contrast Algorithm) uses OKLCH lightness for perceptual accuracy.
|
|
82
|
+
|
|
83
|
+
Lc (Lightness contrast) values:
|
|
84
|
+
|
|
85
|
+
| Use Case | Minimum Lc | Description |
|
|
86
|
+
|----------|-----------|-------------|
|
|
87
|
+
| Body text (14-16px) | >= 75 | Primary reading content |
|
|
88
|
+
| Content text (18px) | >= 60 | Secondary content |
|
|
89
|
+
| Large text (24px+) | >= 45 | Headings, display |
|
|
90
|
+
| Non-text elements | >= 30 | Icons, borders, focus indicators |
|
|
91
|
+
| Placeholder/disabled | >= 15 | Intentionally muted |
|
|
92
|
+
|
|
93
|
+
### Focus Indicator Contrast
|
|
94
|
+
|
|
95
|
+
Focus indicators must have >= 3:1 contrast against adjacent colors:
|
|
96
|
+
- Outline color vs element background
|
|
97
|
+
- Outline color vs surrounding page background
|
|
98
|
+
- Both must pass
|
|
99
|
+
|
|
100
|
+
## Color Blindness Reference
|
|
101
|
+
|
|
102
|
+
### Confusion Lines
|
|
103
|
+
|
|
104
|
+
| Type | Prevalence | Confuses | Safe Alternatives |
|
|
105
|
+
|------|-----------|----------|-------------------|
|
|
106
|
+
| Protanopia (red-blind) | ~1% male | Red/green, red/brown | Use blue/orange, add patterns |
|
|
107
|
+
| Deuteranopia (green-blind) | ~5% male | Green/red, green/brown | Use blue/orange, add patterns |
|
|
108
|
+
| Tritanopia (blue-blind) | ~0.01% | Blue/yellow | Use red/green pairs (opposite) |
|
|
109
|
+
| Achromatopsia (no color) | ~0.003% | All chromatic | Rely on lightness difference only |
|
|
110
|
+
|
|
111
|
+
### Safe Color Pairs
|
|
112
|
+
|
|
113
|
+
Always ensure information is not conveyed by color alone. Safe strategies:
|
|
114
|
+
- Use lightness difference (>= 40% L difference)
|
|
115
|
+
- Add text labels, icons, or patterns alongside color
|
|
116
|
+
- Use blue + orange (safe for most color blindness types)
|
|
117
|
+
- Avoid red-only or green-only indicators
|
|
118
|
+
|
|
119
|
+
## Dark Mode Color Mapping
|
|
120
|
+
|
|
121
|
+
When converting light mode to dark mode:
|
|
122
|
+
|
|
123
|
+
| Light Mode | Dark Mode | Rule |
|
|
124
|
+
|-----------|----------|------|
|
|
125
|
+
| Text L <= 40% | Text L >= 85% | Invert lightness range |
|
|
126
|
+
| Background L >= 90% | Background L <= 20% | Invert lightness range |
|
|
127
|
+
| Accent L 50-65% | Accent L 60-75% | Slight lightness increase |
|
|
128
|
+
| Border L ~92% | Border L ~25% | Invert proportionally |
|
|
129
|
+
|
|
130
|
+
Maintain same hue and similar chroma; adjust lightness to preserve contrast ratios.
|