[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GSXW2FDKPCP2MGSJARK6C7":3,"skill-same:01M6GSXW2FDKPCP2MGSJARK6C7":76},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":46,"commitSha":47,"skillDirectory":48,"forksCount":14,"repositoryHtmlUrl":49,"repositoryHomepageUrl":6,"ownerHtmlUrl":50,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":51,"install":52,"resources":65},"01M6GSXW2FDKPCP2MGSJARK6C7","web-accessibility",null,"Audit and improve web accessibility following WCAG 2.2 guidelines. Use when asked to \"improve accessibility\", \"a11y audit\", \"WCAG compliance\", \"screen reader support\", \"keyboard navigation\", or \"make accessible\".","japurcell\u002Fskills","japurcell","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F10947458?v=4","01M6GSJK1YAG95R6VHF47V30KY","Adam Purcell","01M6GSJK6817NVR5FVDMFFNJ6H",0,"MIT","https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fdefault\u002Fweb-accessibility\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"web","accessibility","web accessibility","when","support","a11y","make","screen","keyboard","navigation","use","a11y audit","reader","quality","improve","WCAG","compliance","audit","guidelines","2026-11-10 10:12:30",false,"---\nname: web-accessibility\ndescription: Audit and improve web accessibility following WCAG 2.2 guidelines. Use when asked to \"improve accessibility\", \"a11y audit\", \"WCAG compliance\", \"screen reader support\", \"keyboard navigation\", or \"make accessible\".\nlicense: MIT\nmetadata:\n  author: web-quality-skills\n  version: \"2.0\"\n---\n\n# Accessibility (a11y)\n\nComprehensive accessibility guidelines based on WCAG 2.2 and Lighthouse accessibility audits. Goal: make content usable by everyone, including people with disabilities.\n\n## Evidence-led audit workflow\n\nWhen a rendered page is available:\n\n1. Run a live Lighthouse Accessibility audit when that capability is available; with Chrome DevTools MCP, use `lighthouse_audit`. Use mobile navigation mode for a general public page or snapshot mode when reloading would lose authenticated or user-created state.\n2. Use failed audit nodes to localize the relevant component or template instead of searching the whole repository for generic patterns.\n3. Inspect a rendered accessibility-tree snapshot for names, roles, states, landmarks, and heading structure; with Chrome DevTools MCP, use `take_snapshot`. Exercise the affected flow with the keyboard.\n4. Fix the source, then re-run the same audit and manual interaction.\n\nIf the live tools are unavailable, use Lighthouse CLI or axe for automated coverage and complete the same manual checks. Automated tools detect only a subset of accessibility barriers: a score of 100 is not WCAG conformance, and a low score does not replace issue-level evidence.\n\n## WCAG Principles: POUR\n\n| Principle          | Description                                       |\n| ------------------ | ------------------------------------------------- |\n| **P**erceivable    | Content can be perceived through different senses |\n| **O**perable       | Interface can be operated by all users            |\n| **U**nderstandable | Content and interface are understandable          |\n| **R**obust         | Content works with assistive technologies         |\n\n## Conformance levels\n\n| Level   | Requirement            | Target                                                |\n| ------- | ---------------------- | ----------------------------------------------------- |\n| **A**   | Minimum accessibility  | Must pass                                             |\n| **AA**  | Standard compliance    | Should pass (legal requirement in many jurisdictions) |\n| **AAA** | Enhanced accessibility | Nice to have                                          |\n\n---\n\n## Perceivable\n\n### Text alternatives (1.1)\n\n**Images require alt text:**\n\n```html\n\u003C!-- ❌ Missing alt -->\n\u003Cimg src=\"chart.png\" \u002F>\n\n\u003C!-- ✅ Descriptive alt -->\n\u003Cimg src=\"chart.png\" alt=\"Bar chart showing 40% increase in Q3 sales\" \u002F>\n\n\u003C!-- ✅ Decorative image (empty alt) -->\n\u003Cimg src=\"decorative-border.png\" alt=\"\" role=\"presentation\" \u002F>\n\n\u003C!-- ✅ Complex image with longer description -->\n\u003Cfigure>\n  \u003Cimg\n    src=\"infographic.png\"\n    alt=\"2024 market trends infographic\"\n    aria-describedby=\"infographic-desc\"\n  \u002F>\n  \u003Cfigcaption id=\"infographic-desc\">\n    \u003C!-- Detailed description -->\n  \u003C\u002Ffigcaption>\n\u003C\u002Ffigure>\n```\n\n**Icon buttons need accessible names:**\n\n```html\n\u003C!-- ❌ No accessible name -->\n\u003Cbutton>\n  \u003Csvg>\u003C!-- menu icon -->\u003C\u002Fsvg>\n\u003C\u002Fbutton>\n\n\u003C!-- ✅ Using aria-label -->\n\u003Cbutton aria-label=\"Open menu\">\n  \u003Csvg aria-hidden=\"true\">\u003C!-- menu icon -->\u003C\u002Fsvg>\n\u003C\u002Fbutton>\n\n\u003C!-- ✅ Using visually hidden text -->\n\u003Cbutton>\n  \u003Csvg aria-hidden=\"true\">\u003C!-- menu icon -->\u003C\u002Fsvg>\n  \u003Cspan class=\"visually-hidden\">Open menu\u003C\u002Fspan>\n\u003C\u002Fbutton>\n```\n\n**Visually hidden class:**\n\n```css\n.visually-hidden {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  white-space: nowrap;\n  border: 0;\n}\n```\n\n### Color contrast (1.4.3, 1.4.6)\n\n| Text Size                          | AA minimum | AAA enhanced |\n| ---------------------------------- | ---------- | ------------ |\n| Normal text (\u003C 18px \u002F \u003C 14px bold) | 4.5:1      | 7:1          |\n| Large text (≥ 18px \u002F ≥ 14px bold)  | 3:1        | 4.5:1        |\n| UI components & graphics           | 3:1        | 3:1          |\n\n```css\n\u002F* ❌ Low contrast (2.5:1) *\u002F\n.low-contrast {\n  color: #999;\n  background: #fff;\n}\n\n\u002F* ✅ Sufficient contrast (7:1) *\u002F\n.high-contrast {\n  color: #333;\n  background: #fff;\n}\n\n\u002F* ✅ Focus states need contrast too (3:1 against background, WCAG 1.4.11) *\u002F\n:focus-visible {\n  outline: 2px solid currentColor;\n  outline-offset: 2px;\n}\n```\n\n**Don't rely on color alone:**\n\n```html\n\u003C!-- ❌ Only color indicates error -->\n\u003Cinput class=\"error-border\" \u002F>\n\u003Cstyle>\n  .error-border {\n    border-color: red;\n  }\n\u003C\u002Fstyle>\n\n\u003C!-- ✅ Color + icon + text -->\n\u003Cdiv class=\"field-error\">\n  \u003Cinput aria-invalid=\"true\" aria-describedby=\"email-error\" \u002F>\n  \u003Cspan id=\"email-error\" class=\"error-message\">\n    \u003Csvg aria-hidden=\"true\">\u003C!-- error icon -->\u003C\u002Fsvg>\n    Please enter a valid email address\n  \u003C\u002Fspan>\n\u003C\u002Fdiv>\n```\n\n### Media alternatives (1.2)\n\n```html\n\u003C!-- Video with captions -->\n\u003Cvideo controls>\n  \u003Csource src=\"video.mp4\" type=\"video\u002Fmp4\" \u002F>\n  \u003Ctrack\n    kind=\"captions\"\n    src=\"captions.vtt\"\n    srclang=\"en\"\n    label=\"English\"\n    default\n  \u002F>\n  \u003Ctrack\n    kind=\"descriptions\"\n    src=\"descriptions.vtt\"\n    srclang=\"en\"\n    label=\"Descriptions\"\n  \u002F>\n\u003C\u002Fvideo>\n\n\u003C!-- Audio with transcript -->\n\u003Caudio controls>\n  \u003Csource src=\"podcast.mp3\" type=\"audio\u002Fmp3\" \u002F>\n\u003C\u002Faudio>\n\u003Cdetails>\n  \u003Csummary>Transcript\u003C\u002Fsummary>\n  \u003Cp>Full transcript text...\u003C\u002Fp>\n\u003C\u002Fdetails>\n```\n\n---\n\n## Operable\n\n### Keyboard accessible (2.1)\n\n**All functionality must be keyboard accessible.** Prefer native interactive elements — `\u003Cbutton>`, `\u003Ca href>`, and form controls handle Enter\u002FSpace activation, focus, and assistive-tech semantics for free. Only add manual keyboard handling when you cannot use a native element.\n\n```html\n\u003C!-- ❌ Non-interactive element with click only: not focusable, no keyboard activation -->\n\u003Cdiv class=\"card\" onclick=\"handleAction()\">Open\u003C\u002Fdiv>\n\n\u003C!-- ✅ Best: use a native button -->\n\u003Cbutton type=\"button\" onclick=\"handleAction()\">Open\u003C\u002Fbutton>\n```\n\n```javascript\n\u002F\u002F ✅ When you MUST use a non-interactive element (e.g. div with role=\"button\"),\n\u002F\u002F make it focusable AND handle keyboard activation. Do NOT add this to a native\n\u002F\u002F \u003Cbutton> — Enter\u002FSpace already fire click, so you'd double-trigger.\nelement.setAttribute(\"role\", \"button\");\nelement.setAttribute(\"tabindex\", \"0\");\nelement.addEventListener(\"click\", handleAction);\nelement.addEventListener(\"keydown\", (e) => {\n  if (e.key === \"Enter\" || e.key === \" \") {\n    e.preventDefault();\n    handleAction();\n  }\n});\n```\n\n**No keyboard traps.** Users must be able to Tab into and out of every component. Use the [modal focus trap pattern](references\u002FA11Y-PATTERNS.md#modal-focus-trap) for dialogs—the native `\u003Cdialog>` element handles this automatically.\n\n### Focus visible (2.4.7)\n\n```css\n\u002F* ❌ Never remove focus outlines *\u002F\n*:focus {\n  outline: none;\n}\n\n\u002F* ✅ Use :focus-visible for keyboard-only focus *\u002F\n:focus {\n  outline: none;\n}\n\n:focus-visible {\n  outline: 2px solid currentColor; \u002F* inherits text color → already contrast-checked *\u002F\n  outline-offset: 2px;\n}\n\n\u002F* ✅ Or pick a brand color and verify ≥3:1 contrast against every background it lands on *\u002F\nbutton:focus-visible {\n  box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.5);\n}\n```\n\n### Focus not obscured (2.4.11) — new in 2.2\n\nWhen an element receives keyboard focus, it must not be entirely hidden by other author-created content such as sticky headers, footers, or overlapping panels. At Level AAA (2.4.12), no part of the focused element may be hidden.\n\n```css\n\u002F* ✅ Account for sticky headers when scrolling to focused elements *\u002F\n:target {\n  scroll-margin-top: 80px;\n}\n\n\u002F* ✅ Ensure focused items clear fixed\u002Fsticky bars *\u002F\n:focus {\n  scroll-margin-top: 80px;\n  scroll-margin-bottom: 60px;\n}\n```\n\n### Skip links (2.4.1)\n\nProvide a skip link so keyboard users can bypass repetitive navigation. See the [skip link pattern](references\u002FA11Y-PATTERNS.md#skip-link) for full markup and styles.\n\n### Target size (2.5.8) — new in 2.2\n\nInteractive targets must be at least **24 × 24 CSS pixels** (AA). Exceptions: inline text links, elements where the browser controls the size, and targets where a 24px circle centered on the bounding box does not overlap another target.\n\n```css\n\u002F* ✅ Minimum target size *\u002F\nbutton,\n[role=\"button\"],\ninput[type=\"checkbox\"] + label,\ninput[type=\"radio\"] + label {\n  min-width: 24px;\n  min-height: 24px;\n}\n\n\u002F* ✅ Comfortable target size (recommended 44×44) *\u002F\n.touch-target {\n  min-width: 44px;\n  min-height: 44px;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n}\n```\n\n### Dragging movements (2.5.7) — new in 2.2\n\nAny action that requires dragging must have a single-pointer alternative (e.g., buttons, inputs). See the [dragging movements pattern](references\u002FA11Y-PATTERNS.md#dragging-movements) for a sortable-list example.\n\n### Timing (2.2)\n\n```javascript\n\u002F\u002F Allow users to extend time limits\nfunction showSessionWarning() {\n  const modal = createModal({\n    title: \"Session Expiring\",\n    content: \"Your session will expire in 2 minutes.\",\n    actions: [\n      { label: \"Extend session\", action: extendSession },\n      { label: \"Log out\", action: logout },\n    ],\n    timeout: 120000,\n  });\n}\n```\n\n### Motion (2.3)\n\n```css\n\u002F* Respect reduced motion preference *\u002F\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n```\n\n---\n\n## Understandable\n\n### Page language (3.1.1)\n\n```html\n\u003C!-- ❌ No language specified -->\n\u003Chtml>\n  \u003C!-- ✅ Language specified -->\n  \u003Chtml lang=\"en\">\n    \u003C!-- ✅ Language changes within page -->\n    \u003Cp>The French word for hello is \u003Cspan lang=\"fr\">bonjour\u003C\u002Fspan>.\u003C\u002Fp>\n  \u003C\u002Fhtml>\n\u003C\u002Fhtml>\n```\n\n### Consistent navigation (3.2.3)\n\n```html\n\u003C!-- Navigation should be consistent across pages -->\n\u003Cnav aria-label=\"Main\">\n  \u003Cul>\n    \u003Cli>\u003Ca href=\"\u002F\" aria-current=\"page\">Home\u003C\u002Fa>\u003C\u002Fli>\n    \u003Cli>\u003Ca href=\"\u002Fproducts\">Products\u003C\u002Fa>\u003C\u002Fli>\n    \u003Cli>\u003Ca href=\"\u002Fabout\">About\u003C\u002Fa>\u003C\u002Fli>\n  \u003C\u002Ful>\n\u003C\u002Fnav>\n```\n\n### Consistent help (3.2.6) — new in 2.2\n\nIf a help mechanism (contact info, chat widget, FAQ link, self-help option) is repeated across multiple pages, it must appear in the **same relative order** each time. Users who rely on consistent placement shouldn't have to hunt for help on every page.\n\n### Form labels (3.3.2)\n\nEvery input needs a programmatically associated label. See the [form labels pattern](references\u002FA11Y-PATTERNS.md#form-labels) for explicit, implicit, and instructional examples.\n\n### Error handling (3.3.1, 3.3.3)\n\nAnnounce errors to screen readers with `role=\"alert\"` or `aria-live`, set `aria-invalid=\"true\"` on invalid fields, and focus the first error on submit. See the [error handling pattern](references\u002FA11Y-PATTERNS.md#error-handling) for full markup and JS.\n\n### Redundant entry (3.3.7) — new in 2.2\n\nDon't force users to re-enter information they already provided in the same session. Auto-populate from earlier steps, or let users select from previously entered values. Exceptions: security re-confirmation and content that has expired.\n\n```html\n\u003C!-- ✅ Auto-fill shipping address from billing -->\n\u003Cfieldset>\n  \u003Clegend>Shipping address\u003C\u002Flegend>\n  \u003Clabel>\n    \u003Cinput type=\"checkbox\" id=\"same-as-billing\" checked \u002F>\n    Same as billing address\n  \u003C\u002Flabel>\n  \u003C!-- Fields auto-populated when checked -->\n\u003C\u002Ffieldset>\n```\n\n### Accessible authentication (3.3.8) — new in 2.2\n\nLogin flows must not rely on cognitive function tests (e.g., remembering a password, solving a puzzle) unless at least one of:\n\n- A copy-paste or autofill mechanism is available\n- An alternative method exists (e.g., passkey, SSO, email link)\n- The test uses object recognition or personal content (AA only; AAA removes this exception)\n\n```html\n\u003C!-- ✅ Allow paste in password fields -->\n\u003Cinput type=\"password\" id=\"password\" autocomplete=\"current-password\" \u002F>\n\n\u003C!-- ✅ Offer passwordless alternatives -->\n\u003Cbutton type=\"button\">Sign in with passkey\u003C\u002Fbutton>\n\u003Cbutton type=\"button\">Email me a login link\u003C\u002Fbutton>\n```\n\n---\n\n## Robust\n\n### ARIA usage (4.1.2)\n\n**Prefer native elements:**\n\n```html\n\u003C!-- ❌ ARIA role on div -->\n\u003Cdiv role=\"button\" tabindex=\"0\">Click me\u003C\u002Fdiv>\n\n\u003C!-- ✅ Native button -->\n\u003Cbutton>Click me\u003C\u002Fbutton>\n\n\u003C!-- ❌ ARIA checkbox -->\n\u003Cdiv role=\"checkbox\" aria-checked=\"false\">Option\u003C\u002Fdiv>\n\n\u003C!-- ✅ Native checkbox -->\n\u003Clabel>\u003Cinput type=\"checkbox\" \u002F> Option\u003C\u002Flabel>\n```\n\n**When ARIA is needed,** use the correct roles and states. See the [ARIA tabs pattern](references\u002FA11Y-PATTERNS.md#aria-tabs) for a complete tablist example.\n\n### Live regions (4.1.3)\n\nUse `aria-live` regions to announce dynamic content changes without moving focus. See the [live regions pattern](references\u002FA11Y-PATTERNS.md#live-regions-and-notifications) for markup and a `showNotification()` helper.\n\n---\n\n## Testing checklist\n\n### Automated testing\n\nPrefer a live Lighthouse audit that returns failing rendered nodes directly to the agent. With Chrome DevTools MCP, this is `lighthouse_audit`. Otherwise:\n\n```bash\n# Lighthouse accessibility audit\nnpx lighthouse https:\u002F\u002Fexample.com --only-categories=accessibility\n\n# axe-core\nnpm install @axe-core\u002Fcli -g\naxe https:\u002F\u002Fexample.com\n```\n\n### Manual testing\n\n- [ ] **Keyboard navigation:** Tab through entire page, use Enter\u002FSpace to activate\n- [ ] **Screen reader:** Test with VoiceOver (Mac), NVDA (Windows), or TalkBack (Android)\n- [ ] **Zoom:** Content usable at 200% zoom\n- [ ] **High contrast:** Test with Windows High Contrast Mode\n- [ ] **Reduced motion:** Test with `prefers-reduced-motion: reduce`\n- [ ] **Focus order:** Logical and follows visual order\n- [ ] **Target size:** Interactive elements meet 24×24px minimum\n\nSee the [screen reader commands reference](references\u002FA11Y-PATTERNS.md#screen-reader-commands) for VoiceOver and NVDA shortcuts.\n\n---\n\n## Common issues by impact\n\n### Critical (fix immediately)\n\n1. Missing form labels\n2. Missing image alt text\n3. Insufficient color contrast\n4. Keyboard traps\n5. No focus indicators\n\n### Serious (fix before launch)\n\n1. Missing page language\n2. Missing heading structure\n3. Non-descriptive link text\n4. Auto-playing media\n5. Missing skip links\n\n### Moderate (fix soon)\n\n1. Missing ARIA labels on icons\n2. Inconsistent navigation\n3. Missing error identification\n4. Timing without controls\n5. Missing landmark regions\n\n## References\n\n- [WCAG 2.2 Quick Reference](https:\u002F\u002Fwww.w3.org\u002FWAI\u002FWCAG22\u002Fquickref\u002F)\n- [WAI-ARIA Authoring Practices](https:\u002F\u002Fwww.w3.org\u002FWAI\u002FARIA\u002Fapg\u002F)\n- [Deque axe Rules](https:\u002F\u002Fdequeuniversity.com\u002Frules\u002Faxe\u002F)\n- [Web Quality Audit](..\u002Fweb-quality-audit\u002FSKILL.md)\n- [WCAG criteria reference](references\u002FWCAG.md)\n- [Accessibility code patterns](references\u002FA11Y-PATTERNS.md)\n","# Accessibility (a11y)\n\nComprehensive accessibility guidelines based on WCAG 2.2 and Lighthouse accessibility audits. Goal: make content usable by everyone, including people with disabilities.\n\n## Evidence-led audit workflow\n\nWhen a rendered page is available:\n\n1. Run a live Lighthouse Accessibility audit when that capability is available; with Chrome DevTools MCP, use `lighthouse_audit`. Use mobile navigation mode for a general public page or snapshot mode when reloading would lose authenticated or user-created state.\n2. Use failed audit nodes to localize the relevant component or template instead of searching the whole repository for generic patterns.\n3. Inspect a rendered accessibility-tree snapshot for names, roles, states, landmarks, and heading structure; with Chrome DevTools MCP, use `take_snapshot`. Exercise the affected flow with the keyboard.\n4. Fix the source, then re-run the same audit and manual interaction.\n\nIf the live tools are unavailable, use Lighthouse CLI or axe for automated coverage and complete the same manual checks. Automated tools detect only a subset of accessibility barriers: a score of 100 is not WCAG conformance, and a low score does not replace issue-level evidence.\n\n## WCAG Principles: POUR\n\n| Principle          | Description                                       |\n| ------------------ | ------------------------------------------------- |\n| **P**erceivable    | Content can be perceived through different senses |\n| **O**perable       | Interface can be operated by all users            |\n| **U**nderstandable | Content and interface are understandable          |\n| **R**obust         | Content works with assistive technologies         |\n\n## Conformance levels\n\n| Level   | Requirement            | Target                                                |\n| ------- | ---------------------- | ----------------------------------------------------- |\n| **A**   | Minimum accessibility  | Must pass                                             |\n| **AA**  | Standard compliance    | Should pass (legal requirement in many jurisdictions) |\n| **AAA** | Enhanced accessibility | Nice to have                                          |\n\n---\n\n## Perceivable\n\n### Text alternatives (1.1)\n\n**Images require alt text:**\n\n```html\n\u003C!-- ❌ Missing alt -->\n\u003Cimg src=\"chart.png\" \u002F>\n\n\u003C!-- ✅ Descriptive alt -->\n\u003Cimg src=\"chart.png\" alt=\"Bar chart showing 40% increase in Q3 sales\" \u002F>\n\n\u003C!-- ✅ Decorative image (empty alt) -->\n\u003Cimg src=\"decorative-border.png\" alt=\"\" role=\"presentation\" \u002F>\n\n\u003C!-- ✅ Complex image with longer description -->\n\u003Cfigure>\n  \u003Cimg\n    src=\"infographic.png\"\n    alt=\"2024 market trends infographic\"\n    aria-describedby=\"infographic-desc\"\n  \u002F>\n  \u003Cfigcaption id=\"infographic-desc\">\n    \u003C!-- Detailed description -->\n  \u003C\u002Ffigcaption>\n\u003C\u002Ffigure>\n```\n\n**Icon buttons need accessible names:**\n\n```html\n\u003C!-- ❌ No accessible name -->\n\u003Cbutton>\n  \u003Csvg>\u003C!-- menu icon -->\u003C\u002Fsvg>\n\u003C\u002Fbutton>\n\n\u003C!-- ✅ Using aria-label -->\n\u003Cbutton aria-label=\"Open menu\">\n  \u003Csvg aria-hidden=\"true\">\u003C!-- menu icon -->\u003C\u002Fsvg>\n\u003C\u002Fbutton>\n\n\u003C!-- ✅ Using visually hidden text -->\n\u003Cbutton>\n  \u003Csvg aria-hidden=\"true\">\u003C!-- menu icon -->\u003C\u002Fsvg>\n  \u003Cspan class=\"visually-hidden\">Open menu\u003C\u002Fspan>\n\u003C\u002Fbutton>\n```\n\n**Visually hidden class:**\n\n```css\n.visually-hidden {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  white-space: nowrap;\n  border: 0;\n}\n```\n\n### Color contrast (1.4.3, 1.4.6)\n\n| Text Size                          | AA minimum | AAA enhanced |\n| ---------------------------------- | ---------- | ------------ |\n| Normal text (\u003C 18px \u002F \u003C 14px bold) | 4.5:1      | 7:1          |\n| Large text (≥ 18px \u002F ≥ 14px bold)  | 3:1        | 4.5:1        |\n| UI components & graphics           | 3:1        | 3:1          |\n\n```css\n\u002F* ❌ Low contrast (2.5:1) *\u002F\n.low-contrast {\n  color: #999;\n  background: #fff;\n}\n\n\u002F* ✅ Sufficient contrast (7:1) *\u002F\n.high-contrast {\n  color: #333;\n  background: #fff;\n}\n\n\u002F* ✅ Focus states need contrast too (3:1 against background, WCAG 1.4.11) *\u002F\n:focus-visible {\n  outline: 2px solid currentColor;\n  outline-offset: 2px;\n}\n```\n\n**Don't rely on color alone:**\n\n```html\n\u003C!-- ❌ Only color indicates error -->\n\u003Cinput class=\"error-border\" \u002F>\n\u003Cstyle>\n  .error-border {\n    border-color: red;\n  }\n\u003C\u002Fstyle>\n\n\u003C!-- ✅ Color + icon + text -->\n\u003Cdiv class=\"field-error\">\n  \u003Cinput aria-invalid=\"true\" aria-describedby=\"email-error\" \u002F>\n  \u003Cspan id=\"email-error\" class=\"error-message\">\n    \u003Csvg aria-hidden=\"true\">\u003C!-- error icon -->\u003C\u002Fsvg>\n    Please enter a valid email address\n  \u003C\u002Fspan>\n\u003C\u002Fdiv>\n```\n\n### Media alternatives (1.2)\n\n```html\n\u003C!-- Video with captions -->\n\u003Cvideo controls>\n  \u003Csource src=\"video.mp4\" type=\"video\u002Fmp4\" \u002F>\n  \u003Ctrack\n    kind=\"captions\"\n    src=\"captions.vtt\"\n    srclang=\"en\"\n    label=\"English\"\n    default\n  \u002F>\n  \u003Ctrack\n    kind=\"descriptions\"\n    src=\"descriptions.vtt\"\n    srclang=\"en\"\n    label=\"Descriptions\"\n  \u002F>\n\u003C\u002Fvideo>\n\n\u003C!-- Audio with transcript -->\n\u003Caudio controls>\n  \u003Csource src=\"podcast.mp3\" type=\"audio\u002Fmp3\" \u002F>\n\u003C\u002Faudio>\n\u003Cdetails>\n  \u003Csummary>Transcript\u003C\u002Fsummary>\n  \u003Cp>Full transcript text...\u003C\u002Fp>\n\u003C\u002Fdetails>\n```\n\n---\n\n## Operable\n\n### Keyboard accessible (2.1)\n\n**All functionality must be keyboard accessible.** Prefer native interactive elements — `\u003Cbutton>`, `\u003Ca href>`, and form controls handle Enter\u002FSpace activation, focus, and assistive-tech semantics for free. Only add manual keyboard handling when you cannot use a native element.\n\n```html\n\u003C!-- ❌ Non-interactive element with click only: not focusable, no keyboard activation -->\n\u003Cdiv class=\"card\" onclick=\"handleAction()\">Open\u003C\u002Fdiv>\n\n\u003C!-- ✅ Best: use a native button -->\n\u003Cbutton type=\"button\" onclick=\"handleAction()\">Open\u003C\u002Fbutton>\n```\n\n```javascript\n\u002F\u002F ✅ When you MUST use a non-interactive element (e.g. div with role=\"button\"),\n\u002F\u002F make it focusable AND handle keyboard activation. Do NOT add this to a native\n\u002F\u002F \u003Cbutton> — Enter\u002FSpace already fire click, so you'd double-trigger.\nelement.setAttribute(\"role\", \"button\");\nelement.setAttribute(\"tabindex\", \"0\");\nelement.addEventListener(\"click\", handleAction);\nelement.addEventListener(\"keydown\", (e) => {\n  if (e.key === \"Enter\" || e.key === \" \") {\n    e.preventDefault();\n    handleAction();\n  }\n});\n```\n\n**No keyboard traps.** Users must be able to Tab into and out of every component. Use the [modal focus trap pattern](references\u002FA11Y-PATTERNS.md#modal-focus-trap) for dialogs—the native `\u003Cdialog>` element handles this automatically.\n\n### Focus visible (2.4.7)\n\n```css\n\u002F* ❌ Never remove focus outlines *\u002F\n*:focus {\n  outline: none;\n}\n\n\u002F* ✅ Use :focus-visible for keyboard-only focus *\u002F\n:focus {\n  outline: none;\n}\n\n:focus-visible {\n  outline: 2px solid currentColor; \u002F* inherits text color → already contrast-checked *\u002F\n  outline-offset: 2px;\n}\n\n\u002F* ✅ Or pick a brand color and verify ≥3:1 contrast against every background it lands on *\u002F\nbutton:focus-visible {\n  box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.5);\n}\n```\n\n### Focus not obscured (2.4.11) — new in 2.2\n\nWhen an element receives keyboard focus, it must not be entirely hidden by other author-created content such as sticky headers, footers, or overlapping panels. At Level AAA (2.4.12), no part of the focused element may be hidden.\n\n```css\n\u002F* ✅ Account for sticky headers when scrolling to focused elements *\u002F\n:target {\n  scroll-margin-top: 80px;\n}\n\n\u002F* ✅ Ensure focused items clear fixed\u002Fsticky bars *\u002F\n:focus {\n  scroll-margin-top: 80px;\n  scroll-margin-bottom: 60px;\n}\n```\n\n### Skip links (2.4.1)\n\nProvide a skip link so keyboard users can bypass repetitive navigation. See the [skip link pattern](references\u002FA11Y-PATTERNS.md#skip-link) for full markup and styles.\n\n### Target size (2.5.8) — new in 2.2\n\nInteractive targets must be at least **24 × 24 CSS pixels** (AA). Exceptions: inline text links, elements where the browser controls the size, and targets where a 24px circle centered on the bounding box does not overlap another target.\n\n```css\n\u002F* ✅ Minimum target size *\u002F\nbutton,\n[role=\"button\"],\ninput[type=\"checkbox\"] + label,\ninput[type=\"radio\"] + label {\n  min-width: 24px;\n  min-height: 24px;\n}\n\n\u002F* ✅ Comfortable target size (recommended 44×44) *\u002F\n.touch-target {\n  min-width: 44px;\n  min-height: 44px;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n}\n```\n\n### Dragging movements (2.5.7) — new in 2.2\n\nAny action that requires dragging must have a single-pointer alternative (e.g., buttons, inputs). See the [dragging movements pattern](references\u002FA11Y-PATTERNS.md#dragging-movements) for a sortable-list example.\n\n### Timing (2.2)\n\n```javascript\n\u002F\u002F Allow users to extend time limits\nfunction showSessionWarning() {\n  const modal = createModal({\n    title: \"Session Expiring\",\n    content: \"Your session will expire in 2 minutes.\",\n    actions: [\n      { label: \"Extend session\", action: extendSession },\n      { label: \"Log out\", action: logout },\n    ],\n    timeout: 120000,\n  });\n}\n```\n\n### Motion (2.3)\n\n```css\n\u002F* Respect reduced motion preference *\u002F\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n```\n\n---\n\n## Understandable\n\n### Page language (3.1.1)\n\n```html\n\u003C!-- ❌ No language specified -->\n\u003Chtml>\n  \u003C!-- ✅ Language specified -->\n  \u003Chtml lang=\"en\">\n    \u003C!-- ✅ Language changes within page -->\n    \u003Cp>The French word for hello is \u003Cspan lang=\"fr\">bonjour\u003C\u002Fspan>.\u003C\u002Fp>\n  \u003C\u002Fhtml>\n\u003C\u002Fhtml>\n```\n\n### Consistent navigation (3.2.3)\n\n```html\n\u003C!-- Navigation should be consistent across pages -->\n\u003Cnav aria-label=\"Main\">\n  \u003Cul>\n    \u003Cli>\u003Ca href=\"\u002F\" aria-current=\"page\">Home\u003C\u002Fa>\u003C\u002Fli>\n    \u003Cli>\u003Ca href=\"\u002Fproducts\">Products\u003C\u002Fa>\u003C\u002Fli>\n    \u003Cli>\u003Ca href=\"\u002Fabout\">About\u003C\u002Fa>\u003C\u002Fli>\n  \u003C\u002Ful>\n\u003C\u002Fnav>\n```\n\n### Consistent help (3.2.6) — new in 2.2\n\nIf a help mechanism (contact info, chat widget, FAQ link, self-help option) is repeated across multiple pages, it must appear in the **same relative order** each time. Users who rely on consistent placement shouldn't have to hunt for help on every page.\n\n### Form labels (3.3.2)\n\nEvery input needs a programmatically associated label. See the [form labels pattern](references\u002FA11Y-PATTERNS.md#form-labels) for explicit, implicit, and instructional examples.\n\n### Error handling (3.3.1, 3.3.3)\n\nAnnounce errors to screen readers with `role=\"alert\"` or `aria-live`, set `aria-invalid=\"true\"` on invalid fields, and focus the first error on submit. See the [error handling pattern](references\u002FA11Y-PATTERNS.md#error-handling) for full markup and JS.\n\n### Redundant entry (3.3.7) — new in 2.2\n\nDon't force users to re-enter information they already provided in the same session. Auto-populate from earlier steps, or let users select from previously entered values. Exceptions: security re-confirmation and content that has expired.\n\n```html\n\u003C!-- ✅ Auto-fill shipping address from billing -->\n\u003Cfieldset>\n  \u003Clegend>Shipping address\u003C\u002Flegend>\n  \u003Clabel>\n    \u003Cinput type=\"checkbox\" id=\"same-as-billing\" checked \u002F>\n    Same as billing address\n  \u003C\u002Flabel>\n  \u003C!-- Fields auto-populated when checked -->\n\u003C\u002Ffieldset>\n```\n\n### Accessible authentication (3.3.8) — new in 2.2\n\nLogin flows must not rely on cognitive function tests (e.g., remembering a password, solving a puzzle) unless at least one of:\n\n- A copy-paste or autofill mechanism is available\n- An alternative method exists (e.g., passkey, SSO, email link)\n- The test uses object recognition or personal content (AA only; AAA removes this exception)\n\n```html\n\u003C!-- ✅ Allow paste in password fields -->\n\u003Cinput type=\"password\" id=\"password\" autocomplete=\"current-password\" \u002F>\n\n\u003C!-- ✅ Offer passwordless alternatives -->\n\u003Cbutton type=\"button\">Sign in with passkey\u003C\u002Fbutton>\n\u003Cbutton type=\"button\">Email me a login link\u003C\u002Fbutton>\n```\n\n---\n\n## Robust\n\n### ARIA usage (4.1.2)\n\n**Prefer native elements:**\n\n```html\n\u003C!-- ❌ ARIA role on div -->\n\u003Cdiv role=\"button\" tabindex=\"0\">Click me\u003C\u002Fdiv>\n\n\u003C!-- ✅ Native button -->\n\u003Cbutton>Click me\u003C\u002Fbutton>\n\n\u003C!-- ❌ ARIA checkbox -->\n\u003Cdiv role=\"checkbox\" aria-checked=\"false\">Option\u003C\u002Fdiv>\n\n\u003C!-- ✅ Native checkbox -->\n\u003Clabel>\u003Cinput type=\"checkbox\" \u002F> Option\u003C\u002Flabel>\n```\n\n**When ARIA is needed,** use the correct roles and states. See the [ARIA tabs pattern](references\u002FA11Y-PATTERNS.md#aria-tabs) for a complete tablist example.\n\n### Live regions (4.1.3)\n\nUse `aria-live` regions to announce dynamic content changes without moving focus. See the [live regions pattern](references\u002FA11Y-PATTERNS.md#live-regions-and-notifications) for markup and a `showNotification()` helper.\n\n---\n\n## Testing checklist\n\n### Automated testing\n\nPrefer a live Lighthouse audit that returns failing rendered nodes directly to the agent. With Chrome DevTools MCP, this is `lighthouse_audit`. Otherwise:\n\n```bash\n# Lighthouse accessibility audit\nnpx lighthouse https:\u002F\u002Fexample.com --only-categories=accessibility\n\n# axe-core\nnpm install @axe-core\u002Fcli -g\naxe https:\u002F\u002Fexample.com\n```\n\n### Manual testing\n\n- [ ] **Keyboard navigation:** Tab through entire page, use Enter\u002FSpace to activate\n- [ ] **Screen reader:** Test with VoiceOver (Mac), NVDA (Windows), or TalkBack (Android)\n- [ ] **Zoom:** Content usable at 200% zoom\n- [ ] **High contrast:** Test with Windows High Contrast Mode\n- [ ] **Reduced motion:** Test with `prefers-reduced-motion: reduce`\n- [ ] **Focus order:** Logical and follows visual order\n- [ ] **Target size:** Interactive elements meet 24×24px minimum\n\nSee the [screen reader commands reference](references\u002FA11Y-PATTERNS.md#screen-reader-commands) for VoiceOver and NVDA shortcuts.\n\n---\n\n## Common issues by impact\n\n### Critical (fix immediately)\n\n1. Missing form labels\n2. Missing image alt text\n3. Insufficient color contrast\n4. Keyboard traps\n5. No focus indicators\n\n### Serious (fix before launch)\n\n1. Missing page language\n2. Missing heading structure\n3. Non-descriptive link text\n4. Auto-playing media\n5. Missing skip links\n\n### Moderate (fix soon)\n\n1. Missing ARIA labels on icons\n2. Inconsistent navigation\n3. Missing error identification\n4. Timing without controls\n5. Missing landmark regions\n\n## References\n\n- [WCAG 2.2 Quick Reference](https:\u002F\u002Fwww.w3.org\u002FWAI\u002FWCAG22\u002Fquickref\u002F)\n- [WAI-ARIA Authoring Practices](https:\u002F\u002Fwww.w3.org\u002FWAI\u002FARIA\u002Fapg\u002F)\n- [Deque axe Rules](https:\u002F\u002Fdequeuniversity.com\u002Frules\u002Faxe\u002F)\n- [Web Quality Audit](..\u002Fweb-quality-audit\u002FSKILL.md)\n- [WCAG criteria reference](references\u002FWCAG.md)\n- [Accessibility code patterns](references\u002FA11Y-PATTERNS.md)\n",{"name":5,"license":15,"metadata":43,"description":7},{"author":44,"version":45},"web-quality-skills","2.0","main","57541c0eee379b047ef924f47432ce8ffa5130e8","skills\u002Fdefault\u002Fweb-accessibility","https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills","https:\u002F\u002Fgithub.com\u002Fjapurcell","2026-11-11 08:59:34",{"source":8,"skillName":5,"commands":53,"prompt":63,"zipAvailable":64},[54,57,60],{"tool":55,"command":56},"npx","npx skills add japurcell\u002Fskills --skill web-accessibility",{"tool":58,"command":59},"bunx","bunx skills add japurcell\u002Fskills --skill web-accessibility",{"tool":61,"command":62},"pnpm","pnpm dlx skills add japurcell\u002Fskills --skill web-accessibility","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fdefault\u002Fweb-accessibility\u002FSKILL.md",true,[66,72],{"path":67,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":70,"sourceHtmlUrl":71},"references\u002FA11Y-PATTERNS.md","REFERENCE","参考文档",6036,"https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fdefault\u002Fweb-accessibility\u002Freferences\u002FA11Y-PATTERNS.md",{"path":73,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":74,"sourceHtmlUrl":75},"references\u002FWCAG.md",9079,"https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fdefault\u002Fweb-accessibility\u002Freferences\u002FWCAG.md",[77,107,129,157,179,200],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":88,"publishedAt":38},"01M6PT0ZTYCN4DHK3SXWS79WSY","spec-create","Create or revise a portable behavioral SPEC for a feature or whole product. Use when specifying a new idea, documenting an existing system for reimplementation, or defining a change while preserving compatibility. Implementation planning is a separate task.","https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fdefault\u002Fspec-create\u002FSKILL.md",[83],{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000031","产品经理","PROFESSION","适用职业",[89,90,91,92,93,94,95,29,96,97,98,99,100,101,102,103,104,105,106],"create","spec","spec create","feature","planning","for","system","Existing","task","output","change","product","implementation","revise","compatibility","behavioral","idea","path",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":114,"publishedAt":38},"01M6GSVHQ4MY4R4SMS8RY6324Q","prd-ralph","Complete at most one eligible unfinished PRD task, verify it, log progress, and optionally create one scoped commit.","https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fdefault\u002Fprd-ralph\u002FSKILL.md",[113],{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},[115,116,117,89,118,119,120,121,122,123,97,124,125,126,127,128,106],"prd ralph","ralph","prd","progress","verify","at","complete","commit","it","log","scoped","false","file","id",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":133,"categories":134,"keywords":138,"publishedAt":38},"01M6GSYMGHE2FEGEFKD926EJH8","fsdp-style-guide","Mandatory for all UI\u002FUX design, implementation, review, audit, or visual regression tasks. Always use for any work that affects user-facing appearance, behavior, accessibility, branding, layout, navigation, forms, dialogs, alerts, tables, or visual design.","https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fforest-service\u002Ffsdp-style-guide\u002FSKILL.md",[135],{"categoryNo":136,"categoryName":137,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000032","设计师",[139,140,141,142,143,144,145,146,29,147,148,149,150,151,152,153,154,36,155,156,94],"fsdp style guide","style guide","FSDP","style","guide","visual regression","regression","design","visual","tasks","review","visual design","alerts","work","branding","layout","ux","behavior",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":163,"publishedAt":38},"01M6GSYHEQARNM7WN0RJA7K7T2","agency-priorities","Provide self-contained USDA strategic goals and Forest Service priorities for agency briefings, proposals, and work-plan alignment. Use when explaining agency direction or evaluating how a project contributes to USDA and Forest Service priorities.","https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fforest-service\u002Fagency-priorities\u002FSKILL.md",[],[164,165,166,167,168,152,169,170,171,172,173,174,175,176,29,94,22,177,178],"agency priorities","priorities","agency","self","alignment","plan","goals","proposals","direction","how","project","strategic","service","briefings","self-contained",{"skillNo":180,"name":181,"nameZh":6,"description":182,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":183,"categories":184,"keywords":188,"publishedAt":38},"01M6GSY9VVN8RSJ5QYM540ZJ1D","accomplishment-report","Create a concise Forest Service executive accomplishment report when all work in an ExecPlan is completed, or update its existing report. Use at ExecPlan closeout and when asked to report completed work, agency alignment, and estimated AI-assisted versus human-only time and cost savings.","https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fforest-service\u002Faccomplishment-report\u002FSKILL.md",[185],{"categoryNo":186,"categoryName":187,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000034","行政与办公人员",[189,190,168,191,89,152,192,193,194,195,120,166,196,176,29,197,198,199,96,22],"report","accomplishment report","cost","concise","human","time","update","only","closeout","savings","execplan",{"skillNo":201,"name":202,"nameZh":6,"description":203,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":204,"categories":205,"keywords":214,"publishedAt":38},"01M6GSY7J8ZMCE319P8Y6JZ432","writing-for-agents","Writing documents for agents. Use when creating or editing skills, or modifying AGENTS.md or CLAUDE.md.","https:\u002F\u002Fgithub.com\u002Fjapurcell\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fdefault\u002Fwriting-for-agents\u002FSKILL.md",[206,211],{"categoryNo":207,"categoryName":208,"taxonomyType":209,"taxonomyTypeDesc":210},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",{"categoryNo":212,"categoryName":213,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000036","内容创作者",[215,216,94,29,217,218,22],"writing","writing for agents","documents","editing"]