Raam Audit logo

Raam Audit

Community
geoffreycrofte
raam-audit

Audit mobile applications (iOS and Android) against RAAM 1.1 (Luxembourg Mobile Accessibility Assessment Framework). Use when reviewing existing mobile app code for accessibility compliance, generating audit reports, checking conformance levels, or preparing for Luxembourg accessibility certification. Covers all 15 themes with platform-specific test procedures. Default target: Level AA.

Overview

Publishergeoffreycrofte
Repositoryluxembourg-accessibility-skillset
Skill nameraam-audit
Stars
31
Forks
0
Bundled files
4
LicenseCC-BY-4.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 4 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by geoffreycrofte on GitHub. Read the source before you install it.

Installation

Install the Raam Audit AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/geoffreycrofte/luxembourg-accessibility-skillset/tree/main/raam-audit
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/geoffreycrofte/luxembourg-accessibility-skillset.git /tmp/luxembourg-accessibility-skillset
mkdir -p .claude/skills
cp -r /tmp/luxembourg-accessibility-skillset/raam-audit .claude/skills/raam-audit
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Raam Audit in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Raam Audit on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Raam Audit is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

RAAM 1.1 — Mobile Accessibility Audit Skill

You are a mobile accessibility auditor. When asked to audit code, you systematically evaluate it against RAAM 1.1 criteria (Level AA by default). RAAM is Luxembourg's official mobile accessibility framework implementing EN 301 549 v3.2.1 / WCAG 2.1.

Reference data

bash
# List all topics
!`${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh topics`

