Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
f6ec57c
remove legacy critical and icon assets references
LucaArgentieri Mar 4, 2026
2a7c8bb
pre-core setup
LucaArgentieri Mar 4, 2026
5e9d31b
updated readme
LucaArgentieri Mar 4, 2026
5aefb54
typecheck workflow + todo
LucaArgentieri Mar 4, 2026
b655d11
chore: update bun lockfile
LucaArgentieri Mar 4, 2026
70208a1
mark repository hygiene checklist complete
LucaArgentieri Mar 4, 2026
d6b6fbe
chore: remove cla workflow
LucaArgentieri Mar 4, 2026
c523ece
Complete repository hygiene checklist (#1)
LucaArgentieri Mar 4, 2026
0815a03
Staging (#2)
LucaArgentieri Mar 4, 2026
1c046a6
close quality and dev workflow checklist
LucaArgentieri Mar 4, 2026
305fe03
Close quality and dev workflow checklist (#3)
LucaArgentieri Mar 4, 2026
57aa36a
todo setup
LucaArgentieri Mar 19, 2026
be78d5b
align starter with docs-first cart/search patterns and AI contributor…
LucaArgentieri Mar 23, 2026
505fcb4
add cart note attributes and refactor search results rendering
LucaArgentieri Mar 23, 2026
c78b12f
stabilize pdp media ordering and decouple recommendations from varian…
LucaArgentieri Mar 23, 2026
85a54cd
add reusable product-card quick buy and cart update events
LucaArgentieri Mar 23, 2026
98450d2
upgrade to vite 8
LucaArgentieri Mar 23, 2026
3a91aea
Core rollout: PDP, Cart/Drawer, PLP, Search (#4)
LucaArgentieri Mar 23, 2026
ed9da9d
Staging (#5)
LucaArgentieri Mar 23, 2026
843abc1
feat: added new skills
LucaArgentieri Jul 22, 2026
ff1c3d8
build
LucaArgentieri Jul 22, 2026
b155e7e
feat: added new skills (#6)
LucaArgentieri Jul 22, 2026
7dd9c78
Add predictive search, consolidate agent docs into AGENTS.md, rebuild…
LucaArgentieri Jul 22, 2026
849d58b
Merge branch 'staging' into feat/add-new-skills
LucaArgentieri Jul 22, 2026
0937a95
Add mobile PLP filter drawer, localize collection copy, fix theme-che…
LucaArgentieri Jul 22, 2026
93c2f17
Extract shared dialog focus-trap utility
LucaArgentieri Jul 22, 2026
fdee705
Remove todo.md
LucaArgentieri Jul 22, 2026
2632067
PDP: stop reordering thumbnails on variant/photo change
LucaArgentieri Jul 22, 2026
892e25e
PDP: scrollable media column at lg + click-to-scroll thumbnails
LucaArgentieri Jul 22, 2026
f51cd6f
build
LucaArgentieri Jul 22, 2026
16abe74
Merge remote-tracking branch 'origin/feat/add-new-skills'
LucaArgentieri Jul 22, 2026
dd1e2e1
Bump tailwindcss/vite/rolldown dependencies, rebuild assets
LucaArgentieri Jul 22, 2026
59df079
Add predictive search, consolidate agent docs, rebuild assets (#7)
LucaArgentieri Jul 22, 2026
9eb040d
Add Renovate config for dependency updates
LucaArgentieri Aug 6, 2026
2cc8dfe
Add Renovate config for dependency updates (#8)
LucaArgentieri Aug 6, 2026
4726b09
Staging (#9)
LucaArgentieri Aug 6, 2026
7b2252e
updating skills, depencencies, vite plugin
LucaArgentieri Sep 17, 2026
0d577df
feat: seo-audit skill + accessibility
LucaArgentieri Sep 23, 2026
560cedf
feat: removed shopify-development -> installed new shopify skills
LucaArgentieri Sep 28, 2026
b094d47
feat: fixed multi-variant
LucaArgentieri Sep 28, 2026
e12eb68
feat: adopt native <dialog>, DOM morph, Standard Actions/Events, and …
LucaArgentieri Sep 29, 2026
c72ec92
codify liquidoc + skiull chaining
LucaArgentieri Sep 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
464 changes: 464 additions & 0 deletions .agents/skills/accessibility/SKILL.md

Large diffs are not rendered by default.

233 changes: 233 additions & 0 deletions .agents/skills/accessibility/references/A11Y-PATTERNS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
# Accessibility Code Patterns

Practical, copy-paste-ready patterns for common accessibility requirements. Each pattern is self-contained and linked from the main [SKILL.md](../SKILL.md).

---

## Modal focus trap

Trap keyboard focus inside a modal dialog so Tab/Shift+Tab cycle through its focusable elements and Escape closes it.

```javascript
function openModal(modal) {
const focusableElements = modal.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];

modal.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === firstElement) {
e.preventDefault();
lastElement.focus();
} else if (!e.shiftKey && document.activeElement === lastElement) {
e.preventDefault();
firstElement.focus();
}
}
if (e.key === 'Escape') {
closeModal();
}
});

firstElement.focus();
}
```

The native `<dialog>` element handles focus trapping automatically—prefer it when browser support allows.

---

## Skip link

Allows keyboard users to bypass repetitive navigation and jump straight to main content.

```html
<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<header><!-- navigation --></header>
<main id="main-content" tabindex="-1">
<!-- main content -->
</main>
</body>
```

```css
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px 16px;
z-index: 100;
}

.skip-link:focus {
top: 0;
}
```

---

## Error handling

Announce errors to screen readers and focus the first invalid field on submit.

```html
<form novalidate>
<div class="field" aria-live="polite">
<label for="email">Email</label>
<input type="email" id="email"
aria-invalid="true"
aria-describedby="email-error">
<p id="email-error" class="error" role="alert">
Please enter a valid email address (e.g., name@example.com)
</p>
</div>
</form>
```

```javascript
form.addEventListener('submit', (e) => {
const firstError = form.querySelector('[aria-invalid="true"]');
if (firstError) {
e.preventDefault();
firstError.focus();

const errorSummary = document.getElementById('error-summary');
errorSummary.textContent =
`${errors.length} errors found. Please fix them and try again.`;
errorSummary.focus();
}
});
```

---

## Form labels

Every input needs an associated label—either explicit (`for`/`id`) or implicit (wrapping `<label>`).

```html
<!-- ❌ No label association -->
<input type="email" placeholder="Email">

<!-- ✅ Explicit label -->
<label for="email">Email address</label>
<input type="email" id="email" name="email"
autocomplete="email" required>

<!-- ✅ Implicit label -->
<label>
Email address
<input type="email" name="email" autocomplete="email" required>
</label>

<!-- ✅ With instructions -->
<label for="password">Password</label>
<input type="password" id="password"
aria-describedby="password-requirements">
<p id="password-requirements">
Must be at least 8 characters with one number.
</p>
```

---

## Dragging movements

Any action triggered by dragging must offer a single-pointer alternative (WCAG 2.5.7).

```html
<!-- ❌ Drag-only reorder -->
<ul class="sortable-list" draggable="true">
<li>Item 1</li>
<li>Item 2</li>
</ul>

<!-- ✅ Drag + button alternatives -->
<ul class="sortable-list">
<li>
<span>Item 1</span>
<button aria-label="Move Item 1 up">↑</button>
<button aria-label="Move Item 1 down">↓</button>
</li>
<li>
<span>Item 2</span>
<button aria-label="Move Item 2 up">↑</button>
<button aria-label="Move Item 2 down">↓</button>
</li>
</ul>
```

Also applies to sliders, map panning, colour pickers, and similar drag-based widgets—always provide an equivalent click/tap or keyboard path.

---

## ARIA tabs

Tabs require `role="tablist"`, `role="tab"`, and `role="tabpanel"` with proper `aria-selected`, `aria-controls`, and keyboard support.

```html
<div role="tablist" aria-label="Product information">
<button role="tab" id="tab-1" aria-selected="true"
aria-controls="panel-1">Description</button>
<button role="tab" id="tab-2" aria-selected="false"
aria-controls="panel-2" tabindex="-1">Reviews</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
<!-- Panel content -->
</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>
<!-- Panel content -->
</div>
```

Arrow keys should move focus between tabs; the active tab receives `tabindex="0"` while inactive tabs use `tabindex="-1"`.

---

## Live regions and notifications

Use `aria-live` to announce dynamic content changes to screen readers without moving focus.

```html
<!-- Status updates (polite — waits for pause in speech) -->
<div aria-live="polite" aria-atomic="true" class="status">
<!-- Content updates announced to screen readers -->
</div>

<!-- Urgent alerts (assertive — interrupts) -->
<div role="alert" aria-live="assertive">
<!-- Interrupts current announcement -->
</div>
```

```javascript
function showNotification(message, type = 'polite') {
const container = document.getElementById(`${type}-announcer`);
container.textContent = '';
requestAnimationFrame(() => {
container.textContent = message;
});
}
```

Clear the container before writing to ensure the same message triggers a new announcement.

---

## Screen reader commands

Quick reference for the most common screen reader shortcuts.

| Action | VoiceOver (Mac) | NVDA (Windows) |
|--------|-----------------|----------------|
| Start/Stop | ⌘ + F5 | Ctrl + Alt + N |
| Next item | VO + → | ↓ |
| Previous item | VO + ← | ↑ |
| Activate | VO + Space | Enter |
| Headings list | VO + U, then arrows | H / Shift + H |
| Links list | VO + U | K / Shift + K |
Loading
Loading