* feat(craft): add accessibility-baseline + opt-ins on dashboard, hr-onboarding, mobile-onboarding Module 3 of 5 in the behavioral craft series proposed in #501. Modules 1 (state-coverage, #502) and 2 (animation-discipline, #515) merged earlier today. The differentiator that survived the corpus review is native-mobile parity. Existing OSS prior art (fecarrico/A11Y.md, awesome-copilot, Community-Access) covers web ARIA well, none covers Flutter Semantics, Compose semantics, iOS UIKit/SwiftUI, or RN labelling APIs. Secondary differentiator: jurisdictional legal-floor calibration. EAA references WCAG 2.1 (via EN 301 549 v3.2.1), not 2.2. ADA Title II 2026-04-24 deadline slipped to 2027-04-26 via 2026-04-20 IFR. Most existing OSS a11y prior art doesn't track either accurately. Three-loop adversarial review pass before push (codex unavailable, ran via substitute agent). Loop 1 caught nine cuts plus four factual fixes including a wrong Android Compose API name. Loop 2 verified and flagged two more trims. Loop 3 said ship. Anchored citations: WCAG 2.2 Understanding pages, ISO/IEC 40500:2025, ADA Title II 2024 + 2026-04-20 IFR, EN 301 549 v3.2.1, WAI-ARIA 1.3 + AccName 1.2 + Core AAM 1.2, WebAIM Million 2025, A11yn (arXiv 2510.13914), APCA W3C silver branch. Refs #501. * fix(craft): accessibility-baseline review fixes (lefarcen + mrcfps) Address all P1/P2/P3 findings: - P1 (lefarcen): add "Keyboard operability and semantic structure" section covering tab reachability (2.1.1), activation keys, no keyboard trap (2.1.2), focus order (2.4.3), native-control-first, document language (3.1.1), heading hierarchy (1.3.1, 2.4.6), landmarks (1.3.1, 2.4.1), text alternatives (1.1.1) - P2 (lefarcen): expand jurisdiction scope with US Section 508 (WCAG 2.0 AA), ADA Title III caveat, EU WAD reference - P2 (lefarcen + mrcfps): rename contrast-table row to "Normal text below 18 pt regular / 14 pt bold" so the table matches the threshold rule - P2 (mrcfps): correct "exclusive" → "inclusive" — exact 4.5:1 / 3:1 passes; the no-rounding rule is what makes 2.999:1 fail - P2 (lefarcen): add "Prior art and scope" note differentiating from existing OSS a11y agent docs - P3 (lefarcen): narrow APCA framing to "not part of WCAG/EN/ADA/Section 508" and clarify size/weight-dependent thresholds - P3 (lefarcen): expand WCAG 2.5.8 exceptions list (Spacing, Equivalent, Inline, User Agent Control, Essential) - Common-mistakes additions: Section 508/2.1 confusion, tabindex>0 anti-pattern, modal-focus-trap distinction from 2.1.2, heading-size vs level confusion * fix(craft): accessibility-baseline mrcfps round-2 precision fixes All three non-blocking precision items addressed: - Update WebAIM Million benchmark from 2025 to 2026 (February 2026 crawl). Form labels: page-level 51% (was 48.2%), input-level 33.1% (was 34.2%) of 6.9M inputs (was 6.3M). ARIA: 59.1 errors on ARIA pages vs 42 on non-ARIA (was 57 vs 27); gap is ~17 in 2026, was 30 in 2025. ARIA usage 82.7% of pages (was 79.4%). Verified directly against webaim.org/projects/million/. - Soften keyboard/semantic-structure intro: Level A items are still labeled Level A, but 2.4.6 Headings and Labels is correctly tagged AA, and the one-h1 / no-skipped-levels rules are now framed as OD craft conventions on top of WCAG's programmatic-structure floor (1.3.1). - Tighten <a> activation note: bare <a> without href is not focusable, not a link, and not keyboard-operable. Use <a href="…"> for navigation or <button> for actions. Added a "common mistakes" entry to lock the rule. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Craft references
Brand-agnostic craft knowledge. Each file is a small, dense rulebook on one dimension of professional UI craft (typography, color, motion, …). Skills opt into the references they need; the daemon injects only the requested ones into the system prompt above the active skill body.
Why a third axis next to skills/ and design-systems/
| Axis | Scope | Example |
|---|---|---|
skills/ |
Artifact shape | saas-landing, dashboard, pricing-page |
design-systems/ |
Brand visual language (the 9-section DESIGN.md) |
linear-app, apple, notion |
craft/ |
Universal craft knowledge — true regardless of brand | letter-spacing rules, accent-overuse caps, anti-AI-slop |
DESIGN.md tells the agent which colors and fonts a brand uses. craft/
tells the agent the universal rules a competent designer applies on top —
e.g. ALL CAPS always needs ≥0.06em tracking, regardless of the brand.
How a skill opts in
Add an od.craft.requires array to the skill's front-matter. Only the
listed sections are injected, so a skill that needs only typography pays
no token cost for color/motion content.
od:
craft:
requires: [typography, color, anti-ai-slop]
Allowed values match the file names in this directory minus the .md
extension. Unknown values are silently ignored (forward-compatible).
Why silent fallback instead of fail-fast?
A skeptical reader will ask: "If a skill requests a planned-but-not-yet-vendored
section and the corresponding file doesn't exist yet, shouldn't we warn
the user?" We chose forward-compatibility over fail-fast: a skill
authored today can list a planned slug and start benefiting the moment
the matching craft/<slug>.md is vendored in a follow-up PR, with no
skill edit needed. The cost of a missed reference is a missing
paragraph in the system prompt, not a broken skill — so the loud
failure mode is not worth the friction.
Note for skill authors arriving from older guidance: an earlier draft
used motion as the future-slug placeholder. The shipped equivalent
today is animation-discipline. Use that one if your skill emits
motion.
Enforcement levels
Craft files mix auto-checked rules and guidance.
- Auto-checked. Rules wired into
apps/daemon/src/lint-artifact.ts— currently the P0 list inanti-ai-slop.md(Tailwind-indigo accent, two-stop hero gradients, emoji-as-icons, etc.). The linter reports these as findings back to the UI (for P0/P1 badges) and to the agent (as a system reminder for self-correction). Artifact persistence is not currently hard-blocked on P0 hits. - Guidance. The rest. The agent reads the rules, reviewers apply them, the linter doesn't check them.
A purely behavioral craft file (state-coverage, animation-discipline) is guidance unless a specific rule is later promoted into lint-artifact.ts.
Files
| File | Section name | When to require |
|---|---|---|
typography.md |
typography |
Any skill that emits typed content (~all skills) |
color.md |
color |
Any skill that emits styled output (~all skills) |
anti-ai-slop.md |
anti-ai-slop |
Marketing pages, landing pages, decks |
state-coverage.md |
state-coverage |
Any skill with stateful UI (dashboards, mobile apps, forms, list/table views) |
animation-discipline.md |
animation-discipline |
Any skill that ships motion: mobile apps, multi-screen flows, gamified UI, transitions, microinteractions |
accessibility-baseline.md |
accessibility-baseline |
Any skill that ships interactive UI: dashboards, forms, mobile flows, anything with focus/labels/keyboard paths |
Partial-stateful skills. A skill that's mostly static but contains an embedded form, data table, or query surface should opt in. State-coverage rules apply to the stateful component, not the whole page.
More sections (icons, craft-details) will be added in follow-up
PRs as we wire the linter side.
Attribution
Craft content is adapted from the MIT-licensed
refero_skill project
(© Refero Design), with edits to fit Open Design's house style and link
back to OD's design tokens (var(--accent) etc.) instead of generic
Tailwind hex values.