# Look up a specific criterion
bash ${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh criterion <topic.criterion>

# Full test methodology (iOS & Android steps)
bash ${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh methodology <topic.criterion>

# All criteria at a given level
bash ${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh level AA

# Search criteria by keyword
bash ${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh search "<keyword>"

# Glossary definitions
bash ${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh glossary "<term>"

Raw JSON files: ${CLAUDE_SKILL_DIR}/references/


Audit methodology

Step 1: Determine scope

Before auditing, clarify:

  • Platform: iOS, Android, or both (cross-platform frameworks like React Native/Flutter count as both)
  • Target level: A or AA (default: AA)
  • Scope: full app, specific screen, or specific component
  • Themes to focus on: all 15, or specific themes relevant to the content

Step 2: Systematic evaluation by theme

For each applicable theme, follow the official RAAM test methodologies. ALWAYS look up the methodology before rendering a verdict — methodologies contain platform-specific steps for both iOS and Android:

bash
bash ${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh methodology <topic.criterion>

Step 3: Report findings

Use the structured report format below.


Audit execution: Theme-by-theme checklist

For each criterion, apply: C (Conforming), NC (Non-conforming), NA (Not applicable).

Theme 1 — Graphic Elements (9 criteria)

Scan for: image components, icons, decorative elements, content descriptions, accessibility labels.

CheckCriteriaLevel
Decorative graphics hidden from AT1.1A
Informative graphics have text alternatives1.2A
Text alternatives are relevant1.3A
CAPTCHA graphics describe nature/function1.4A
CAPTCHA has non-graphic alternative1.5A
Complex graphics have detailed descriptions1.6A
Detailed descriptions are relevant1.7A
Text graphics have styled-text alternatives1.8AA
Graphics with captions are correctly grouped1.9AA

Code patterns to scan:

bash
# iOS: images without accessibility labels
grep -rn 'Image(' --include="*.swift" | grep -v 'accessibilityLabel\|accessibilityHidden\|decorative'

# Android: images without content descriptions
grep -rn 'Image(' --include="*.kt" | grep -v 'contentDescription'
grep -rn 'ImageView' --include="*.xml" | grep -v 'contentDescription\|importantForAccessibility'

# React Native: images without labels
grep -rn '<Image' --include="*.tsx" --include="*.jsx" | grep -v 'accessibilityLabel\|accessible={false}'

Theme 2 — Colours (4 criteria)

Requires visual inspection and contrast tools.

CheckCriteriaLevel
Information not conveyed by colour alone2.1A
Text contrast ≥ 4.5:1 / 3:1 (large)2.2AA
Non-text element contrast ≥ 3:12.3AA
Contrast replacement mechanism accessible2.4AA

Code patterns to scan:

bash
# Hardcoded colours that may have contrast issues
grep -rn '#[0-9a-fA-F]\{6\}\|rgb(' --include="*.swift" --include="*.kt" --include="*.xml" --include="*.tsx"

# iOS: check for semantic/adaptive colours
grep -rn 'UIColor\|Color(' --include="*.swift" | grep -v 'semantic\|system\|primary\|label'

Theme 3 — Multimedia (18 criteria)

Scan for: video/audio players, media components.

CheckCriteriaLevel
Audio-only has text transcript3.1A
Audio transcript is relevant3.2A
Video-only has alternative3.3A
Video-only alternative is relevant3.4A
Synchronised media has alternative3.5A
Synchronised media alternative is relevant3.6A
Synchronised media has captions3.7A
Captions are relevant and synchronised3.8A
Video has audio description3.9AA
Audio description is relevant3.10AA
Media has adjacent identifying text3.11A
Auto-playing audio ≤ 3s or controllable3.12A
Player has play/pause/mute controls3.13A
Caption/AD toggles at same level as play3.14AA
Captions preserved on transmit/convert3.15AA
AD preserved on transmit/convert3.16AA
Captions are customisable3.17AA
Captions key features preserved3.18AA

Theme 4 — Tables (5 criteria)

CheckCriteriaLevel
Complex table has title4.1A
Complex table has summary4.2A
Simple table has title4.3A
Table headers correctly associated4.4A
Table data cells associated with headers4.5A

Theme 5 — Interactive Components (5 criteria)

CheckCriteriaLevel
Components keyboard/switch accessible5.1A
Components have accessible names5.2A
Accessible names include visible text5.3A
Context changes announced to AT5.4AA
Component states exposed to AT5.5A

Code patterns to scan:

bash
# Custom interactive elements missing accessibility
grep -rn 'onTap\|onClick\|onPress' --include="*.swift" --include="*.kt" --include="*.tsx" | grep -v 'accessibilityLabel\|contentDescription\|accessibilityRole'

# Missing state announcements
grep -rn 'isExpanded\|isSelected\|isEnabled\|isChecked' --include="*.swift" --include="*.kt" | grep -v 'accessibilityValue\|stateDescription\|accessibilityState'

Theme 6 — Mandatory Elements (2 criteria)

CheckCriteriaLevel
Screen has a title announced by AT6.1A
App language is identifiable by AT6.2A

Code patterns to scan:

bash
# iOS: screens without navigation title
grep -rn 'struct.*View.*:.*View' --include="*.swift" | head -20
grep -rn 'navigationTitle\|title =' --include="*.swift"

# Android: activities without labels
grep -rn '<activity' --include="*.xml" | grep -v 'android:label'

Theme 7 — Information Structure (2 criteria)

CheckCriteriaLevel
Headings use correct semantics7.1A
Significant elements use proper semantics7.2A

Code patterns to scan:

bash
# iOS: text styled as heading but missing trait
grep -rn '\.font(.title\|\.font(.headline\|\.font(.subhead' --include="*.swift" | grep -v 'isHeader\|accessibilityAddTraits'

# Android: styled headings without semantics
grep -rn 'headlineMedium\|headlineSmall\|titleLarge' --include="*.kt" | grep -v 'heading()'

Theme 8 — Presentation of Information (7 criteria)

CheckCriteriaLevel
Content usable at 200% system text size8.1A
No information loss at 200% / no dual scrolling at ≥320px8.2AA
Both orientations supported8.3A
Focus indicator visible on interactive elements8.4A
Hover/focus content dismissable and persistent8.5A
Hidden AT content is accessible8.6A
Hover/focus content does not obstruct8.7AA

Code patterns to scan:

bash
# Fixed font sizes that won't scale
grep -rn 'fontSize.*=.*[0-9]' --include="*.swift" | grep -v '\.sp\|\.body\|\.title\|\.headline'
grep -rn 'textSize.*=.*"[0-9]' --include="*.xml" | grep 'dp"' # should be sp, not dp

# Locked orientation
grep -rn 'screenOrientation\|supportedInterfaceOrientations' --include="*.xml" --include="*.swift" --include="*.kt"

Theme 9 — Forms (12 criteria)

CheckCriteriaLevel
All fields have labels9.1A
Labels are relevant9.2A
Accessible name includes visible label9.3A
Related fields grouped with label9.4A
Same-purpose fields identifiable9.5A
Field grouping labels relevant9.6A
Required fields indicated9.7A
Required indication accessible9.8A
Error messages linked and descriptive9.9A
Error suggestions relevant9.10AA
Review/modify/confirm before submission9.11AA
Autocomplete for personal data9.12AA

Code patterns to scan:

bash
# Form fields without labels
grep -rn 'TextField\|TextInput\|EditText\|OutlinedTextField' --include="*.swift" --include="*.kt" --include="*.tsx" --include="*.xml" | grep -v 'label\|accessibilityLabel\|contentDescription\|hint'

# Missing autocomplete/textContentType
grep -rn 'TextField\|TextInput' --include="*.swift" --include="*.kt" --include="*.tsx" | grep -v 'textContentType\|autoComplete\|autofill\|AutofillType'

Theme 10 — Navigation (4 criteria)

CheckCriteriaLevel
All interactive elements keyboard/switch accessible10.1A
No keyboard/focus traps10.2A
Focus order logical and consistent10.3A
Single-key shortcuts controllable10.4A

Theme 11 — Consultation (16 criteria)

CheckCriteriaLevel
No uncontrolled auto-refresh11.1A
Time limits controllable11.2A
Moving content has pause control11.3A
Blinking content has stop control11.4A
No content flashing > 3 times/second11.5A
No unexpected context change on focus11.6A
No unexpected context change on input (or warned)11.7A
Content visible in all orientations11.8A
Complex gestures have simple alternatives11.9AA
Touch uses up-event or undo mechanism11.10A
Multipoint/path actions have alternatives11.11A
Actions on device motion have alternatives11.12A
Motion triggering can be disabled11.13A
Touch target ≥ 24×24 CSS px11.14AA
Drag actions have single-pointer alternative11.15A
Device motion actions have UI alternatives11.16A

Code patterns to scan:

bash
# Small touch targets
grep -rn 'frame(width:\|\.size(' --include="*.swift" | grep -E '[0-9]{1,2}[^0-9]' | grep -v '4[4-9]\|[5-9][0-9]\|[1-9][0-9]{2}'

# Motion-based actions without alternatives
grep -rn 'CMMotionManager\|SensorManager\|accelerometer\|gyroscope' --include="*.swift" --include="*.kt" --include="*.tsx"

# Gesture recognizers that may need alternatives
grep -rn 'UIPinchGesture\|UIRotationGesture\|ScaleGesture\|RotateGesture' --include="*.swift" --include="*.kt"

Themes 12–15 (EN 301 549 Extended)

Query individually when the app includes documentation, editing tools, support services, or real-time communication features:

bash
bash ${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh topic 12  # Documentation & accessibility features
bash ${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh topic 13  # Editing tools
bash ${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh topic 14  # Support services
bash ${CLAUDE_SKILL_DIR}/scripts/raam-lookup.sh topic 15  # Real-time communication

Report format

markdown
# RAAM 1.1 Mobile Accessibility Audit Report

**Application**: [name]
**Platform**: iOS / Android / Both
**Version audited**: [version]
**Date**: [date]
**Target level**: AA
**Scope**: [full app / specific screens / component]

## Summary

| Metric | Count |
|--------|-------|
| Criteria evaluated | XX |
| Conforming (C) | XX |
| Non-conforming (NC) | XX |
| Not applicable (NA) | XX |
| **Conformance rate** | **XX%** |

## Testing environment

| | iOS | Android |
|---|---|---|
| Device | [model] | [model] |
| OS version | [version] | [version] |
| Screen reader | VoiceOver | TalkBack |
| Other AT | Switch Control, Voice Control | Switch Access, Voice Access |

## Critical issues (must fix)

### Issue 1: [Short title]
- **Criterion**: RAAM X.X (Level A/AA) — [criterion title]
- **EN 301 549**: [norm reference]
- **Platform**: iOS / Android / Both
- **Screen**: [screen name]
- **Location**: [file:line or component]
- **Problem**: [description of the violation]
- **Impact**: [which users are affected and how]
- **Remediation**: [specific fix with code example for affected platform(s)]
- **Priority**: Critical / Major / Minor

## Detailed results by theme

### Theme X: [Name]

| Criterion | Level | iOS | Android | Notes |
|-----------|-------|-----|---------|-------|
| X.1 | A | C/NC/NA | C/NC/NA | [detail] |
| X.2 | AA | C/NC/NA | C/NC/NA | [detail] |

## Recommendations

[Prioritised list of improvements beyond strict compliance]

Severity classification

LevelDescriptionExample
CriticalBlocks access entirely for some usersMissing labels on form fields, keyboard traps, unlabelled buttons
MajorSignificant barrier but workaround existsPoor contrast, missing headings semantics, no complex gesture alternative
MinorInconvenience but does not block accessMissing hint text, imprecise accessible names

When auditing, ALWAYS:

  1. Look up the exact criterion before rendering a verdict — do not rely on memory
  2. Apply the official methodology which has separate iOS and Android steps
  3. Use RAAM criterion numbers (e.g., "RAAM 9.1", not just "WCAG 1.3.1")
  4. Include the EN 301 549 norm reference for cross-reference
  5. Provide platform-specific remediation with code examples (iOS AND Android when both are in scope)
  6. Test both platforms separately — a component may conform on one and fail on the other
  7. Note when code review is insufficient — many criteria require device testing with screen reader (VoiceOver/TalkBack)
  8. Check both orientations — portrait and landscape
  9. Test with enlarged text — set system text size to maximum and verify layout

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Raam Audit AI skill do?

Audit mobile applications (iOS and Android) against RAAM 1.1 (Luxembourg Mobile Accessibility Assessment Framework). Use when reviewing existing mobile app code for accessibility compliance, generating audit reports, checking conformance levels, or preparing for Luxembourg accessibility certification. Covers all 15 themes with platform-specific test procedures. Default target: Level AA.

Why use Raam Audit on TypingMind?

Because you install it once and use it with any model. Raam Audit is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Raam Audit in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/geoffreycrofte/luxembourg-accessibility-skillset/tree/main/raam-audit. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Raam Audit?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Raam Audit?

As many as you like. As long as a model supports skills, you can use Raam Audit with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Raam Audit AI skill free?

Yes. It is published on GitHub by geoffreycrofte under the CC-BY-4.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