Proposed CSC Standards
Accessibility
Cross-component rules tied to WCAG 2.2 AA, HTML, and ARIA. Meeting a rule here is not a completed audit.
Rules
Use the HTML element that matches the behavior
Links navigate. Buttons act. Headings are headings. Tables are tables.
Implementation detail
Semantic elements provide roles and keyboard behavior that custom widgets must rebuild.
Use a link for navigation, a button for an action, a heading for a heading, and a table for tabular data.
Check: The accessibility role matches the visual behavior.
Keep a visible focus indicator
Every interactive control shows :focus-visible.
Implementation detail
WCAG 2.4.7 and 2.4.11.
Do not remove the 3px #85b6ff outline without a replacement that meets 2.4.11.
Check: Tab through the page. Each stop is visible.
Name every control
Inputs, buttons, and links have accessible names.
Implementation detail
WCAG 4.1.2 Name, Role, Value.
Use visible labels. Use aria-label only when the control has no visible text, such as an icon-only button.
Check: Accessibility properties show a name for each control.
Meet contrast for text and controls
Text is at least 4.5:1. Control boundaries and icons are at least 3:1.
Implementation detail
WCAG 1.4.3 and 1.4.11. White on #EC1C2D fails 4.5:1, so destructive buttons use #C41222.
Use the tokens. Measure new combinations.
Check: Record the measured pairs. Do not mark the product as audited from this page alone.
Identify errors in text
A failed field or form says what is wrong in text.
Implementation detail
WCAG 3.3.1.
Put the error in text on the field or in an alert. Do not rely on a red border.
Check: The error string is present and associated with the field or form.
Meet the 24 CSS pixel target minimum
Targets are at least 24 by 24 CSS pixels except where WCAG 2.5.8 lists an exception.
Implementation detail
This is the AA minimum. A 44 pixel target is a separate proposed convention.
See BTN-008 and BTN-009. Do not swap the two numbers.
Check: Measure the border box or document the exception.
Examples
The accessible name is the aria-label. The icon is hidden from it.
Imports: None. Dependencies: None. Rules: A11Y-003.
export function ClosePanel() {
return (
<button type="button" aria-label="Close dialog" style={{ width: 40, height: 40, borderRadius: 8, border: 0, background: 'transparent' }}>
<span aria-hidden="true">×</span>
</button>
);
}Testing checklist
Reusable prompts for this guideline are in the AI Development Hub.