@hegemonart/get-design-done 1.42.0 → 1.44.0
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +1126 -1038
- package/README.md +159 -155
- package/SKILL.md +42 -42
- package/agents/README.md +53 -53
- package/agents/a11y-mapper.md +3 -3
- package/agents/component-benchmark-harvester.md +8 -8
- package/agents/component-benchmark-synthesizer.md +11 -11
- package/agents/component-taxonomy-mapper.md +5 -5
- package/agents/compose-executor.md +25 -25
- package/agents/conflict-resolver.md +8 -8
- package/agents/cost-forecaster.md +12 -12
- package/agents/decision-journal-exporter.md +5 -5
- package/agents/design-advisor.md +19 -19
- package/agents/design-assumptions-analyzer.md +16 -16
- package/agents/design-auditor.md +39 -39
- package/agents/design-authority-watcher.md +28 -28
- package/agents/design-component-generator.md +27 -27
- package/agents/design-context-builder.md +66 -66
- package/agents/design-context-checker-gate.md +5 -5
- package/agents/design-context-checker.md +20 -20
- package/agents/design-discussant.md +23 -23
- package/agents/design-doc-writer.md +12 -12
- package/agents/design-executor.md +38 -38
- package/agents/design-figma-writer.md +31 -31
- package/agents/design-fixer.md +27 -27
- package/agents/design-integration-checker-gate.md +5 -5
- package/agents/design-integration-checker.md +29 -29
- package/agents/design-paper-writer.md +14 -14
- package/agents/design-pattern-mapper.md +9 -9
- package/agents/design-pencil-writer.md +12 -12
- package/agents/design-phase-researcher.md +14 -14
- package/agents/design-plan-checker.md +13 -13
- package/agents/design-planner.md +24 -24
- package/agents/design-reflector.md +48 -48
- package/agents/design-research-synthesizer.md +21 -21
- package/agents/design-start-writer.md +7 -7
- package/agents/design-update-checker.md +8 -8
- package/agents/design-verifier-gate.md +5 -5
- package/agents/design-verifier.md +80 -80
- package/agents/ds-generator.md +14 -14
- package/agents/ds-migration-planner.md +12 -12
- package/agents/email-executor.md +26 -26
- package/agents/experiment-result-ingester.md +10 -10
- package/agents/flutter-executor.md +28 -28
- package/agents/gdd-graph-refresh.md +10 -10
- package/agents/gdd-intel-updater.md +11 -11
- package/agents/gdd-learnings-extractor.md +2 -2
- package/agents/motion-mapper.md +8 -8
- package/agents/motion-verifier.md +16 -16
- package/agents/pdf-executor.md +27 -27
- package/agents/perf-analyzer.md +20 -20
- package/agents/pr-commenter.md +24 -24
- package/agents/prototype-gate.md +29 -29
- package/agents/quality-gate-runner.md +21 -21
- package/agents/rollout-coordinator.md +8 -8
- package/agents/swift-executor.md +41 -41
- package/agents/ticket-sync-agent.md +19 -19
- package/agents/token-mapper.md +6 -6
- package/agents/user-research-synthesizer.md +13 -13
- package/agents/visual-hierarchy-mapper.md +2 -2
- package/dist/claude-code/.claude/skills/add-backlog/SKILL.md +3 -3
- package/dist/claude-code/.claude/skills/analyze-dependencies/SKILL.md +10 -10
- package/dist/claude-code/.claude/skills/apply-reflections/SKILL.md +13 -13
- package/dist/claude-code/.claude/skills/apply-reflections/apply-reflections-procedure.md +20 -20
- package/dist/claude-code/.claude/skills/audit/SKILL.md +7 -7
- package/dist/claude-code/.claude/skills/bandit-status/SKILL.md +7 -7
- package/dist/claude-code/.claude/skills/benchmark/SKILL.md +7 -7
- package/dist/claude-code/.claude/skills/bootstrap-ds/SKILL.md +10 -10
- package/dist/claude-code/.claude/skills/brief/SKILL.md +20 -20
- package/dist/claude-code/.claude/skills/budget/SKILL.md +4 -4
- package/dist/claude-code/.claude/skills/cache-manager/SKILL.md +6 -6
- package/dist/claude-code/.claude/skills/cache-manager/cache-policy.md +5 -5
- package/dist/claude-code/.claude/skills/check-update/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/compare/SKILL.md +15 -15
- package/dist/claude-code/.claude/skills/compare/compare-rubric.md +17 -17
- package/dist/claude-code/.claude/skills/complete-cycle/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/connections/SKILL.md +11 -11
- package/dist/claude-code/.claude/skills/connections/connections-onboarding.md +76 -76
- package/dist/claude-code/.claude/skills/continue/SKILL.md +2 -2
- package/dist/claude-code/.claude/skills/darkmode/SKILL.md +17 -17
- package/dist/claude-code/.claude/skills/darkmode/darkmode-audit-procedure.md +7 -7
- package/dist/claude-code/.claude/skills/debug/SKILL.md +3 -3
- package/dist/claude-code/.claude/skills/debug/debug-feedback-loops.md +12 -12
- package/dist/claude-code/.claude/skills/design/SKILL.md +12 -12
- package/dist/claude-code/.claude/skills/design/design-procedure.md +23 -23
- package/dist/claude-code/.claude/skills/discover/SKILL.md +7 -7
- package/dist/claude-code/.claude/skills/discover/discover-procedure.md +18 -18
- package/dist/claude-code/.claude/skills/discuss/SKILL.md +12 -12
- package/dist/claude-code/.claude/skills/do/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/explore/SKILL.md +21 -21
- package/dist/claude-code/.claude/skills/explore/explore-procedure.md +48 -48
- package/dist/claude-code/.claude/skills/export/SKILL.md +9 -9
- package/dist/claude-code/.claude/skills/extract-learnings/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/fast/SKILL.md +7 -7
- package/dist/claude-code/.claude/skills/figma-extract/SKILL.md +11 -11
- package/dist/claude-code/.claude/skills/figma-write/SKILL.md +6 -6
- package/dist/claude-code/.claude/skills/graphify/SKILL.md +4 -4
- package/dist/claude-code/.claude/skills/health/SKILL.md +16 -16
- package/dist/claude-code/.claude/skills/health/health-mcp-detection.md +3 -3
- package/dist/claude-code/.claude/skills/health/health-skill-length-report.md +6 -6
- package/dist/claude-code/.claude/skills/help/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/list-assumptions/SKILL.md +4 -4
- package/dist/claude-code/.claude/skills/map/SKILL.md +12 -12
- package/dist/claude-code/.claude/skills/migrate/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/new-cycle/SKILL.md +2 -2
- package/dist/claude-code/.claude/skills/new-cycle/milestone-completeness-rubric.md +16 -16
- package/dist/claude-code/.claude/skills/new-project/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/next/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/note/SKILL.md +1 -1
- package/dist/claude-code/.claude/skills/openrouter-status/SKILL.md +4 -4
- package/dist/claude-code/.claude/skills/optimize/SKILL.md +15 -15
- package/dist/claude-code/.claude/skills/pause/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/peer-cli-add/SKILL.md +11 -11
- package/dist/claude-code/.claude/skills/peer-cli-add/peer-cli-protocol.md +39 -39
- package/dist/claude-code/.claude/skills/peer-cli-customize/SKILL.md +14 -14
- package/dist/claude-code/.claude/skills/peers/SKILL.md +4 -4
- package/dist/claude-code/.claude/skills/plan/SKILL.md +13 -13
- package/dist/claude-code/.claude/skills/plan/plan-procedure.md +24 -24
- package/dist/claude-code/.claude/skills/plant-seed/SKILL.md +4 -4
- package/dist/claude-code/.claude/skills/pr-branch/SKILL.md +2 -2
- package/dist/claude-code/.claude/skills/progress/SKILL.md +15 -15
- package/dist/claude-code/.claude/skills/quality-gate/SKILL.md +22 -22
- package/dist/claude-code/.claude/skills/quality-gate/threat-modeling.md +19 -19
- package/dist/claude-code/.claude/skills/quick/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/reapply-patches/SKILL.md +7 -7
- package/dist/claude-code/.claude/skills/reflect/SKILL.md +3 -3
- package/dist/claude-code/.claude/skills/reflect/procedures/capability-gap-scan.md +11 -11
- package/dist/claude-code/.claude/skills/report-issue/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/report-issue/report-issue-procedure.md +27 -27
- package/dist/claude-code/.claude/skills/resume/SKILL.md +9 -9
- package/dist/claude-code/.claude/skills/review-backlog/SKILL.md +3 -3
- package/dist/claude-code/.claude/skills/review-decisions/SKILL.md +3 -3
- package/dist/claude-code/.claude/skills/roi/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/rollout-status/SKILL.md +4 -4
- package/dist/claude-code/.claude/skills/router/SKILL.md +11 -11
- package/dist/claude-code/.claude/skills/router/capability-gap-emitter.md +6 -6
- package/dist/claude-code/.claude/skills/router/router-pick-emitter.md +9 -9
- package/dist/claude-code/.claude/skills/router/router-rules.md +7 -7
- package/dist/claude-code/.claude/skills/scan/SKILL.md +16 -16
- package/dist/claude-code/.claude/skills/scan/scan-procedure.md +42 -42
- package/dist/claude-code/.claude/skills/settings/SKILL.md +2 -2
- package/dist/claude-code/.claude/skills/ship/SKILL.md +7 -7
- package/dist/claude-code/.claude/skills/sketch/SKILL.md +10 -10
- package/dist/claude-code/.claude/skills/sketch-wrap-up/SKILL.md +12 -12
- package/dist/claude-code/.claude/skills/skill-manifest/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/spike/SKILL.md +7 -7
- package/dist/claude-code/.claude/skills/spike-wrap-up/SKILL.md +13 -13
- package/dist/claude-code/.claude/skills/start/SKILL.md +8 -8
- package/dist/claude-code/.claude/skills/start/start-procedure.md +9 -9
- package/dist/claude-code/.claude/skills/stats/SKILL.md +5 -5
- package/dist/claude-code/.claude/skills/style/SKILL.md +12 -12
- package/dist/claude-code/.claude/skills/style/style-doc-procedure.md +12 -12
- package/dist/claude-code/.claude/skills/synthesize/SKILL.md +10 -10
- package/dist/claude-code/.claude/skills/timeline/SKILL.md +4 -4
- package/dist/claude-code/.claude/skills/todo/SKILL.md +3 -3
- package/dist/claude-code/.claude/skills/turn-closeout/SKILL.md +10 -10
- package/dist/claude-code/.claude/skills/unlock-decision/SKILL.md +3 -3
- package/dist/claude-code/.claude/skills/update/SKILL.md +9 -9
- package/dist/claude-code/.claude/skills/using-gdd/SKILL.md +17 -17
- package/dist/claude-code/.claude/skills/verify/SKILL.md +13 -13
- package/dist/claude-code/.claude/skills/verify/verify-procedure.md +34 -34
- package/dist/claude-code/.claude/skills/warm-cache/SKILL.md +8 -8
- package/dist/claude-code/.claude/skills/watch-authorities/SKILL.md +9 -9
- package/dist/claude-code/.claude/skills/zoom-out/SKILL.md +4 -4
- package/package.json +9 -2
- package/reference/DEPRECATIONS.md +10 -10
- package/reference/STATE-TEMPLATE.md +26 -26
- package/reference/accessibility.md +13 -13
- package/reference/adr-format.md +13 -13
- package/reference/ai-native-tool-interface.md +5 -5
- package/reference/anti-patterns.md +9 -9
- package/reference/architecture-vocabulary.md +31 -31
- package/reference/audit-scoring.md +13 -13
- package/reference/authority-feeds.md +36 -36
- package/reference/bandit-integration.md +25 -25
- package/reference/brand-voice.md +36 -36
- package/reference/capability-gap-stage-gate.md +20 -20
- package/reference/checklists.md +26 -26
- package/reference/cli-localization.md +13 -13
- package/reference/codex-tools.md +2 -2
- package/reference/color-theory.md +28 -28
- package/reference/component-authoring.md +4 -4
- package/reference/components/README.md +13 -13
- package/reference/components/TEMPLATE.md +13 -13
- package/reference/components/accordion.md +15 -15
- package/reference/components/alert.md +25 -25
- package/reference/components/badge.md +18 -18
- package/reference/components/breadcrumbs.md +24 -24
- package/reference/components/button.md +21 -21
- package/reference/components/card.md +13 -13
- package/reference/components/checkbox.md +20 -20
- package/reference/components/chip.md +20 -20
- package/reference/components/command-palette.md +15 -15
- package/reference/components/date-picker.md +22 -22
- package/reference/components/drawer.md +13 -13
- package/reference/components/file-upload.md +22 -22
- package/reference/components/input.md +18 -18
- package/reference/components/label.md +25 -25
- package/reference/components/link.md +19 -19
- package/reference/components/list.md +17 -17
- package/reference/components/menu.md +19 -19
- package/reference/components/modal-dialog.md +16 -16
- package/reference/components/navbar.md +19 -19
- package/reference/components/pagination.md +18 -18
- package/reference/components/popover.md +12 -12
- package/reference/components/progress.md +18 -18
- package/reference/components/radio.md +17 -17
- package/reference/components/rich-text-editor.md +24 -24
- package/reference/components/select-combobox.md +16 -16
- package/reference/components/sidebar.md +15 -15
- package/reference/components/skeleton.md +20 -20
- package/reference/components/slider.md +20 -20
- package/reference/components/stepper.md +24 -24
- package/reference/components/switch.md +19 -19
- package/reference/components/table.md +21 -21
- package/reference/components/tabs.md +11 -11
- package/reference/components/toast.md +19 -19
- package/reference/components/tooltip.md +19 -19
- package/reference/components/tree.md +17 -17
- package/reference/composition.md +38 -38
- package/reference/config-schema.md +37 -37
- package/reference/context-md-format.md +9 -9
- package/reference/contrast-advanced.md +29 -29
- package/reference/conversational-ui.md +17 -17
- package/reference/cost-governance.md +14 -14
- package/reference/css-grid-layout.md +8 -8
- package/reference/cycle-handoff-preamble.md +3 -3
- package/reference/data-visualization.md +67 -67
- package/reference/debugger-philosophy.md +5 -5
- package/reference/design-system-guidance.md +21 -21
- package/reference/design-systems-catalog.md +20 -20
- package/reference/design-variants.md +11 -11
- package/reference/domains/civic-patterns.md +10 -10
- package/reference/domains/finance-patterns.md +9 -9
- package/reference/domains/gaming-patterns.md +9 -9
- package/reference/domains/healthcare-patterns.md +11 -11
- package/reference/ds-bootstrap-rubric.md +13 -13
- package/reference/email-design.md +22 -22
- package/reference/emotional-design.md +10 -10
- package/reference/error-recovery.md +11 -11
- package/reference/export-formats.md +7 -7
- package/reference/figma-sandbox.md +6 -6
- package/reference/first-principles.md +10 -10
- package/reference/form-patterns.md +26 -26
- package/reference/framer-motion-patterns.md +49 -49
- package/reference/gdd-runtime-audit.md +17 -17
- package/reference/gdd-threat-model.md +44 -44
- package/reference/gemini-tools.md +3 -3
- package/reference/gestalt.md +24 -24
- package/reference/heuristics.md +32 -32
- package/reference/i18n.md +44 -44
- package/reference/iconography.md +24 -24
- package/reference/image-optimization.md +14 -14
- package/reference/information-architecture.md +47 -47
- package/reference/intel-schema.md +1 -1
- package/reference/known-failure-modes.md +37 -37
- package/reference/meta-rules.md +5 -5
- package/reference/migrations/material-3-to-4.md +17 -17
- package/reference/migrations/mui-v6.md +16 -16
- package/reference/migrations/shadcn-v2.md +25 -25
- package/reference/migrations/tailwind-v4.md +21 -21
- package/reference/model-prices.md +3 -3
- package/reference/model-tiers.md +40 -40
- package/reference/motion-advanced.md +21 -21
- package/reference/motion-easings.md +29 -29
- package/reference/motion-interpolate.md +1 -1
- package/reference/motion-spring.md +13 -13
- package/reference/motion-transition-taxonomy.md +34 -34
- package/reference/motion.md +31 -31
- package/reference/multi-author-model.md +13 -13
- package/reference/native-platforms.md +28 -28
- package/reference/notification-routing.md +6 -6
- package/reference/onboarding-progressive-disclosure.md +32 -32
- package/reference/openrouter-tier-mapping.md +8 -8
- package/reference/palette-catalog.md +37 -37
- package/reference/parallelism-rules.md +20 -20
- package/reference/peer-cli-capabilities.md +14 -14
- package/reference/peer-protocols.md +21 -21
- package/reference/perf-budget.md +21 -21
- package/reference/performance.md +22 -22
- package/reference/platforms.md +51 -51
- package/reference/pr-review-integration.md +7 -7
- package/reference/prices/antigravity.md +3 -3
- package/reference/prices/augment.md +3 -3
- package/reference/prices/claude.md +2 -2
- package/reference/prices/cline.md +4 -4
- package/reference/prices/codebuddy.md +3 -3
- package/reference/prices/codex.md +2 -2
- package/reference/prices/copilot.md +3 -3
- package/reference/prices/cursor.md +3 -3
- package/reference/prices/gemini.md +2 -2
- package/reference/prices/kilo.md +3 -3
- package/reference/prices/opencode.md +4 -4
- package/reference/prices/qwen.md +2 -2
- package/reference/prices/trae.md +3 -3
- package/reference/prices/windsurf.md +3 -3
- package/reference/prices.openrouter.md +5 -5
- package/reference/print-design.md +36 -36
- package/reference/priority-matrix.md +2 -2
- package/reference/project-skills-guide.md +3 -3
- package/reference/proportion-systems.md +23 -23
- package/reference/pseudonymization-rules.md +30 -30
- package/reference/retrieval-contract.md +14 -14
- package/reference/review-format.md +7 -7
- package/reference/rollout-coordination.md +10 -10
- package/reference/rtl-cjk-cultural.md +39 -39
- package/reference/runtime-models.md +28 -28
- package/reference/shared-preamble.md +26 -26
- package/reference/skill-authoring-contract.md +16 -16
- package/reference/skill-placeholders.md +3 -3
- package/reference/start-interview.md +10 -10
- package/reference/style-vocabulary.md +25 -25
- package/reference/surfaces.md +4 -4
- package/reference/ticket-sync.md +9 -9
- package/reference/typography.md +64 -64
- package/reference/user-research.md +54 -54
- package/reference/variable-fonts-loading.md +15 -15
- package/reference/visual-hierarchy-layout.md +41 -41
- package/scripts/lib/harness-freshness.cjs +59 -0
- package/scripts/lib/health-mirror/index.cjs +27 -0
- package/scripts/lib/manifest/harnesses.json +280 -14
- package/scripts/lib/manifest/prose-denylist.json +1 -1
- package/scripts/lib/manifest/schemas/harnesses.schema.json +32 -0
- package/sdk/mcp/gdd-mcp/server.js +125 -0
- package/skills/add-backlog/SKILL.md +3 -3
- package/skills/analyze-dependencies/SKILL.md +10 -10
- package/skills/apply-reflections/SKILL.md +13 -13
- package/skills/apply-reflections/apply-reflections-procedure.md +20 -20
- package/skills/audit/SKILL.md +7 -7
- package/skills/bandit-status/SKILL.md +7 -7
- package/skills/benchmark/SKILL.md +7 -7
- package/skills/bootstrap-ds/SKILL.md +10 -10
- package/skills/brief/SKILL.md +20 -20
- package/skills/budget/SKILL.md +4 -4
- package/skills/cache-manager/SKILL.md +6 -6
- package/skills/cache-manager/cache-policy.md +5 -5
- package/skills/check-update/SKILL.md +5 -5
- package/skills/compare/SKILL.md +15 -15
- package/skills/compare/compare-rubric.md +17 -17
- package/skills/complete-cycle/SKILL.md +5 -5
- package/skills/connections/SKILL.md +11 -11
- package/skills/connections/connections-onboarding.md +76 -76
- package/skills/continue/SKILL.md +2 -2
- package/skills/darkmode/SKILL.md +17 -17
- package/skills/darkmode/darkmode-audit-procedure.md +7 -7
- package/skills/debug/SKILL.md +3 -3
- package/skills/debug/debug-feedback-loops.md +12 -12
- package/skills/design/SKILL.md +12 -12
- package/skills/design/design-procedure.md +23 -23
- package/skills/discover/SKILL.md +7 -7
- package/skills/discover/discover-procedure.md +18 -18
- package/skills/discuss/SKILL.md +12 -12
- package/skills/do/SKILL.md +1 -1
- package/skills/explore/SKILL.md +21 -21
- package/skills/explore/explore-procedure.md +48 -48
- package/skills/export/SKILL.md +9 -9
- package/skills/extract-learnings/SKILL.md +5 -5
- package/skills/fast/SKILL.md +7 -7
- package/skills/figma-extract/SKILL.md +11 -11
- package/skills/figma-write/SKILL.md +6 -6
- package/skills/graphify/SKILL.md +4 -4
- package/skills/health/SKILL.md +16 -16
- package/skills/health/health-mcp-detection.md +3 -3
- package/skills/health/health-skill-length-report.md +6 -6
- package/skills/help/SKILL.md +1 -1
- package/skills/list-assumptions/SKILL.md +4 -4
- package/skills/map/SKILL.md +12 -12
- package/skills/migrate/SKILL.md +5 -5
- package/skills/new-cycle/SKILL.md +2 -2
- package/skills/new-cycle/milestone-completeness-rubric.md +16 -16
- package/skills/new-project/SKILL.md +1 -1
- package/skills/next/SKILL.md +5 -5
- package/skills/note/SKILL.md +1 -1
- package/skills/openrouter-status/SKILL.md +4 -4
- package/skills/optimize/SKILL.md +15 -15
- package/skills/pause/SKILL.md +5 -5
- package/skills/peer-cli-add/SKILL.md +11 -11
- package/skills/peer-cli-add/peer-cli-protocol.md +39 -39
- package/skills/peer-cli-customize/SKILL.md +14 -14
- package/skills/peers/SKILL.md +4 -4
- package/skills/plan/SKILL.md +13 -13
- package/skills/plan/plan-procedure.md +24 -24
- package/skills/plant-seed/SKILL.md +4 -4
- package/skills/pr-branch/SKILL.md +2 -2
- package/skills/progress/SKILL.md +15 -15
- package/skills/quality-gate/SKILL.md +22 -22
- package/skills/quality-gate/threat-modeling.md +19 -19
- package/skills/quick/SKILL.md +5 -5
- package/skills/reapply-patches/SKILL.md +7 -7
- package/skills/reflect/SKILL.md +3 -3
- package/skills/reflect/procedures/capability-gap-scan.md +11 -11
- package/skills/report-issue/SKILL.md +5 -5
- package/skills/report-issue/report-issue-procedure.md +27 -27
- package/skills/resume/SKILL.md +9 -9
- package/skills/review-backlog/SKILL.md +3 -3
- package/skills/review-decisions/SKILL.md +3 -3
- package/skills/roi/SKILL.md +5 -5
- package/skills/rollout-status/SKILL.md +4 -4
- package/skills/router/SKILL.md +11 -11
- package/skills/router/capability-gap-emitter.md +6 -6
- package/skills/router/router-pick-emitter.md +9 -9
- package/skills/router/router-rules.md +7 -7
- package/skills/scan/SKILL.md +16 -16
- package/skills/scan/scan-procedure.md +42 -42
- package/skills/settings/SKILL.md +2 -2
- package/skills/ship/SKILL.md +7 -7
- package/skills/sketch/SKILL.md +10 -10
- package/skills/sketch-wrap-up/SKILL.md +12 -12
- package/skills/skill-manifest/SKILL.md +5 -5
- package/skills/spike/SKILL.md +7 -7
- package/skills/spike-wrap-up/SKILL.md +13 -13
- package/skills/start/SKILL.md +8 -8
- package/skills/start/start-procedure.md +9 -9
- package/skills/stats/SKILL.md +5 -5
- package/skills/style/SKILL.md +12 -12
- package/skills/style/style-doc-procedure.md +12 -12
- package/skills/synthesize/SKILL.md +10 -10
- package/skills/timeline/SKILL.md +4 -4
- package/skills/todo/SKILL.md +3 -3
- package/skills/turn-closeout/SKILL.md +10 -10
- package/skills/unlock-decision/SKILL.md +3 -3
- package/skills/update/SKILL.md +9 -9
- package/skills/using-gdd/SKILL.md +17 -17
- package/skills/verify/SKILL.md +13 -13
- package/skills/verify/verify-procedure.md +34 -34
- package/skills/warm-cache/SKILL.md +8 -8
- package/skills/watch-authorities/SKILL.md +9 -9
- package/skills/zoom-out/SKILL.md +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# File Upload
|
|
1
|
+
# File Upload - Benchmark Spec
|
|
2
2
|
|
|
3
3
|
**Harvested from**: Polaris (DropZone), Carbon (FileUploader), Atlassian Design System, Material 3
|
|
4
4
|
**Wave**: 5 · **Category**: Advanced
|
|
@@ -34,7 +34,7 @@ File list (appears after selection):
|
|
|
34
34
|
| Part | Required | Notes |
|
|
35
35
|
|------|----------|-------|
|
|
36
36
|
| Drop zone container | Yes | Dashed border; drag-over changes fill + border color |
|
|
37
|
-
| `<input type="file">` | Yes | MUST be accessible (not `display:none`)
|
|
37
|
+
| `<input type="file">` | Yes | MUST be accessible (not `display:none`) - keyboard fallback |
|
|
38
38
|
| Browse trigger button | Yes | Visually activates the file input; must be a `<button>` or `<label>` |
|
|
39
39
|
| File list | Yes (when files selected) | Per-file name, size, status, progress bar, remove button |
|
|
40
40
|
| Progress bar | Yes (during upload) | `role="progressbar"` + `aria-valuenow` per file or overall |
|
|
@@ -62,11 +62,11 @@ File list (appears after selection):
|
|
|
62
62
|
|
|
63
63
|
| State | Trigger | Visual | ARIA |
|
|
64
64
|
|-------|---------|--------|------|
|
|
65
|
-
| default |
|
|
65
|
+
| default | - | Dashed border, instructional text | - |
|
|
66
66
|
| drag-over | File dragged over zone | Filled background + solid border color change | `aria-dropeffect="copy"` (deprecated but still useful) |
|
|
67
|
-
| drag-invalid | Wrong file type dragged over | Error border color; tooltip/message |
|
|
67
|
+
| drag-invalid | Wrong file type dragged over | Error border color; tooltip/message | - |
|
|
68
68
|
| uploading | File being sent | Per-file progress bar animating | `aria-valuenow` on progressbar |
|
|
69
|
-
| upload-done | Transfer complete | Check icon; status text "Done" |
|
|
69
|
+
| upload-done | Transfer complete | Check icon; status text "Done" | - |
|
|
70
70
|
| upload-error | Transfer failed | Error icon; error message per file | `aria-live="assertive"` error region |
|
|
71
71
|
| disabled | `disabled` prop | 38% opacity; drag events ignored | `aria-disabled="true"` on zone |
|
|
72
72
|
|
|
@@ -80,9 +80,9 @@ File list (appears after selection):
|
|
|
80
80
|
| md (default) | 128px | 8px | 14px |
|
|
81
81
|
| lg | 200px | 12px | 16px |
|
|
82
82
|
|
|
83
|
-
**Norm**: Drop zone should be large enough that it is comfortably hittable
|
|
83
|
+
**Norm**: Drop zone should be large enough that it is comfortably hittable - 128px minimum height for default. File list rows are 48–56px tall for accessible remove-button target size *(Carbon, Polaris)*.
|
|
84
84
|
|
|
85
|
-
Cross-link: `reference/surfaces.md`
|
|
85
|
+
Cross-link: `reference/surfaces.md` - minimum 44×44px touch targets for remove buttons.
|
|
86
86
|
|
|
87
87
|
---
|
|
88
88
|
|
|
@@ -94,7 +94,7 @@ Cross-link: `reference/surfaces.md` — minimum 44×44px touch targets for remov
|
|
|
94
94
|
- File size: caption-sm, secondary color
|
|
95
95
|
- Status text (Done / Error): caption-sm, success or error semantic color
|
|
96
96
|
|
|
97
|
-
Cross-link: `reference/typography.md`
|
|
97
|
+
Cross-link: `reference/typography.md` - truncation rules.
|
|
98
98
|
|
|
99
99
|
---
|
|
100
100
|
|
|
@@ -105,12 +105,12 @@ Cross-link: `reference/typography.md` — truncation rules.
|
|
|
105
105
|
|
|
106
106
|
### Keyboard Contract
|
|
107
107
|
|
|
108
|
-
*Derived from native `<input type="file">` behavior and WAI-ARIA APG button pattern
|
|
108
|
+
*Derived from native `<input type="file">` behavior and WAI-ARIA APG button pattern - W3C - 2024*
|
|
109
109
|
|
|
110
110
|
| Key | Action |
|
|
111
111
|
|-----|--------|
|
|
112
112
|
| Tab | Move focus to browse button / file input |
|
|
113
|
-
| Enter / Space | Activate browse button
|
|
113
|
+
| Enter / Space | Activate browse button - opens native file picker dialog |
|
|
114
114
|
| Tab (in file list) | Move through file items and remove buttons |
|
|
115
115
|
| Enter / Space (on remove button) | Remove file from list |
|
|
116
116
|
|
|
@@ -118,15 +118,15 @@ Drag-and-drop is pointer-only; keyboard users MUST be able to complete the entir
|
|
|
118
118
|
|
|
119
119
|
### Accessibility Rules
|
|
120
120
|
|
|
121
|
-
- `<input type="file">` MUST NOT use `display:none` or `visibility:hidden`
|
|
121
|
+
- `<input type="file">` MUST NOT use `display:none` or `visibility:hidden` - use `opacity:0` positioned absolutely with dimensions matching the trigger, OR keep a visible file input alongside the drop zone
|
|
122
122
|
- The browse trigger MUST be a `<button>` or `<label for="file-input">` so it is keyboard-focusable and activates the input
|
|
123
|
-
- Remove buttons MUST have `aria-label="Remove [filename]"`
|
|
124
|
-
- Upload errors MUST be announced via `aria-live="assertive"`
|
|
123
|
+
- Remove buttons MUST have `aria-label="Remove [filename]"` - an icon-only ✕ with no accessible name fails AT users
|
|
124
|
+
- Upload errors MUST be announced via `aria-live="assertive"` - do not rely solely on visual indicators
|
|
125
125
|
- Progress bars MUST keep `aria-valuenow` updated throughout upload
|
|
126
126
|
- `accept` attribute MUST match the visible allowed-types hint text so users are not surprised by rejection
|
|
127
127
|
- File list additions/removals should be announced via `aria-live="polite"` on the list container
|
|
128
128
|
|
|
129
|
-
Cross-link: `reference/accessibility.md`
|
|
129
|
+
Cross-link: `reference/accessibility.md` - aria-live regions, accessible file input patterns.
|
|
130
130
|
|
|
131
131
|
---
|
|
132
132
|
|
|
@@ -140,9 +140,9 @@ Cross-link: `reference/accessibility.md` — aria-live regions, accessible file
|
|
|
140
140
|
| Progress bar fill | continuous | linear | Matches upload byte progress |
|
|
141
141
|
| Upload complete tick | 200ms | ease-out | Check icon draw animation |
|
|
142
142
|
|
|
143
|
-
**BAN**: Do not animate progress bar with CSS only at a fixed pace
|
|
143
|
+
**BAN**: Do not animate progress bar with CSS only at a fixed pace - progress MUST reflect actual upload percentage via `aria-valuenow`.
|
|
144
144
|
|
|
145
|
-
Cross-link: `reference/motion.md`
|
|
145
|
+
Cross-link: `reference/motion.md` - reduced-motion: skip slide/collapse animations; keep progress bar updates.
|
|
146
146
|
|
|
147
147
|
---
|
|
148
148
|
|
|
@@ -155,10 +155,10 @@ Cross-link: `reference/motion.md` — reduced-motion: skip slide/collapse animat
|
|
|
155
155
|
- Announce upload errors via `aria-live="assertive"` *(WCAG 2.1 §4.1.3 Status Messages)*
|
|
156
156
|
|
|
157
157
|
### Don't
|
|
158
|
-
- Don't use `display:none` on the file input
|
|
159
|
-
- Don't omit the `accept` hint text
|
|
160
|
-
- Don't show only drag-drop UI with no browse button
|
|
161
|
-
- Don't use a generic `aria-label="Remove"` on remove buttons
|
|
158
|
+
- Don't use `display:none` on the file input - keyboard and AT users cannot trigger the picker *(WCAG 2.1 §2.1.1)*
|
|
159
|
+
- Don't omit the `accept` hint text - users should know allowed types before selecting *(Polaris, Carbon)*
|
|
160
|
+
- Don't show only drag-drop UI with no browse button - drag is inaccessible to keyboard users *(Carbon, Atlassian)*
|
|
161
|
+
- Don't use a generic `aria-label="Remove"` on remove buttons - AT users cannot identify which file *(Carbon)*
|
|
162
162
|
|
|
163
163
|
---
|
|
164
164
|
|
|
@@ -166,8 +166,8 @@ Cross-link: `reference/motion.md` — reduced-motion: skip slide/collapse animat
|
|
|
166
166
|
|
|
167
167
|
| Anti-pattern | Entry |
|
|
168
168
|
|--------------|-------|
|
|
169
|
-
| BAN-08 | File input hidden with display:none
|
|
170
|
-
| BAN-13 | Icon-only action button without aria-label
|
|
169
|
+
| BAN-08 | File input hidden with display:none - keyboard inaccessible - `reference/anti-patterns.md#ban-08` |
|
|
170
|
+
| BAN-13 | Icon-only action button without aria-label - `reference/anti-patterns.md#ban-13` |
|
|
171
171
|
|
|
172
172
|
---
|
|
173
173
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Input
|
|
1
|
+
# Input - Benchmark Spec
|
|
2
2
|
|
|
3
3
|
**Harvested from**: Material 3, Carbon, Ant Design, Mantine, Polaris, Fluent 2, Atlassian, shadcn/ui
|
|
4
4
|
**Wave**: 1 · **Category**: Inputs
|
|
@@ -47,7 +47,7 @@ Label * ← <label for="id"> — always visible
|
|
|
47
47
|
| Number | `type="number"` or `inputmode="numeric"` | Material 3, Ant, Mantine |
|
|
48
48
|
|
|
49
49
|
**Norm** (≥6/18): outlined with floating or static label is the most-cited default.
|
|
50
|
-
**Diverge**: floating vs. static label
|
|
50
|
+
**Diverge**: floating vs. static label - Material 3 uses floating; Carbon, Polaris, Atlassian use static (above). Static label is safer for a11y (floating requires JavaScript + ARIA management).
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
@@ -55,14 +55,14 @@ Label * ← <label for="id"> — always visible
|
|
|
55
55
|
|
|
56
56
|
| State | Trigger | Visual | ARIA |
|
|
57
57
|
|-------|---------|--------|------|
|
|
58
|
-
| default |
|
|
59
|
-
| hover | pointer over | Border lightens 20% |
|
|
60
|
-
| focus | keyboard / click | 2px focus-visible ring or thickened border |
|
|
61
|
-
| filled | has value | Label lifts (floating) or stays static |
|
|
58
|
+
| default | - | Resting border | - |
|
|
59
|
+
| hover | pointer over | Border lightens 20% | - |
|
|
60
|
+
| focus | keyboard / click | 2px focus-visible ring or thickened border | - |
|
|
61
|
+
| filled | has value | Label lifts (floating) or stays static | - |
|
|
62
62
|
| disabled | `disabled` attr | 38% opacity; cursor: not-allowed | `disabled` attr |
|
|
63
63
|
| read-only | `readonly` attr | No border change; cursor: default | `readonly` attr |
|
|
64
64
|
| error | invalid | Red/error border + icon + error message | `aria-invalid="true"` + `aria-describedby` |
|
|
65
|
-
| success | valid (opt.) | Green border + check icon |
|
|
65
|
+
| success | valid (opt.) | Green border + check icon | - |
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
|
@@ -75,20 +75,20 @@ Label * ← <label for="id"> — always visible
|
|
|
75
75
|
| lg | 48px | 16px | 16px | 16px |
|
|
76
76
|
|
|
77
77
|
**Norm**: 40px default height (Carbon, Polaris, Fluent, Atlassian confirm).
|
|
78
|
-
Minimum width: 200px
|
|
78
|
+
Minimum width: 200px - narrower inputs invite input truncation and frustrate users.
|
|
79
79
|
|
|
80
|
-
Cross-link: `reference/surfaces.md`
|
|
80
|
+
Cross-link: `reference/surfaces.md` - hit area ≥44px via padding; `reference/typography.md` - label sizing.
|
|
81
81
|
|
|
82
82
|
---
|
|
83
83
|
|
|
84
84
|
## Typography
|
|
85
85
|
|
|
86
86
|
- Label: 14px/500 above input; 12px when floating in focus/filled state
|
|
87
|
-
- Placeholder: 14px/400; color at 40% contrast minimum
|
|
87
|
+
- Placeholder: 14px/400; color at 40% contrast minimum - never the only label
|
|
88
88
|
- Helper/error: 12px/400; full contrast for error messages
|
|
89
89
|
- **Placeholder is not a label**: it disappears on type, fails contrast, and cannot be announced by screen readers as a persistent label
|
|
90
90
|
|
|
91
|
-
Cross-link: `reference/typography.md`
|
|
91
|
+
Cross-link: `reference/typography.md` - text-wrap, font-smoothing rules
|
|
92
92
|
|
|
93
93
|
---
|
|
94
94
|
|
|
@@ -99,7 +99,7 @@ Cross-link: `reference/typography.md` — text-wrap, font-smoothing rules
|
|
|
99
99
|
|
|
100
100
|
### Keyboard Contract
|
|
101
101
|
|
|
102
|
-
*Quoted verbatim from WAI-ARIA APG
|
|
102
|
+
*Quoted verbatim from WAI-ARIA APG - https://www.w3.org/WAI/ARIA/apg/patterns/textbox/ - W3C - 2024*
|
|
103
103
|
|
|
104
104
|
| Key | Action |
|
|
105
105
|
|-----|--------|
|
|
@@ -115,7 +115,7 @@ Password toggle and clear button must be keyboard accessible (Enter/Space activa
|
|
|
115
115
|
|
|
116
116
|
### Accessibility Rules
|
|
117
117
|
|
|
118
|
-
- Label MUST be associated via `<label for="id">` or `aria-label`
|
|
118
|
+
- Label MUST be associated via `<label for="id">` or `aria-label` - `placeholder` alone is not sufficient
|
|
119
119
|
- Error message MUST be linked via `aria-describedby` and triggered before or alongside visual indicator
|
|
120
120
|
- `aria-invalid="true"` MUST be set on the input when in error state
|
|
121
121
|
- `aria-required="true"` for required fields (supplement with visual `*` + legend)
|
|
@@ -133,7 +133,7 @@ Cross-link: `reference/accessibility.md`
|
|
|
133
133
|
| border colour | 100ms | ease | Focus/error state border change |
|
|
134
134
|
| error message in | 150ms | ease-out | Slide-down + fade; respect prefers-reduced-motion |
|
|
135
135
|
|
|
136
|
-
Cross-link: `reference/motion.md`
|
|
136
|
+
Cross-link: `reference/motion.md` - `prefers-reduced-motion` guard required on label float
|
|
137
137
|
|
|
138
138
|
---
|
|
139
139
|
|
|
@@ -146,10 +146,10 @@ Cross-link: `reference/motion.md` — `prefers-reduced-motion` guard required on
|
|
|
146
146
|
- Use `autocomplete` attributes for common fields (name, email, address) *(Polaris, Fluent)*
|
|
147
147
|
|
|
148
148
|
### Don't
|
|
149
|
-
- Don't use `placeholder` as the only label
|
|
149
|
+
- Don't use `placeholder` as the only label - it disappears and fails contrast *(Carbon, Polaris, Atlassian)*
|
|
150
150
|
- Don't show error state before the user has had a chance to input (premature validation) *(Polaris)*
|
|
151
|
-
- Don't remove the label on focus to create space
|
|
152
|
-
- Don't use `type="number"` for things that aren't math operands (phone, ZIP)
|
|
151
|
+
- Don't remove the label on focus to create space - floating labels break screen readers *(Atlassian)*
|
|
152
|
+
- Don't use `type="number"` for things that aren't math operands (phone, ZIP) - use `inputmode` instead *(Mantine, Carbon)*
|
|
153
153
|
|
|
154
154
|
---
|
|
155
155
|
|
|
@@ -157,7 +157,7 @@ Cross-link: `reference/motion.md` — `prefers-reduced-motion` guard required on
|
|
|
157
157
|
|
|
158
158
|
| Anti-pattern | Entry |
|
|
159
159
|
|--------------|-------|
|
|
160
|
-
| Placeholder-as-label | `reference/anti-patterns.md`
|
|
160
|
+
| Placeholder-as-label | `reference/anti-patterns.md` - no dedicated BAN yet; cross-ref accessibility.md |
|
|
161
161
|
|
|
162
162
|
---
|
|
163
163
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Label
|
|
1
|
+
# Label - Benchmark Spec
|
|
2
2
|
|
|
3
3
|
**Harvested from**: WAI-ARIA APG, Carbon, Material 3, Mantine, Polaris, Atlassian, Fluent 2, shadcn/ui
|
|
4
4
|
**Wave**: 1 · **Category**: Inputs
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
9
9
|
|
|
10
|
-
A label is the visible text that identifies a form control to the user and to assistive technology. It is the most critical accessibility primitive in forms
|
|
10
|
+
A label is the visible text that identifies a form control to the user and to assistive technology. It is the most critical accessibility primitive in forms - every input, select, checkbox, radio, and switch MUST have an associated label. Labels are distinct from placeholders (which disappear) and from hints (which supplement but do not replace). *(WAI-ARIA APG, Carbon, Polaris, Atlassian all agree)*
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -42,26 +42,26 @@ Alternative (legend for group):
|
|
|
42
42
|
|
|
43
43
|
| Variant | Description | Systems |
|
|
44
44
|
|---------|-------------|---------|
|
|
45
|
-
| Static label (above) | Fixed position above control
|
|
45
|
+
| Static label (above) | Fixed position above control - most accessible | Carbon, Polaris, Atlassian, Fluent |
|
|
46
46
|
| Floating label | Starts inside control, floats up on focus/fill | Material 3, Mantine, shadcn |
|
|
47
47
|
| Inline label | Label beside control (radio/checkbox) | All |
|
|
48
48
|
| Legend | Group label inside `<fieldset>` | WAI-ARIA APG, all (for groups) |
|
|
49
49
|
| Visually hidden | Accessible but not visible (e.g., search icon button) | WAI-ARIA APG, Carbon |
|
|
50
50
|
|
|
51
|
-
**Norm** (≥5/18): static label above the control is the most accessible and implementation-simple approach
|
|
52
|
-
**Diverge**: floating label
|
|
51
|
+
**Norm** (≥5/18): static label above the control is the most accessible and implementation-simple approach - recommended as the default.
|
|
52
|
+
**Diverge**: floating label - Material 3 and Mantine use it; Carbon, Polaris, Atlassian explicitly recommend static labels for a11y predictability. Floating labels require JavaScript, break if JS fails, and require careful `aria-*` management.
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
56
|
## States
|
|
57
57
|
|
|
58
|
-
Labels are not interactive
|
|
58
|
+
Labels are not interactive - they have no hover/focus states of their own. However:
|
|
59
59
|
|
|
60
60
|
| Control State | Label Behaviour |
|
|
61
61
|
|---------------|-----------------|
|
|
62
62
|
| error | Label colour may shift to error colour (optional); error text replaces/appends helper |
|
|
63
63
|
| disabled | Label at 38% opacity alongside disabled control |
|
|
64
|
-
| required | Required indicator (`*`) added
|
|
64
|
+
| required | Required indicator (`*`) added - never remove from DOM |
|
|
65
65
|
| focus (on control) | Label may shift colour to primary (Material 3 floating) |
|
|
66
66
|
|
|
67
67
|
---
|
|
@@ -70,19 +70,19 @@ Labels are not interactive — they have no hover/focus states of their own. How
|
|
|
70
70
|
|
|
71
71
|
| Property | Value | Notes |
|
|
72
72
|
|----------|-------|-------|
|
|
73
|
-
| Font size | 14px (static); 12px (floating
|
|
73
|
+
| Font size | 14px (static); 12px (floating - small state) | |
|
|
74
74
|
| Weight | 500 | Slightly heavier than body to distinguish |
|
|
75
75
|
| Gap: label → control | 4–8px | *(Carbon: 4px, Material 3: 8px)* |
|
|
76
76
|
| Required asterisk gap | 2px left of asterisk | |
|
|
77
77
|
| Width | Match control width | Labels should not exceed their control |
|
|
78
78
|
|
|
79
|
-
Cross-link: `reference/typography.md`
|
|
79
|
+
Cross-link: `reference/typography.md` - label sizing rules
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
83
83
|
## Typography
|
|
84
84
|
|
|
85
|
-
- Label text: 14px/500
|
|
85
|
+
- Label text: 14px/500 - slightly heavier than body 400; distinguishes from surrounding content
|
|
86
86
|
- Required `*`: same size, colour matches error or primary brand colour
|
|
87
87
|
- Visually-hidden labels: use CSS `.sr-only` pattern (clip + overflow: hidden + absolute), never `display:none` or `visibility:hidden`
|
|
88
88
|
|
|
@@ -108,20 +108,20 @@ Cross-link: `reference/typography.md` — label sizing rules
|
|
|
108
108
|
|
|
109
109
|
### Association Methods (in order of preference)
|
|
110
110
|
|
|
111
|
-
*Per WAI-ARIA APG
|
|
111
|
+
*Per WAI-ARIA APG - https://www.w3.org/WAI/ARIA/apg/ - W3C - 2024*
|
|
112
112
|
|
|
113
|
-
1. **`<label for="id">`**
|
|
114
|
-
2. **`aria-labelledby="label-id"`**
|
|
115
|
-
3. **`aria-label="string"`**
|
|
116
|
-
4. **`<legend>` inside `<fieldset>`**
|
|
113
|
+
1. **`<label for="id">`** - native HTML; best browser + AT support; clicking label focuses control
|
|
114
|
+
2. **`aria-labelledby="label-id"`** - when label cannot use `for` (complex composites)
|
|
115
|
+
3. **`aria-label="string"`** - when no visible label is possible (icon-only controls); last resort
|
|
116
|
+
4. **`<legend>` inside `<fieldset>`** - for groups of related controls; not replaceable by `aria-label`
|
|
117
117
|
|
|
118
118
|
### Accessibility Rules
|
|
119
119
|
|
|
120
|
-
- NEVER use `placeholder` as the only label
|
|
120
|
+
- NEVER use `placeholder` as the only label - it disappears on input and fails colour contrast *(WAI-ARIA APG, WCAG 1.3.1)*
|
|
121
121
|
- Required fields: mark with `aria-required="true"` on the control AND `*` visually; provide a form-level note explaining the `*` convention
|
|
122
|
-
- Optional fields: prefer marking optional fields with "(optional)" text over marking every required field with `*`
|
|
123
|
-
- Group labels: `<legend>` inside `<fieldset>` is the ONLY proper group label technique
|
|
124
|
-
- Visually hidden labels: use `.sr-only` CSS
|
|
122
|
+
- Optional fields: prefer marking optional fields with "(optional)" text over marking every required field with `*` - reduces asterisk clutter in long forms *(Polaris, Carbon)*
|
|
123
|
+
- Group labels: `<legend>` inside `<fieldset>` is the ONLY proper group label technique - `aria-label` on a `<div>` group is inadequate for radio/checkbox groups in most AT
|
|
124
|
+
- Visually hidden labels: use `.sr-only` CSS - never `display:none` (removes from AT tree) or `visibility:hidden`
|
|
125
125
|
|
|
126
126
|
---
|
|
127
127
|
|
|
@@ -129,15 +129,15 @@ Cross-link: `reference/typography.md` — label sizing rules
|
|
|
129
129
|
|
|
130
130
|
### Do
|
|
131
131
|
- Place labels above controls, not beside them, for forms wider than 240px *(Carbon, Polaris, Atlassian)*
|
|
132
|
-
- Use `<label for="id">`
|
|
132
|
+
- Use `<label for="id">` - the click zone extends to the full label, improving usability *(WAI-ARIA APG, all)*
|
|
133
133
|
- Explain the `*` required indicator once near the top of the form *(Polaris, Carbon)*
|
|
134
|
-
- Use `<legend>` for groups
|
|
134
|
+
- Use `<legend>` for groups - it is read before each option in the group *(WAI-ARIA APG)*
|
|
135
135
|
|
|
136
136
|
### Don't
|
|
137
|
-
- Don't use `placeholder` as the only label
|
|
138
|
-
- Don't use `display:none` on labels
|
|
139
|
-
- Don't write labels as questions ("What is your name?")
|
|
140
|
-
- Don't truncate label text
|
|
137
|
+
- Don't use `placeholder` as the only label - it fails at 3 accessibility criteria *(WAI-ARIA APG, WCAG 1.3.1, 1.4.3)*
|
|
138
|
+
- Don't use `display:none` on labels - removes them from the AT accessibility tree *(WAI-ARIA APG)*
|
|
139
|
+
- Don't write labels as questions ("What is your name?") - prefer noun phrases ("Full name") *(Polaris, Carbon)*
|
|
140
|
+
- Don't truncate label text - ellipsis hides required information from all users *(Atlassian, Carbon)*
|
|
141
141
|
|
|
142
142
|
---
|
|
143
143
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Link
|
|
1
|
+
# Link - Benchmark Spec
|
|
2
2
|
|
|
3
3
|
**Harvested from**: Carbon, Polaris, Primer (GitHub), Fluent 2, WAI-ARIA APG, Material 3, Mantine, Atlassian
|
|
4
4
|
**Wave**: 1 · **Category**: Inputs
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
9
9
|
|
|
10
|
-
A link navigates the user to a new resource
|
|
10
|
+
A link navigates the user to a new resource - another page, section, or external URL. It is the semantic counterpart to Button: if clicking takes the user somewhere, it is a `<a href>` link; if it triggers an action in the current context, it is a button. Never reverse these roles. *(Carbon, Primer, WAI-ARIA APG all enforce this boundary)*
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -28,11 +28,11 @@ External: [Open dashboard ↗]
|
|
|
28
28
|
| Part | Required | Notes |
|
|
29
29
|
|------|----------|-------|
|
|
30
30
|
| `<a href>` | Yes | Native element; href MUST be a real URL or `#anchor` |
|
|
31
|
-
| Visible label | Yes | Descriptive of destination
|
|
31
|
+
| Visible label | Yes | Descriptive of destination - not "click here" or "read more" |
|
|
32
32
|
| Underline | Conditional | Required for inline links in body text; optional for standalone/nav |
|
|
33
33
|
| Visited state | No | Encouraged for inline links in long-form content |
|
|
34
34
|
| External icon | Conditional | Required when `target="_blank"`; 12–14px, inline-aligned |
|
|
35
|
-
| `rel="noopener noreferrer"` | Yes (external) | Security
|
|
35
|
+
| `rel="noopener noreferrer"` | Yes (external) | Security - prevents opener access |
|
|
36
36
|
|
|
37
37
|
---
|
|
38
38
|
|
|
@@ -47,8 +47,8 @@ External: [Open dashboard ↗]
|
|
|
47
47
|
| Destructive | Rare; red colour for delete-via-link patterns | Polaris (critical link) |
|
|
48
48
|
| Disabled | `aria-disabled="true"` + `tabindex="-1"` | Carbon, Primer |
|
|
49
49
|
|
|
50
|
-
**Norm** (≥6/18): inline links in body text MUST be underlined
|
|
51
|
-
**Diverge**: visited state
|
|
50
|
+
**Norm** (≥6/18): inline links in body text MUST be underlined - colour alone fails WCAG 1.4.1.
|
|
51
|
+
**Diverge**: visited state - Primer and Carbon use it for documentation; most SaaS systems omit it.
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
@@ -57,9 +57,9 @@ External: [Open dashboard ↗]
|
|
|
57
57
|
| State | Visual | ARIA / HTML |
|
|
58
58
|
|-------|--------|-------------|
|
|
59
59
|
| default | Underline + colour | `href` present |
|
|
60
|
-
| hover | Colour shift (10% darker/lighter) |
|
|
61
|
-
| focus | 2px focus-visible ring |
|
|
62
|
-
| active / pressed | Colour darkens + subtle scale 0.98 |
|
|
60
|
+
| hover | Colour shift (10% darker/lighter) | - |
|
|
61
|
+
| focus | 2px focus-visible ring | - |
|
|
62
|
+
| active / pressed | Colour darkens + subtle scale 0.98 | - |
|
|
63
63
|
| visited | Distinct colour (purple conventional) | `:visited` pseudo-class |
|
|
64
64
|
| disabled | 38% opacity; pointer-events: none | `aria-disabled="true"` + `tabindex="-1"` |
|
|
65
65
|
|
|
@@ -67,11 +67,11 @@ External: [Open dashboard ↗]
|
|
|
67
67
|
|
|
68
68
|
## Sizing & Spacing
|
|
69
69
|
|
|
70
|
-
- Links inherit parent font-size and line-height
|
|
70
|
+
- Links inherit parent font-size and line-height - do not override
|
|
71
71
|
- Standalone link min-height: 44px via padding for touch targets
|
|
72
72
|
- Icon size (external/leading): 12–14px; `vertical-align: middle`; 4px gap from text
|
|
73
73
|
|
|
74
|
-
Cross-link: `reference/surfaces.md`
|
|
74
|
+
Cross-link: `reference/surfaces.md` - hit-area pattern for standalone links
|
|
75
75
|
|
|
76
76
|
---
|
|
77
77
|
|
|
@@ -79,7 +79,7 @@ Cross-link: `reference/surfaces.md` — hit-area pattern for standalone links
|
|
|
79
79
|
|
|
80
80
|
- Inline links: same weight as surrounding text (400); underline distinguishes them
|
|
81
81
|
- Standalone links: 400–500 weight; may have leading icon or trailing arrow
|
|
82
|
-
- Never use ALL CAPS for links
|
|
82
|
+
- Never use ALL CAPS for links - reduces readability and implies different semantics
|
|
83
83
|
- Truncate with ellipsis + `title` attribute only when space is genuinely constrained
|
|
84
84
|
|
|
85
85
|
---
|
|
@@ -87,11 +87,11 @@ Cross-link: `reference/surfaces.md` — hit-area pattern for standalone links
|
|
|
87
87
|
## Keyboard & Accessibility
|
|
88
88
|
|
|
89
89
|
> **WAI-ARIA role**: `link` (implicit on `<a href>`)
|
|
90
|
-
> **Required attributes**: `href`
|
|
90
|
+
> **Required attributes**: `href` - without it, the element is not a link and has no keyboard access
|
|
91
91
|
|
|
92
92
|
### Keyboard Contract
|
|
93
93
|
|
|
94
|
-
*Quoted verbatim from WAI-ARIA APG
|
|
94
|
+
*Quoted verbatim from WAI-ARIA APG - https://www.w3.org/WAI/ARIA/apg/patterns/link/ - W3C - 2024*
|
|
95
95
|
|
|
96
96
|
| Key | Action |
|
|
97
97
|
|-----|--------|
|
|
@@ -101,11 +101,11 @@ Cross-link: `reference/surfaces.md` — hit-area pattern for standalone links
|
|
|
101
101
|
|
|
102
102
|
### Accessibility Rules
|
|
103
103
|
|
|
104
|
-
- Link text MUST describe the destination
|
|
104
|
+
- Link text MUST describe the destination - "click here" and "read more" fail 2.4.6 (descriptive labels)
|
|
105
105
|
- External links opening in new tab MUST disclose this: append "(opens in new tab)" to `aria-label`, or use a visually-hidden span
|
|
106
106
|
- `target="_blank"` MUST always be paired with `rel="noopener noreferrer"` (security + performance)
|
|
107
|
-
- Disabled links: `aria-disabled="true"` + `tabindex="-1"`
|
|
108
|
-
- Inline links in body text MUST be underlined
|
|
107
|
+
- Disabled links: `aria-disabled="true"` + `tabindex="-1"` - never `href=""` or `href="#"`
|
|
108
|
+
- Inline links in body text MUST be underlined - colour alone is insufficient for WCAG 1.4.1 (non-text contrast)
|
|
109
109
|
- Icon-only links (e.g., social icons) MUST have `aria-label` describing the destination
|
|
110
110
|
|
|
111
111
|
---
|
|
@@ -123,12 +123,12 @@ Cross-link: `reference/surfaces.md` — hit-area pattern for standalone links
|
|
|
123
123
|
|
|
124
124
|
### Do
|
|
125
125
|
- Use descriptive link text: "View account settings" not "click here" *(Polaris, Carbon, WAI-ARIA APG)*
|
|
126
|
-
- Underline inline links in body text *(Carbon, Polaris, WAI-ARIA APG
|
|
126
|
+
- Underline inline links in body text *(Carbon, Polaris, WAI-ARIA APG - WCAG 1.4.1)*
|
|
127
127
|
- Add `rel="noopener noreferrer"` to all `target="_blank"` links *(Primer, Carbon, Fluent 2)*
|
|
128
128
|
- Disclose new-tab behavior in `aria-label` or visually-hidden text *(WAI-ARIA APG, Primer)*
|
|
129
129
|
|
|
130
130
|
### Don't
|
|
131
|
-
- Don't use `<a>` without `href`
|
|
131
|
+
- Don't use `<a>` without `href` - it's not a link, not keyboard-accessible, and will confuse screen readers *(WAI-ARIA APG)*
|
|
132
132
|
- Don't use `<button>` when the action is navigation *(Carbon, Primer)*
|
|
133
133
|
- Don't rely on colour alone to distinguish links from surrounding text *(WCAG 1.4.1)*
|
|
134
134
|
- Don't open links in new tabs unexpectedly without disclosure *(Polaris, Primer, WCAG 3.2.5)*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# List (Interactive & Display)
|
|
1
|
+
# List (Interactive & Display) - Benchmark Spec
|
|
2
2
|
|
|
3
3
|
**Harvested from**: Carbon, Polaris, Material 3, Mantine, WAI-ARIA APG, UUPM (app-interface, MIT)
|
|
4
4
|
**Wave**: 4 · **Category**: Navigation & Data
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
9
9
|
|
|
10
|
-
A list component handles two distinct patterns: (1) a display list renders a series of items using semantic `<ul>/<ol>/<li>` HTML
|
|
10
|
+
A list component handles two distinct patterns: (1) a display list renders a series of items using semantic `<ul>/<ol>/<li>` HTML - no ARIA needed; (2) an interactive list (listbox) presents selectable options with keyboard navigation and selection state. Use a display list for content; use an interactive listbox when users choose one or more items from a set. *(Carbon, Polaris, Material 3 all define separate display and interactive list patterns)*
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -58,8 +58,8 @@ Display list: Interactive listbox:
|
|
|
58
58
|
|
|
59
59
|
| State | Trigger | Visual | ARIA |
|
|
60
60
|
|-------|---------|--------|------|
|
|
61
|
-
| default |
|
|
62
|
-
| option-hover | pointer over | 8% overlay |
|
|
61
|
+
| default | - | Items visible; none selected | `aria-selected="false"` on all options |
|
|
62
|
+
| option-hover | pointer over | 8% overlay | - |
|
|
63
63
|
| option-focus | keyboard focus | 2px focus-visible ring | managed via `tabindex` |
|
|
64
64
|
| option-selected | click or Enter/Space | Filled highlight; checkmark for multi-select | `aria-selected="true"` |
|
|
65
65
|
| option-disabled | disabled prop | 38% opacity; cursor: default | `aria-disabled="true"` |
|
|
@@ -90,7 +90,7 @@ Display list: Interactive listbox:
|
|
|
90
90
|
- Empty state heading: heading-sm, center-aligned
|
|
91
91
|
- Empty state body: body-sm, `color: --text-subtle`
|
|
92
92
|
|
|
93
|
-
Cross-link: `reference/typography.md`
|
|
93
|
+
Cross-link: `reference/typography.md` - body-sm, heading scale
|
|
94
94
|
|
|
95
95
|
---
|
|
96
96
|
|
|
@@ -101,7 +101,7 @@ Cross-link: `reference/typography.md` — body-sm, heading scale
|
|
|
101
101
|
|
|
102
102
|
### Keyboard Contract
|
|
103
103
|
|
|
104
|
-
*Quoted verbatim from WAI-ARIA APG
|
|
104
|
+
*Quoted verbatim from WAI-ARIA APG - https://www.w3.org/WAI/ARIA/apg/patterns/listbox/ - W3C - 2024*
|
|
105
105
|
|
|
106
106
|
| Key | Action |
|
|
107
107
|
|-----|--------|
|
|
@@ -117,14 +117,14 @@ Cross-link: `reference/typography.md` — body-sm, heading scale
|
|
|
117
117
|
|
|
118
118
|
### Accessibility Rules
|
|
119
119
|
|
|
120
|
-
- Display lists use native `<ul>/<li>`
|
|
121
|
-
- Interactive lists MUST use `role="listbox"` + `role="option"`
|
|
120
|
+
- Display lists use native `<ul>/<li>` - no ARIA roles needed; they are already accessible
|
|
121
|
+
- Interactive lists MUST use `role="listbox"` + `role="option"` - not `<ul>/<li>` with click handlers
|
|
122
122
|
- `aria-selected` MUST be present on every `role="option"` (either `true` or `false`)
|
|
123
123
|
- Multi-select listbox MUST declare `aria-multiselectable="true"` on the container
|
|
124
124
|
- Virtual scroll: all options in the virtualised window must have correct `aria-posinset` and `aria-setsize` attributes
|
|
125
125
|
- Empty state container MUST have `aria-label` or `aria-live` so AT announces the empty state
|
|
126
126
|
|
|
127
|
-
Cross-link: `reference/accessibility.md`
|
|
127
|
+
Cross-link: `reference/accessibility.md` - listbox pattern, virtual list accessibility
|
|
128
128
|
|
|
129
129
|
---
|
|
130
130
|
|
|
@@ -136,25 +136,25 @@ Cross-link: `reference/accessibility.md` — listbox pattern, virtual list acces
|
|
|
136
136
|
| Skeleton item shimmer | 1500ms | linear loop | Loading placeholder |
|
|
137
137
|
| Empty state entry | 150ms | ease-out | Fade in |
|
|
138
138
|
|
|
139
|
-
**BAN**: Do not animate item reordering unless using a deliberate drag-and-drop library
|
|
139
|
+
**BAN**: Do not animate item reordering unless using a deliberate drag-and-drop library - unsolicited reordering causes disorientation.
|
|
140
140
|
|
|
141
|
-
Cross-link: `reference/motion.md`
|
|
141
|
+
Cross-link: `reference/motion.md` - skeleton shimmer, list animations
|
|
142
142
|
|
|
143
143
|
---
|
|
144
144
|
|
|
145
145
|
## Do / Don't
|
|
146
146
|
|
|
147
147
|
### Do
|
|
148
|
-
- Use native `<ul>/<ol>/<li>` for display-only lists
|
|
148
|
+
- Use native `<ul>/<ol>/<li>` for display-only lists - no ARIA needed *(WAI-ARIA APG)*
|
|
149
149
|
- Use `role="listbox"` + `role="option"` for selectable lists *(WAI-ARIA APG, Carbon, Polaris)*
|
|
150
150
|
- Virtualise at > 100 items to prevent DOM bloat *(Carbon, Mantine)*
|
|
151
151
|
- Provide a meaningful empty state with a CTA when the list can be populated *(Polaris, Material 3)*
|
|
152
152
|
|
|
153
153
|
### Don't
|
|
154
|
-
- Don't use `<div onClick>` list items without `role="option"`
|
|
155
|
-
- Don't omit `aria-selected` on options
|
|
156
|
-
- Don't use `<ul>/<li>` with `role="option"`
|
|
157
|
-
- Don't load all items at once when count > 100
|
|
154
|
+
- Don't use `<div onClick>` list items without `role="option"` - keyboard-inaccessible *(WCAG 2.1.1)*
|
|
155
|
+
- Don't omit `aria-selected` on options - AT cannot determine what is selected *(WAI-ARIA APG)*
|
|
156
|
+
- Don't use `<ul>/<li>` with `role="option"` - mixing native list semantics and listbox ARIA creates conflicts *(WAI-ARIA)*
|
|
157
|
+
- Don't load all items at once when count > 100 - renders slowly and wastes memory *(Carbon, Mantine)*
|
|
158
158
|
|
|
159
159
|
---
|
|
160
160
|
|
|
@@ -162,7 +162,7 @@ Cross-link: `reference/motion.md` — skeleton shimmer, list animations
|
|
|
162
162
|
|
|
163
163
|
| Anti-pattern | Entry |
|
|
164
164
|
|--------------|-------|
|
|
165
|
-
| BAN-04 | `transition: all` on interactive elements
|
|
165
|
+
| BAN-04 | `transition: all` on interactive elements - `reference/anti-patterns.md#ban-04` |
|
|
166
166
|
|
|
167
167
|
---
|
|
168
168
|
|