Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
3d615e6
feat(orders): ORDERS-7706 add new return page layout
jpajar May 4, 2026
43587dc
feat(returns): ORDERS-7704 condition for new returns on orders page (…
bc-vivekaggarwal May 12, 2026
5453ccd
Merge pull request #2649 from bigcommerce/ORDERS-7706
jpajar May 8, 2026
cbee406
feat(returns): ORDERS-7705 condition for new returns on order details…
bc-vivekaggarwal May 12, 2026
ff03b37
feat(orders): ORDERS-7734 add template for guest return portal
BC-SEven Apr 28, 2026
524eefb
feat(returns): ORDERS-7708 new-return page — render items from order …
bc-vivekaggarwal May 27, 2026
594fed1
feat(orders): ORDERS-7331 add template for create return page
May 28, 2026
a7959e4
Merge pull request #2649 from bigcommerce/ORDERS-7706
jpajar May 8, 2026
f69d4be
feat(returns): ORDERS-7717 - add new returns list ui
bc-bryan May 26, 2026
c365118
feat(returns): ORDERS-7717 - use rma number
bc-bryan May 27, 2026
8ce1483
feat(returns): ORDERS-7717 - add CHANGELOG item
bc-bryan May 28, 2026
36fc679
feat(returns): ORDERS-7717 - address copilot review
bc-bryan May 28, 2026
d9e25bb
feat(orders): ORDERS-7718 add return details page layout
jpajar Jun 5, 2026
96477f6
feat(orders): ORDERS-7718 add status mappping from enum
jpajar Jun 9, 2026
b5d0ec1
Orders 7764 render create return page with context (#2673)
bc-vivekaggarwal Jun 11, 2026
ba7c537
feat(orders): ORDERS-7707 improve create return page design for mobil…
jpajar Jun 16, 2026
7e694b8
feat(orders): ORDERS-7715 add createReturn mutation and confirmation …
jpajar Jun 22, 2026
2dc8a1e
feat(orders): ORDERS-7715 handle double submissions
jpajar Jun 22, 2026
6503884
feat(orders): ORDERS-7859 add error message on failed return creation
jpajar Jun 23, 2026
42c63df
feat(returns): ORDERS-7857 add loading state as return submission (#2…
bc-vivekaggarwal Jun 25, 2026
29a1827
feat(returns): ORDERS-7751 - add return details page data
bc-bryan Jun 15, 2026
5835d6d
feat(orders): ORDERS-7751 add placeholder image
bc-bryan Jun 19, 2026
f4424d6
feat(returns): ORDERS-7751 check resolution and requested exist
bc-bryan Jun 19, 2026
85c27fb
feat(returns): ORDERS-7751 use handlebars for details templates
bc-bryan Jun 25, 2026
dec1665
feat(returns): ORDERS-7751 update thumbnail image TODO with id
bc-bryan Jun 25, 2026
be5ff79
feat(returns): ORDERS-7751 remove unused localization keys and markup
bc-bryan Jun 25, 2026
9cd3c8b
feat(returns): ORDERS-7751 use span tag instead of dt tag
bc-bryan Jun 25, 2026
41a88dc
feat(returns): ORDERS-7751 output localized string instead of status …
bc-bryan Jun 26, 2026
459b272
feat(returns): ORDERS-7751 add sr-only label for orderId
bc-bryan Jun 26, 2026
b4af3c7
feat(returns): ORDERS-7751 remove per item status
bc-bryan Jun 30, 2026
941b401
feat(returns): ORDERS-7751 add order_number_label key
bc-bryan Jun 30, 2026
767f027
feat(returns): ORDERS-7751 reference correct object for thumbnail fal…
bc-bryan Jun 30, 2026
453684e
feat(orders): ORDERS-7681 add Cancel return button and handler to ret…
jpajar Jun 24, 2026
78d39ba
feat(orders): ORDERS-7681 extend Account module for ReturnDetails module
jpajar Jul 1, 2026
31944dc
feat(returns): ORDERS-7771 tighten spacing on mobile and tablet viewp…
bc-bryan Jul 1, 2026
2ce4429
feat(returns): ORDERS-7771 update changelog
bc-bryan Jul 1, 2026
c16e5a1
feat(returns): ORDERS-7771 scope shared account css changes to return…
bc-bryan Jul 1, 2026
592a299
feat(returns): ORDERS-7771 fix mobile stacking for detail items
bc-bryan Jul 1, 2026
6094e64
feat(returns): ORDERS-7771 remove invalid margin value
bc-bryan Jul 1, 2026
8e32413
feat(returns): ORDERS-7771 move returns list specific styles to it's …
bc-bryan Jul 1, 2026
0bc45a2
feat(returns): ORDERS-7771 address copilot feedback
bc-bryan Jul 2, 2026
3e8fb51
feat(orders): ORDERS-7736 implement guest return portal page (#2696)
BC-SEven Jul 8, 2026
b932c97
feat(orders): ORDERS-7886 Update error message to generic message wit…
BC-SEven Jul 12, 2026
149645a
feat(orders): ORDERS-7736 add client side validation for guest return…
BC-SEven Jul 15, 2026
4338a13
feat(orders): ORDERS-7935 add badge for CANCELLED order returns
jpajar Jul 15, 2026
3b5a20e
feat(returns): ORDERS-7900: strike requested with resolved resolution…
bc-vivekaggarwal Jul 16, 2026
29099b0
feat(returns): ORDERS-7752 add cursor pagination to returns
bc-bryan Jul 15, 2026
fad6436
feat(returns): ORDERS-7752 use pagination.<resource> key
bc-bryan Jul 15, 2026
d3672e6
feat(returns): ORDERS-7752 use div with region role
bc-bryan Jul 16, 2026
328441b
feat(orders): ORDERS-7770 add responsive styling for returns details …
jpajar Jul 16, 2026
ea1a9c1
feat(orders): ORDERS-7837 add additional note field to mutation when …
jpajar Jul 21, 2026
bcff912
feat(orders): ORDERS-7838 add additional note section to new shopper …
jpajar Jul 22, 2026
21784af
feat(orders): ORDERS-7647 update return list navigation to work with …
BC-SEven Jul 23, 2026
d766d4f
feat(orders): ORDERS-7890 add product images to return details page (…
BC-SEven Jul 23, 2026
7594a5d
chore(common): PROJECT-7525 move CHANGELOG items back to draft after …
BC-SEven Jul 27, 2026
5f6346f
feat(returns): ORDER-7874 add accessibility to create return page (#2…
bc-vivekaggarwal Jul 27, 2026
87db9d5
Merge pull request #2649 from bigcommerce/ORDERS-7706
jpajar May 8, 2026
1602d12
Merge pull request #2649 from bigcommerce/ORDERS-7706
jpajar May 8, 2026
60fb8b7
fix(returns): ORDERS-7752 rename keys to be snake_case for consistency
bc-bryan Jul 22, 2026
8420d34
feat(returns): ORDERS-7878 add accessibility to returns list page
bc-vivekaggarwal Jul 30, 2026
7b994a9
chore(other): add Bugbot config
bc-vivekaggarwal Jul 31, 2026
426f0cf
feat(orders): ORDERS-7961 fix styling for Warm and Bold themes for St…
jpajar Aug 3, 2026
2242da5
fix(returns): ORDERS-7719 align return detail page with design and sn…
bc-vivekaggarwal Aug 4, 2026
30b719f
feat(returns): ORDERS-7875 add accessibility to return detail page
bc-vivekaggarwal Aug 4, 2026
ff453fd
feat(returns): ORDERS-7877 add order-scoped aria-labels to returns en…
bc-vivekaggarwal Aug 12, 2026
bc4cc2f
feat(orders): ORDERS-7876 improve accessibility for guest-return page
jpajar Aug 11, 2026
7442d25
feat(orders): ORDERS-7876 clear errors to prevent announcing errors t…
jpajar Aug 12, 2026
ee3e527
feat(returns): ORDERS-7945 add page title to returns related pages fo…
bc-vivekaggarwal Aug 14, 2026
21bcea7
feat(orders): ORDERS-7966 add items total to returns detail and listi…
jpajar Aug 14, 2026
91912e6
feat(orders): ORDERS-7966 rename labels as per feedback
jpajar Aug 14, 2026
46f64aa
feat(orders): ORDERS-7959 add "go to return portal link" in webpages …
BC-SEven Aug 25, 2026
3460616
feat(orders): ORDERS-7965 fix return listing page quantity displayed
jpajar Aug 24, 2026
fd3eba7
feat(orders): ORDERS-7965 align date format and status badge between …
jpajar Aug 25, 2026
73581e4
feat(orders): ORDERS-7965 add total for each line item in a return
jpajar Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions .claude/skills/accessibility/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
---
name: accessibility
description: >-
Enforce WCAG 2.2 AA for Cornerstone storefront UI: semantics, accessible names,
forms/errors, keyboard/focus, live regions, decorative hiding, contrast, and
lang/en.json ARIA strings. Use whenever creating or editing anything a shopper
sees or interacts with — Stencil/Handlebars templates (templates/**/*.html),
theme JS (assets/js/theme/**), or component SCSS (assets/scss/**) — including
forms, buttons, links, dialogs, lists, headings, icons, images, status messages,
focus, visibility, layout, color, or motion. Also use when the user mentions
accessibility, ARIA, screen readers, keyboard navigation, focus, or WCAG, even
if they did not ask for an accessibility pass explicitly.
---

# Accessibility (WCAG 2.2 AA) for Cornerstone storefront UI

Cornerstone ships to merchants who inherit our accessibility. Shoppers using a
screen reader, keyboard, or magnification must complete every flow. Build
accessibility in at authoring time — automated checks only catch part of it.

This skill is an implementation guardrail, not a substitute for
[WCAG 2.2](https://www.w3.org/WAI/WCAG22/quickref/). Deeper criteria and
high-churn surfaces: [reference.md](reference.md). Good/bad snippets:
[examples.md](examples.md).

## Do this first

Before editing, list in one line which areas the change affects:

`semantics` · `names/roles/states` · `forms/errors` · `keyboard/focus` ·
`dynamic updates` · `visual/reflow/motion` · `pointer/touch` · `images/media`

Design applicable requirements into the solution, then edit.

## Mandatory rules

1. **Semantics before ARIA.** Use `<button>` / `<a href>` (not a clickable
`<div>`), `<ul>/<li>` for lists, one `<h1>` per page with non-skipping
heading levels, `<main>` / `<form>` landmarks. Add `role` / `aria-*` only
when HTML cannot express the semantics — no ARIA beats bad ARIA.
- **Changing a tag changes its styling — preserve it on the class.** When
you swap an element's tag to fix semantics, tag-dependent CSS (element
styles, default UA margins, and any theme rules keyed on the old tag) does
**not** follow. Before finishing, diff the old vs new tag's computed styling
and add whatever the class was relying on so appearance is preserved. Put it
on the **component's own class or a scoped selector** — do **not** broaden a
_shared_ class's contract to fix one component, which regresses any consumer
whose tag legitimately differs.

2. **Names, forms, and errors.**
- Every control needs an accessible name. Prefer a persistent visible
`<label>`; placeholders and `title` are not labels. The accessible name
must contain the visible label text.
- Use `<fieldset>/<legend>` for related controls; valid `autocomplete`
tokens for user data; keep instructions available while completing the field.
- Inside `{{#each}}`, derive ids from the item id (`id="qty-{{id}}"`) —
never a static id in a loop.
- If the visible label is `display:none` at any breakpoint, use
`aria-labelledby` instead of `<label for>` (hidden labels drop from the
accessibility tree; `aria-labelledby` does not).
- Keep required/invalid and ARIA state (`expanded`, `selected`, `pressed`,
`current`, etc.) synchronized with the UI. Link hints/errors with
`aria-describedby`. Errors identify the field, explain the problem,
suggest correction, and preserve entered values.

3. **Keyboard and focus.**
- Prefer native controls. Links: Enter. Buttons: Enter/Space. Custom widgets:
follow the applicable WAI-ARIA Authoring Practices pattern (Escape/arrows
where specified).
- All functionality works without a pointer; no keyboard traps. Focus order
matches DOM order; avoid positive `tabindex`.
- Focus is visible, ≥3:1 against adjacent colors, and not entirely obscured.
Prefer `:focus-visible` with a 2px outline.
- Use native `disabled` when unavailable. Use `aria-disabled="true"` only
when the control must stay focusable/discoverable — then block click,
keyboard, and submit in JS. Never put `aria-disabled` on a container with
active descendants.
- Failed submit: error summary with `tabindex="-1"`, move focus to it.
Do **not** also give that focused summary `role="alert"`. For urgent async
errors where focus should stay put, use a pre-existing `role="alert"`
region. Set `aria-invalid="true"` on invalid fields.
- Success / major view change: move focus only when needed to establish
context; avoid focusing whole containers. Never use timing hacks to wait
for screen-reader speech.

4. **Announce dynamic changes.** Loading, progress, and success use a concise,
pre-existing status region, e.g.:

```html
<p class="aria-description--hidden" role="status" aria-atomic="true" data-status></p>
```

Replace stale text rather than accumulating messages. Set `aria-busy="true"`
on the affected region while processing. Default to polite (`role="status"`
or `aria-live="polite"`); use assertive (`aria-live="assertive"`) only when a
shopper acting on stale info could cause a real problem — e.g. Cornerstone's
return submission uses assertive so shoppers don't double-submit or navigate
away mid-request (see [examples.md](examples.md#4-announce-progress-move-focus-for-success)).
Prefer assertive over `role="alert"` for this — `alert` implies an error.

5. **The two “hiddens” are opposites.**
- `aria-hidden="true"`: seen, not heard. Never on a focusable element.
- `.aria-description--hidden`: heard, not seen (SR-only text and live regions).
- Informative images: concise `alt`. Decorative `<img>`: `alt=""`. Decorative
SVG/icons: `aria-hidden="true"`, not focusable. Icon-only controls need a
translatable accessible name.

6. **Visual, motion, pointer, media.** Preserve content under zoom, reflow,
text-spacing, forced colors, and `prefers-reduced-motion`. Meet contrast;
never use color alone; pointer targets ≥24×24 CSS px unless SC 2.5.8
exception applies. In Cornerstone, `color("greys","base")` (#999) fails for
text — use `color("greys","dark")` (#666).
- **`prefers-reduced-motion` targets substantial/auto-playing motion**
(parallax, carousels, looping scenes). Transient loading spinners are
exempt (SC 2.2.2, A) and reduced-motion coverage for them is AAA — don't
add per-spinner overrides.

7. **Translatable strings.** No hardcoded English in ARIA. Add a key to
`lang/en.json`, reference via `{{lang '...'}}` or
`{{~inject 'x' (lang '...')}}` for JS. Remove unused keys.

8. **Cornerstone conventions.**
- Reuse `form-select`, `form-input`, `form-label`, `button`,
`aria-description--hidden` — they carry focus/contrast/state styling.
- Merchant/customer strings: `{{value}}` (auto-escapes). Never
`{{{sanitize value}}}` for those strings.

## Verification checklist

Copy and track. Never claim a manual check passed unless it was performed.

```
A11y progress:
- [ ] Affected areas listed (Do this first)
- [ ] Semantics / names / roles / states correct
- [ ] Forms, errors, ids (incl. loops) correct
- [ ] Keyboard / focus plan implemented
- [ ] Dynamic updates announced (or N/A)
- [ ] Decorative content hidden correctly
- [ ] Contrast / motion / targets checked as applicable
- [ ] lang/en.json keys added; unused keys removed
- [ ] Diff audit (below) done
- [ ] Lighthouse audit run manually against a rendered URL
- [ ] Manual checks still required: _______________
```

1. **Static / diff audit (always):** unique and unorphaned ids; no focusable
`aria-hidden`; no stale ARIA state; no a11y behavior removed by responsive
CSS; translatable ARIA strings.
2. **Lighthouse (manual — there's no automated pipeline for this; run it
yourself against a rendered URL when one is available):**
`URL=<page-url> npm run lighthouse` (target 100% accessibility). Use axe
DevTools when available. A clean Lighthouse run ≠ WCAG conformance.
3. **Keyboard / responsive (when interactive environment available):** full
flow without pointer; focus visibility/order; no traps; zoom/reflow;
reduced motion as applicable.
4. **Screen reader (when available):** VoiceOver (macOS ⌘F5) or NVDA — changed
names, states, errors, announcements.

If keyboard, screen reader, or Lighthouse could not run, say so explicitly in
your response and list what remains for the human.

## Project pattern references

Validate patterns against the rules above — existing code may predate guidance:

- `templates/pages/create-return.html`
- `templates/pages/account/returns.html`
- `templates/components/account/returns-list-v2.html`
- `templates/components/carousel-content-announcement.html`
- `templates/components/carousel-play-pause-button.html`

Canonical recent examples of form/focus/live-region work: returns templates.
Carousel files show announcement + play/pause naming patterns.
Loading
Loading