raweb-code — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited raweb-code (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are an accessibility-aware developer. Every piece of HTML, CSS, and JavaScript you write MUST conform to RAWeb 1.1 (Level AA by default). RAWeb is Luxembourg's official web accessibility framework implementing EN 301 549 and WCAG 2.1.
The full RAWeb 1.1 criteria, test methodologies, and glossary are available as JSON files. Use the lookup script to query specific criteria on demand:
# List all topics
!`${CLAUDE_SKILL_DIR}/scripts/raweb-lookup.sh topics`
# Look up a specific criterion
bash ${CLAUDE_SKILL_DIR}/scripts/raweb-lookup.sh criterion 1.1
# Look up test methodology
bash ${CLAUDE_SKILL_DIR}/scripts/raweb-lookup.sh methodology 1.1.1
# Search criteria by keyword
bash ${CLAUDE_SKILL_DIR}/scripts/raweb-lookup.sh search "form"
# Check glossary definition
bash ${CLAUDE_SKILL_DIR}/scripts/raweb-lookup.sh glossary "text alternative"The raw JSON reference files are located at:
${CLAUDE_SKILL_DIR}/references/criteres.json — All 136+ criteria with tests and WCAG/EN 301 549 mappings${CLAUDE_SKILL_DIR}/references/methodologies.json — Step-by-step test procedures${CLAUDE_SKILL_DIR}/references/glossaire.json — Glossary of accessibility terms${CLAUDE_SKILL_DIR}/references/themes.json — Topic names${CLAUDE_SKILL_DIR}/references/niveaux.json — WCAG conformance levels per criterionWhen writing code for a specific component, ALWAYS look up the relevant RAWeb criteria first to ensure full compliance. For example, before writing a form, run search "form" and topic 11.
ALWAYS:
<img> conveying information MUST have a meaningful alt attribute (1.1)<img> MUST have alt="" and no title, aria-label, or aria-labelledby (1.2)<svg> conveying information MUST have role="img" + text alternative via aria-label or aria-labelledby (1.1)<svg> MUST have aria-hidden="true" (1.2)aria-describedby (1.6)NEVER:
alt undefined on an informative imagealt="image", alt="photo", alt="icon" — describe what the image conveystitle as the sole text alternative (poor assistive technology support)<!-- GOOD: informative image -->
<img src="chart.png" alt="Sales increased 40% in Q3 2024">
<!-- GOOD: decorative image -->
<img src="decoration.svg" alt="">
<!-- GOOD: complex image with detailed description -->
<figure>
<img src="orgchart.png" alt="Company organisation chart. Full description below.">
<figcaption>
<details>
<summary>Full description of the organisation chart</summary>
<p>The CEO reports to the board. Three departments report to the CEO...</p>
</details>
</figcaption>
</figure>
<!-- GOOD: SVG informative -->
<svg role="img" aria-label="Warning: connection unstable">
<use href="#icon-warning"/>
</svg>
<!-- GOOD: SVG decorative -->
<svg aria-hidden="true" focusable="false"><use href="#flourish"/></svg><iframe> MUST have a descriptive title attribute (2.1)title must be relevant to the frame content (2.2)<iframe src="map.html" title="Interactive map of our office locations"></iframe><!-- BAD: colour alone conveys meaning -->
<span class="text-red">Required field</span>
<!-- GOOD: colour + text indicator -->
<span class="text-red">Required field *</span>
<span class="sr-only">(required)</span>
<!-- Or better with native HTML -->
<input type="text" required aria-required="true"><video controls>
<source src="presentation.mp4" type="video/mp4">
<track kind="captions" src="captions-en.vtt" srclang="en" label="English" default>
<track kind="descriptions" src="descriptions-en.vtt" srclang="en" label="English audio descriptions">
</video><th> elements for headers with appropriate scope attribute (5.6, 5.7)id/headers associations (5.7)<caption>, aria-label, or aria-labelledby (5.4)<th>, <caption>, scope, or headers (5.8)<!-- GOOD: simple data table -->
<table>
<caption>Q3 2024 Revenue by Region</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col">Revenue</th>
<th scope="col">Growth</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Europe</th>
<td>€2.4M</td>
<td>+12%</td>
</tr>
</tbody>
</table>aria-label or aria-labelledby — but the aria-label MUST include the visible text (6.1, 6.2)<!-- BAD -->
<a href="/report.pdf">Click here</a>
<!-- GOOD -->
<a href="/report.pdf">Download the Q3 2024 financial report (PDF, 2.4 MB)</a>
<!-- GOOD: contextual with aria-label containing visible text -->
<article>
<h3>RAWeb 1.1 released</h3>
<p>The new version adds 17 additional criteria...</p>
<a href="/news/raweb" aria-label="Read more about RAWeb 1.1 released">Read more</a>
</article>role="status", role="alert", role="log", aria-live, or aria-relevant (7.4)<!-- GOOD: live region for status updates -->
<div role="status" aria-live="polite" aria-atomic="true">
<p>3 results found.</p>
</div>
<!-- GOOD: alert for important messages -->
<div role="alert">
<p>Your session will expire in 2 minutes.</p>
</div>// GOOD: keyboard + pointer support
button.addEventListener('click', handler); // covers mouse + Enter/Space
button.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handler(e);
}
});<!DOCTYPE html> (8.1)lang attribute on <html> matching the primary language (8.3)lang on the relevant element (8.7 — Level AA)<title> (8.5, 8.6)<title> MUST be updated when the page state changes significantly (8.6)id attributes in the page (8.2)<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Contact Us — Acme Corp</title>
</head>
<body>
<p>Visit our <span lang="fr">bureau principal</span> in Luxembourg.</p>
</body>
</html><h1>–<h6>) with a logical hierarchy — no skipped levels (9.1)<header>, <nav>, <main>, <footer>, <aside> (9.2)<ul>, <ol>, <dl>) for list content (9.3)<blockquote> for quotations with proper cite if applicable (9.4)<body>
<header role="banner">
<nav aria-label="Main navigation">...</nav>
</header>
<main role="main">
<h1>Page Title</h1>
<section aria-labelledby="section-heading">
<h2 id="section-heading">Section</h2>
<h3>Sub-section</h3>
</section>
</main>
<footer role="contentinfo">...</footer>
</body>/* GOOD: visible focus indicator */
:focus-visible {
outline: 3px solid #0056b3;
outline-offset: 2px;
}
/* GOOD: ensure reflow support */
.container {
max-width: 100%;
overflow-wrap: break-word;
}
/* NEVER: hide focus outline globally */
/* *:focus { outline: none; } ← FORBIDDEN */This is a critical topic. Always look up criteria with `bash ${CLAUDE_SKILL_DIR}/scripts/raweb-lookup.sh topic 11` when implementing forms.
<label for="id">, aria-labelledby, aria-label, or title (11.1)<label> element with for attribute is the preferred method (11.1)<fieldset> and <legend> (11.5)required and/or aria-required="true" for mandatory fields (11.10)autocomplete with appropriate values (11.13 — Level AA)<form novalidate>
<fieldset>
<legend>Personal information</legend>
<div>
<label for="fname">First name <span aria-hidden="true">*</span></label>
<input type="text" id="fname" name="fname"
autocomplete="given-name"
required aria-required="true"
aria-describedby="fname-error">
<p id="fname-error" role="alert" class="error" hidden>
Please enter your first name.
</p>
</div>
<div>
<label for="email">Email address <span aria-hidden="true">*</span></label>
<input type="email" id="email" name="email"
autocomplete="email"
required aria-required="true"
aria-describedby="email-hint email-error">
<p id="email-hint" class="hint">Format: [email protected]</p>
<p id="email-error" role="alert" class="error" hidden>
Please enter a valid email address (e.g., [email protected]).
</p>
</div>
</fieldset>
<button type="submit">Submit</button>
</form>tabindex values (12.8)<body>
<!-- Skip link: first focusable element -->
<a href="#main-content" class="skip-link">Skip to main content</a>
<nav aria-label="Main navigation">
<ul>
<li><a href="/" aria-current="page">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
<main id="main-content" tabindex="-1">
<!-- Page content -->
</main>
</body>.skip-link {
position: absolute;
top: -100%;
left: 0;
z-index: 1000;
padding: 0.5rem 1rem;
background: #000;
color: #fff;
}
.skip-link:focus {
top: 0;
}<!-- GOOD: file download with format and size -->
<a href="/report.pdf">
Annual report 2024 <span class="file-info">(PDF, 3.2 MB)</span>
</a>
<!-- GOOD: new window warning -->
<a href="https://external.example.com" target="_blank"
rel="noopener noreferrer">
External resource
<span class="sr-only">(opens in a new window)</span>
</a>When building interactive components, look up the correct ARIA pattern from the local reference data BEFORE writing any code. The component library contains 30 patterns extracted from the WAI-ARIA Authoring Practices Guide with keyboard interactions, required/optional ARIA attributes, and implementation notes.
# Find the right pattern by keyword (e.g., "modal", "dropdown", "toggle")
bash ${CLAUDE_SKILL_DIR}/scripts/raweb-component-lookup.sh find "<keyword>"
# Show full pattern details (keyboard, ARIA roles, attributes, notes)
bash ${CLAUDE_SKILL_DIR}/scripts/raweb-component-lookup.sh show <slug>
# List all 30 available patterns
bash ${CLAUDE_SKILL_DIR}/scripts/raweb-component-lookup.sh list
# Find patterns that use a specific ARIA role
bash ${CLAUDE_SKILL_DIR}/scripts/raweb-component-lookup.sh roles "<role>"find with the most natural keyword the developer usedshow <slug> to get keyboard interactions and ARIA requirementsThe individual pattern files are located at: ${CLAUDE_SKILL_DIR}/references/components/<slug>.json
Each file contains:
description — What the component iskeyboard_interactions — All required and optional keyboard behavioursaria.roles — Which ARIA roles to use and wherearia.required_attributes — Attributes that MUST be presentaria.optional_attributes — Attributes to add when applicablenotes — Implementation tips and common pitfalls| When the developer says... | Look up slug |
|---|---|
| modal, dialog, popup, overlay, lightbox | dialog-modal |
| tabs, tab panel, tabbed interface | tabs |
| accordion, collapsible, FAQ | accordion |
| dropdown menu, context menu, submenu | menubar or menu-button |
| toast, notification, flash message | alert |
| confirm dialog, delete confirmation | alertdialog |
| carousel, slideshow, image gallery | carousel |
| autocomplete, typeahead, combobox | combobox |
| select, dropdown list, listbox | listbox |
| breadcrumb, navigation trail | breadcrumb |
| tooltip, hint, hover text | tooltip |
| toggle, switch, on/off | switch |
| slider, range, volume control | slider or slider-multithumb |
| tree, file browser, nested list | treeview |
| data grid, spreadsheet, editable table | grid |
| static table, data table | table |
| toolbar, action bar, button group | toolbar |
| radio buttons, option group | radio |
| checkbox, check all | checkbox |
| show/hide, details, read more | disclosure |
| spinner, number input, stepper | spinbutton |
| meter, gauge, battery level | meter |
| feed, infinite scroll, timeline | feed |
| page structure, landmarks | landmarks |
| split view, resizable panes | windowsplitter |
Always include and use this utility in your CSS:
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}Before considering any code complete, verify:
alt (informative) or alt="" (decorative)lang attribute and language changes are marked<title><nav>, <main>, <header>, <footer>)bash ${CLAUDE_SKILL_DIR}/scripts/raweb-lookup.sh criterion <topic.criterion>bash ${CLAUDE_SKILL_DIR}/scripts/raweb-lookup.sh methodology <topic.criterion.test>bash ${CLAUDE_SKILL_DIR}/scripts/raweb-component-lookup.sh find "<keyword>" then show <slug>bash ${CLAUDE_SKILL_DIR}/scripts/raweb-lookup.sh glossary "<term>"<button> is better than <div role="button">~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.