diff --git a/docs/AccessibilityGuide.md b/docs/AccessibilityGuide.md
new file mode 100644
index 00000000..5a2c4ac8
--- /dev/null
+++ b/docs/AccessibilityGuide.md
@@ -0,0 +1,353 @@
+# Accessibility Guide
+
+DocuElevate targets **WCAG 2.1 Level AA** compliance across all user-facing pages. This guide documents the accessibility standards, patterns, and practices used in the project.
+
+## Table of Contents
+
+- [Standards Overview](#standards-overview)
+- [ARIA Patterns Used](#aria-patterns-used)
+- [Keyboard Navigation](#keyboard-navigation)
+- [Color and Contrast](#color-and-contrast)
+- [Forms and Inputs](#forms-and-inputs)
+- [Tables](#tables)
+- [Modals and Dialogs](#modals-and-dialogs)
+- [Dynamic Content](#dynamic-content)
+- [Images and Icons](#images-and-icons)
+- [Testing and Validation](#testing-and-validation)
+- [Developer Checklist](#developer-checklist)
+
+## Standards Overview
+
+DocuElevate follows [WCAG 2.1 Level AA](https://www.w3.org/WAI/WCAG21/quickref/?currentsidebar=%23col_overview&levels=aaa) guidelines. The key principles are:
+
+| Principle | Description |
+|-----------|-------------|
+| **Perceivable** | Information and UI components must be presentable in ways all users can perceive |
+| **Operable** | UI components and navigation must be operable via keyboard and assistive technologies |
+| **Understandable** | Information and UI operation must be understandable |
+| **Robust** | Content must be robust enough for a wide variety of user agents and assistive technologies |
+
+## ARIA Patterns Used
+
+### Landmarks
+
+`base.html` provides the following landmark structure on every page:
+
+```html
+Skip to main content
+
+{% block content %}{% endblock %}
+
+```
+
+### Navigation
+
+- Active page links use `aria-current="page"`
+- The admin dropdown uses `aria-haspopup="true"`, `aria-expanded`, `role="menu"`, and `role="menuitem"`
+- The mobile menu toggle has `aria-label="Toggle navigation menu"` and `aria-expanded`
+
+### Decorative Icons
+
+Font Awesome icons that appear next to descriptive text must have `aria-hidden="true"`:
+
+```html
+
+
+ Settings
+
+
+
+
+```
+
+## Keyboard Navigation
+
+### Skip Link
+
+Every page inherits a skip-to-content link from `base.html` that becomes visible on keyboard focus:
+
+```css
+.skip-link:focus {
+ position: fixed;
+ top: 0;
+ left: 0;
+ /* ... visible styles ... */
+}
+```
+
+### Focus Indicators
+
+Global `focus-visible` styles are defined in `frontend/static/styles.css`:
+
+```css
+a:focus-visible,
+button:focus-visible,
+input:focus-visible,
+select:focus-visible,
+textarea:focus-visible,
+[tabindex]:focus-visible {
+ outline: 2px solid #2563eb;
+ outline-offset: 2px;
+}
+```
+
+> **Warning:** Never remove or suppress focus indicators with `outline: none` unless you provide an equally visible alternative.
+
+### Interactive Custom Elements
+
+When using `
` or `` as interactive elements (avoid when possible), ensure:
+
+```html
+
+```
+
+## Color and Contrast
+
+### Minimum Ratios (WCAG 1.4.3)
+
+| Text Type | Minimum Contrast Ratio |
+|-----------|----------------------|
+| Normal text (< 18pt) | 4.5:1 |
+| Large text (≥ 18pt or ≥ 14pt bold) | 3:1 |
+| UI components and graphical objects | 3:1 |
+
+### Dark Mode
+
+Dark mode overrides in `styles.css` are verified for WCAG AA contrast ratios. When adding new color values:
+
+1. Verify light mode contrast at [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
+2. Verify dark mode contrast for the corresponding dark override
+3. Never rely on color alone — always pair with text, icons, or patterns
+
+### Status Badges
+
+Status indicators use both color **and** text:
+
+```html
+Completed
+Failed
+```
+
+## Forms and Inputs
+
+### Labels (WCAG 1.3.1, 3.3.2)
+
+Every form input **must** have an associated label:
+
+```html
+
+
+
+
+
+
+```
+
+### Error Messages (WCAG 3.3.1)
+
+Error messages must be announced to screen readers:
+
+```html
+
+
{{ error_message }}
+
+```
+
+### Search Forms
+
+Use `role="search"` and proper labelling:
+
+```html
+
+```
+
+### Focus Management
+
+When opening a modal:
+1. Move focus into the dialog (first focusable element or the dialog itself)
+2. Trap focus within the dialog while open
+3. Return focus to the trigger element when closed
+
+## Dynamic Content
+
+### Live Regions (WCAG 4.1.3)
+
+Content that updates dynamically must be announced to screen readers:
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+| Attribute | Use When |
+|-----------|----------|
+| `aria-live="polite"` | Updates that don't require immediate attention (search results, progress) |
+| `aria-live="assertive"` | Critical updates that require immediate attention (errors) |
+| `role="status"` | Status information (equivalent to `aria-live="polite"`) |
+| `role="alert"` | Important messages that require immediate attention |
+
+## Images and Icons
+
+### Content Images
+
+```html
+
+```
+
+### Decorative Images
+
+```html
+
+```
+
+### Icon-Only Buttons
+
+```html
+
+```
+
+### Icons with Adjacent Text
+
+```html
+
+ Upload
+
+```
+
+## Testing and Validation
+
+### Automated Checks (CI Pipeline)
+
+The CI pipeline runs `djlint` on every pull request:
+
+```bash
+# Run locally before committing
+djlint frontend/templates/ --lint
+```
+
+Configuration is in `pyproject.toml` under `[tool.djlint]`. The linter enforces:
+
+| Rule | Description |
+|------|-------------|
+| H005 | `` tag must have `lang` attribute |
+| H013 | `` tag must have `alt` attribute |
+| H016 | Document must have `` tag |
+| H025 | Tag should not be an orphan |
+| H026 | Empty `id` and `class` attributes should be removed |
+
+### Manual Testing
+
+For each new feature or UI change, verify:
+
+1. **Keyboard navigation**: Tab through all interactive elements; confirm logical focus order
+2. **Screen reader**: Test with a screen reader (VoiceOver on macOS, NVDA on Windows, Orca on Linux)
+3. **Color contrast**: Check new color combinations with [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
+4. **Zoom**: Test at 200% zoom; ensure content remains usable
+5. **Responsive**: Test at mobile viewport widths (320px, 375px)
+
+### Browser Testing Tools
+
+- **Chrome DevTools Accessibility panel** — audit ARIA attributes and contrast
+- **axe DevTools** browser extension — automated WCAG scanning
+- **Lighthouse** — includes accessibility audit in Performance tab
+
+## Developer Checklist
+
+Use this checklist when creating or modifying UI templates:
+
+- [ ] All images have appropriate `alt` attributes
+- [ ] All decorative icons have `aria-hidden="true"`
+- [ ] All icon-only buttons have `aria-label`
+- [ ] All form inputs have associated labels (via `for`/`id` or `aria-label`)
+- [ ] All tables have `aria-label` or `
` and `scope` on headers
+- [ ] All modals have `role="dialog"`, `aria-modal="true"`, and `aria-labelledby`
+- [ ] Dynamic content areas have `aria-live="polite"` or appropriate role
+- [ ] Color contrast meets 4.5:1 for normal text, 3:1 for large text
+- [ ] All interactive elements are keyboard-accessible
+- [ ] Focus indicators are visible on all interactive elements
+- [ ] `djlint frontend/templates/ --lint` passes with zero errors
+- [ ] Page heading hierarchy is correct (h1 → h2 → h3, no skipped levels)