Accessibility Expert
---
name: accessibility-expert
description: Tests and remediates accessibility issues for WCAG compliance and assistive technology compatibility. Use when (1) auditing UI for accessibility violations, (2) implementing keyboard navigation or screen reader support, (3) fixing color contrast or focus indicator issues, (4) ensuring form accessibility and error handling, (5) creating ARIA implementations.
---
# Accessibility Testing and Remediation
## Configuration
- **WCAG Level**: ${wcag_level:AA}
- **Target Component**: ${component_name:Application}
- **Compliance Standard**: ${compliance_standard:WCAG 2.1}
- **Testing Scope**: ${testing_scope:full-audit}
- **Screen Reader**: ${screen_reader:NVDA}
## WCAG 2.1 Quick Reference
### Compliance Levels
| Level | Requirement | Common Issues |
|-------|-------------|---------------|
| A | Minimum baseline | Missing alt text, no keyboard access, missing form labels |
| ${wcag_level:AA} | Standard target | Contrast < 4.5:1, missing focus indicators, poor heading structure |
| AAA | Enhanced | Contrast < 7:1, sign language, extended audio description |
### Four Principles (POUR)
1. **Perceivable**: Content available to senses (alt text, captions, contrast)
2. **Operable**: UI navigable by all input methods (keyboard, touch, voice)
3. **Understandable**: Content and UI predictable and readable
4. **Robust**: Works with current and future assistive technologies
## Violation Severity Matrix
```
CRITICAL (fix immediately):
- No keyboard access to interactive elements
- Missing form labels
- Images without alt text
- Auto-playing audio without controls
- Keyboard traps
HIGH (fix before release):
- Contrast ratio below ${min_contrast_ratio:4.5}:1 (text) or 3:1 (large text)
- Missing skip links
- Incorrect heading hierarchy
- Focus not visible
- Missing error identification
MEDIUM (fix in next sprint):
- Inconsistent navigation
- Missing landmarks
- Poor link text ("click here")
- Missing language attribute
- Complex tables without headers
LOW (backlog):
- Timing adjustments
- Multiple ways to find content
- Context-sensitive help
```
## Testing Decision Tree
```
Start: What are you testing?
|
+-- New Component
| +-- Has interactive elements? --> Keyboard Navigation Checklist
| +-- Has text content? --> Check contrast + heading structure
| +-- Has images? --> Verify alt text appropriateness
| +-- Has forms? --> Form Accessibility Checklist
|
+-- Existing Page/Feature
| +-- Run automated scan first (axe-core, Lighthouse)
| +-- Manual keyboard walkthrough
| +-- Screen reader verification
| +-- Color contrast spot-check
|
+-- Third-party Widget
+-- Check ARIA implementation
+-- Verify keyboard support
+-- Test with screen reader
+-- Document limitations
```
## Keyboard Navigation Checklist
```markdown
[ ] All interactive elements reachable via Tab
[ ] Tab order follows visual/logical flow
[ ] Focus indicator visible (${focus_indicator_width:2}px+ outline, 3:1 contrast)
[ ] No keyboard traps (can Tab out of all elements)
[ ] Skip link as first focusable element
[ ] Enter activates buttons and links
[ ] Space activates checkboxes and buttons
[ ] Arrow keys navigate within components (tabs, menus, radio groups)
[ ] Escape closes modals and dropdowns
[ ] Modals trap focus until dismissed
```
## Screen Reader Testing Patterns
### Essential Announcements to Verify
```
Interactive Elements:
Button: "[label], button"
Link: "[text], link"
Checkbox: "[label], checkbox, [checked/unchecked]"
Radio: "[label], radio button, [selected], [position] of [total]"
Combobox: "[label], combobox, [collapsed/expanded]"
Dynamic Content:
Loading: Use aria-busy="true" on container
Status: Use role="status" for non-critical updates
Alert: Use role="alert" for critical messages
Live regions: aria-live="${aria_live_politeness:polite}"
Forms:
Required: "required" announced with label
Invalid: "invalid entry" with error message
Instructions: Announced with label via aria-describedby
```
### Testing Sequence
1. Navigate entire page with Tab key, listening to announcements
2. Test headings navigation (H key in screen reader)
3. Test landmark navigation (D key / rotor)
4. Test tables (T key, arrow keys within table)
5. Test forms (F key, complete form submission)
6. Test dynamic content updates (verify live regions)
## Color Contrast Requirements
| Text Type | Minimum Ratio | Enhanced (AAA) |
|-----------|---------------|----------------|
| Normal text (<${large_text_threshold:18}pt) | ${min_contrast_ratio:4.5}:1 | 7:1 |
| Large text (>=${large_text_threshold:18}pt or 14pt bold) | 3:1 | 4.5:1 |
| UI components & graphics | 3:1 | N/A |
| Focus indicators | 3:1 | N/A |
### Contrast Check Process
```
1. Identify all foreground/background color pairs
2. Calculate contrast ratio: (L1 + 0.05) / (L2 + 0.05)
where L1 = lighter luminance, L2 = darker luminance
3. Common failures to check:
- Placeholder text (often too light)
- Disabled state (exempt but consider usability)
- Links within text (must distinguish from text)
- Error/success states on colored backgrounds
- Text over images (use overlay or text shadow)
```
## ARIA Implementation Guide
### First Rule of ARIA
Use native HTML elements when possible. ARIA is for custom widgets only.
```html
<!-- WRONG: ARIA on native element -->
<div role="button" tabindex="0">Submit</div>
<!-- RIGHT: Native button -->
<button type="submit">Submit</button>
```
### When ARIA is Needed
```html
<!-- Custom tabs -->
<div role="tablist">
<button role="tab" aria-selected="true" aria-controls="panel1">Tab 1</button>
<button role="tab" aria-selected="false" aria-controls="panel2">Tab 2</button>
</div>
<div role="tabpanel" id="panel1">Content 1</div>
<div role="tabpanel" id="panel2" hidden>Content 2</div>
<!-- Expandable section -->
<button aria-expanded="false" aria-controls="content">Show details</button>
<div id="content" hidden>Expandable content</div>
<!-- Modal dialog -->
<div role="dialog" aria-modal="true" aria-labelledby="title">
<h2 id="title">Dialog Title</h2>
<!-- content -->
</div>
<!-- Live region for dynamic updates -->
<div aria-live="${aria_live_politeness:polite}" aria-atomic="true">
<!-- Status messages injected here -->
</div>
```
### Common ARIA Mistakes
```
- role="button" without keyboard support (Enter/Space)
- aria-label duplicating visible text
- aria-hidden="true" on focusable elements
- Missing aria-expanded on disclosure buttons
- Incorrect aria-controls reference
- Using aria-describedby for essential information
```
## Form Accessibility Patterns
### Required Form Structure
```html
<form>
<!-- Explicit label association -->
<label for="email">Email address</label>
<input type="email" id="email" name="email"
aria-required="true"
aria-describedby="email-hint email-error">
<span id="email-hint">We'll never share your email</span>
<span id="email-error" role="alert"></span>
<!-- Group related fields -->
<fieldset>
<legend>Shipping address</legend>
<!-- address fields -->
</fieldset>
<!-- Clear submit button -->
<button type="submit">Complete order</button>
</form>
```
### Error Handling Requirements
```
1. Identify the field in error (highlight + icon)
2. Describe the error in text (not just color)
3. Associate error with field (aria-describedby)
4. Announce error to screen readers (role="alert")
5. Move focus to first error on submit failure
6. Provide correction suggestions when possible
```
## Mobile Accessibility Checklist
```markdown
Touch Targets:
[ ] Minimum ${touch_target_size:44}x${touch_target_size:44} CSS pixels
[ ] Adequate spacing between targets (${touch_target_spacing:8}px+)
[ ] Touch action not dependent on gesture path
Gestures:
[ ] Alternative to multi-finger gestures
[ ] Alternative to path-based gestures (swipe)
[ ] Motion-based actions have alternatives
Screen Reader (iOS/Android):
[ ] accessibilityLabel set for images and icons
[ ] accessibilityHint for complex interactions
[ ] accessibilityRole matches element behavior
[ ] Focus order follows visual layout
```
## Automated Testing Integration
### Pre-commit Hook
```bash
#!/bin/bash
# Run axe-core on changed files
npx axe-core-cli --exit src/**/*.html
# Check for common issues
grep -r "onClick.*div\|onClick.*span" src/ && \
echo "Warning: Click handler on non-interactive element" && exit 1
```
### CI Pipeline Checks
```yaml
accessibility-audit:
script:
- npx pa11y-ci --config .pa11yci.json
- npx lighthouse --accessibility --output=json
artifacts:
paths:
- accessibility-report.json
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
```
### Minimum CI Thresholds
```
axe-core: 0 critical violations, 0 serious violations
Lighthouse accessibility: >= ${lighthouse_a11y_threshold:90}
pa11y: 0 errors (warnings acceptable)
```
## Remediation Priority Framework
```
Priority 1 (This Sprint):
- Blocks user task completion
- Legal compliance risk
- Affects many users
Priority 2 (Next Sprint):
- Degrades experience significantly
- Automated tools flag as error
- Violates ${wcag_level:AA} requirement
Priority 3 (Backlog):
- Minor inconvenience
- Violates AAA only
- Affects edge cases
Priority 4 (Enhancement):
- Improves usability for all
- Best practice, not requirement
- Future-proofing
```
## Verification Checklist
Before marking accessibility work complete:
```markdown
Automated:
[ ] axe-core: 0 violations
[ ] Lighthouse accessibility: ${lighthouse_a11y_threshold:90}+
[ ] HTML validation passes
[ ] No console accessibility warnings
Keyboard:
[ ] Complete all tasks keyboard-only
[ ] Focus visible at all times
[ ] Tab order logical
[ ] No keyboard traps
Screen Reader (test with at least one):
[ ] All content announced
[ ] Interactive elements labeled
[ ] Errors and updates announced
[ ] Navigation efficient
Visual:
[ ] All text passes contrast
[ ] UI components pass contrast
[ ] Works at ${zoom_level:200}% zoom
[ ] Works in high contrast mode
[ ] No seizure-inducing flashing
Forms:
[ ] All fields labeled
[ ] Errors identifiable
[ ] Required fields indicated
[ ] Instructions available
```
## Documentation Template
```markdown
# Accessibility Statement
## Conformance Status
This [website/application] is [fully/partially] conformant with ${compliance_standard:WCAG 2.1} Level ${wcag_level:AA}.
## Known Limitations
| Feature | Issue | Workaround | Timeline |
|---------|-------|------------|----------|
| [Feature] | [Description] | [Alternative] | [Fix date] |
## Assistive Technology Tested
- ${screen_reader:NVDA} [version] with Firefox [version]
- VoiceOver with Safari [version]
- JAWS [version] with Chrome [version]
## Feedback
Contact [email] for accessibility issues.
Last updated: [date]
```
Accessibility Testing Superpower
---
name: accessibility-testing-superpower
description: |
Performs WCAG compliance audits and accessibility remediation for web applications.
Use when: 1) Auditing UI for WCAG 2.1/2.2 compliance 2) Fixing screen reader or keyboard navigation issues 3) Implementing ARIA patterns correctly 4) Reviewing color contrast and visual accessibility 5) Creating accessible forms or interactive components
---
# Accessibility Testing Workflow
## Configuration
- **WCAG Level**: ${wcag_level:AA}
- **Component Under Test**: ${component_name:Page}
- **Compliance Standard**: ${compliance_standard:WCAG 2.1}
- **Minimum Lighthouse Score**: ${lighthouse_score:90}
- **Primary Screen Reader**: ${screen_reader:NVDA}
- **Test Framework**: ${test_framework:jest-axe}
## Audit Decision Tree
```
Accessibility request received
|
+-- New component/page?
| +-- Run automated scan first (axe-core, Lighthouse)
| +-- Keyboard navigation test
| +-- Screen reader announcement check
| +-- Color contrast verification
|
+-- Existing violation to fix?
| +-- Identify WCAG success criterion
| +-- Check if semantic HTML solves it
| +-- Apply ARIA only when HTML insufficient
| +-- Verify fix with assistive technology
|
+-- Compliance audit?
+-- Automated scan (catches ~30% of issues)
+-- Manual testing checklist
+-- Document violations by severity
+-- Create remediation roadmap
```
## WCAG Quick Reference
### Severity Classification
| Severity | Impact | Examples | Fix Timeline |
|----------|--------|----------|--------------|
| Critical | Blocks access entirely | No keyboard focus, empty buttons, missing alt on functional images | Immediate |
| Serious | Major barriers | Poor contrast, missing form labels, no skip links | Within sprint |
| Moderate | Difficult but usable | Inconsistent navigation, unclear error messages | Next release |
| Minor | Inconvenience | Redundant alt text, minor heading order issues | Backlog |
### Common Violations and Fixes
**Missing accessible name**
```html
<!-- Violation -->
<button><svg>...</svg></button>
<!-- Fix: aria-label -->
<button aria-label="Close dialog"><svg>...</svg></button>
<!-- Fix: visually hidden text -->
<button><span class="sr-only">Close dialog</span><svg>...</svg></button>
```
**Form label association**
```html
<!-- Violation -->
<label>Email</label>
<input type="email">
<!-- Fix: explicit association -->
<label for="email">Email</label>
<input type="email" id="email">
<!-- Fix: implicit association -->
<label>Email <input type="email"></label>
```
**Color contrast failure**
```
Minimum ratios (WCAG ${wcag_level:AA}):
- Normal text (<${large_text_size:18}px or <${bold_text_size:14}px bold): ${contrast_ratio_normal:4.5}:1
- Large text (>=${large_text_size:18}px or >=${bold_text_size:14}px bold): ${contrast_ratio_large:3}:1
- UI components and graphics: 3:1
Tools: WebAIM Contrast Checker, browser DevTools
```
**Focus visibility**
```css
/* Never do this without alternative */
:focus { outline: none; }
/* Proper custom focus */
:focus-visible {
outline: ${focus_outline_width:2}px solid ${focus_outline_color:#005fcc};
outline-offset: ${focus_outline_offset:2}px;
}
```
## ARIA Decision Framework
```
Need to convey information to assistive technology?
|
+-- Can semantic HTML do it?
| +-- YES: Use HTML (<button>, <nav>, <main>, <article>)
| +-- NO: Continue to ARIA
|
+-- What type of ARIA needed?
+-- Role: What IS this element? (role="dialog", role="tab")
+-- State: What condition? (aria-expanded, aria-checked)
+-- Property: What relationship? (aria-labelledby, aria-describedby)
+-- Live region: Dynamic content? (aria-live="${aria_live_mode:polite}")
```
### ARIA Patterns for Common Widgets
**Disclosure (show/hide)**
```html
<button aria-expanded="false" aria-controls="content-1">
Show details
</button>
<div id="content-1" hidden>
Content here
</div>
```
**Tab interface**
```html
<div role="tablist" aria-label="${component_name:Settings}">
<button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1">
General
</button>
<button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2" tabindex="-1">
Privacy
</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">...</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>...</div>
```
**Modal dialog**
```html
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
<h2 id="dialog-title">Confirm action</h2>
<p>Are you sure you want to proceed?</p>
<button>Cancel</button>
<button>Confirm</button>
</div>
```
## Keyboard Navigation Checklist
```
[ ] All interactive elements focusable with Tab
[ ] Focus order matches visual/logical order
[ ] Focus visible on all elements
[ ] No keyboard traps (can always Tab out)
[ ] Skip link as first focusable element
[ ] Escape closes modals/dropdowns
[ ] Arrow keys navigate within widgets (tabs, menus, grids)
[ ] Enter/Space activates buttons and links
[ ] Custom shortcuts documented and configurable
```
### Focus Management Patterns
**Modal focus trap**
```javascript
// On modal open:
// 1. Save previously focused element
// 2. Move focus to first focusable in modal
// 3. Trap Tab within modal boundaries
// On modal close:
// 1. Return focus to saved element
```
**Dynamic content**
```javascript
// After adding content:
// - Announce via aria-live region, OR
// - Move focus to new content heading
// After removing content:
// - Move focus to logical next element
// - Never leave focus on removed element
```
## Screen Reader Testing
### Announcement Verification
| Element | Should Announce |
|---------|-----------------|
| Button | Role + name + state ("Submit button") |
| Link | Name + "link" ("Home page link") |
| Image | Alt text OR "decorative" (skip) |
| Heading | Level + text ("Heading level 2, About us") |
| Form field | Label + type + state + instructions |
| Error | Error message + field association |
### Testing Commands (Quick Reference)
**VoiceOver (macOS)**
- VO = Ctrl + Option
- VO + A: Read all
- VO + Right/Left: Navigate elements
- VO + Cmd + H: Next heading
- VO + Cmd + J: Next form control
**${screen_reader:NVDA} (Windows)**
- NVDA + Down: Read all
- Tab: Next focusable
- H: Next heading
- F: Next form field
- B: Next button
## Automated Testing Integration
### axe-core in tests
```javascript
// ${test_framework:jest-axe}
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('${component_name:component} is accessible', async () => {
const { container } = render(<${component_name:MyComponent} />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
```
### Lighthouse CI threshold
```javascript
// lighthouserc.js
module.exports = {
assertions: {
'categories:accessibility': ['error', { minScore: ${lighthouse_score:90} / 100 }],
},
};
```
## Remediation Priority Matrix
```
Impact vs Effort:
Low Effort High Effort
High Impact | DO FIRST | PLAN NEXT |
| alt text | redesign |
| labels | nav rebuild |
----------------|--------------|---------------|
Low Impact | QUICK WIN | BACKLOG |
| contrast | nice-to-have|
| tweaks | enhancements|
```
## Verification Checklist
Before marking accessibility work complete:
```
Automated Testing:
[ ] axe-core reports zero violations
[ ] Lighthouse accessibility >= ${lighthouse_score:90}
[ ] HTML validator passes (affects AT parsing)
Keyboard Testing:
[ ] Full task completion without mouse
[ ] Visible focus at all times
[ ] Logical tab order
[ ] No traps
Screen Reader Testing:
[ ] Tested with at least one screen reader (${screen_reader:NVDA})
[ ] All content announced correctly
[ ] Interactive elements have roles/states
[ ] Dynamic updates announced
Visual Testing:
[ ] Contrast ratios verified (${contrast_ratio_normal:4.5}:1 minimum)
[ ] Works at ${zoom_level:200}% zoom
[ ] No information conveyed by color alone
[ ] Respects prefers-reduced-motion
```
Commit Message Preparation
# Git Commit Guidelines for AI Language Models
## Core Principles
1. **Follow Conventional Commits** (https://www.conventionalcommits.org/)
2. **Be concise and precise** - No flowery language, superlatives, or unnecessary adjectives
3. **Focus on WHAT changed, not HOW it works** - Describe the change, not implementation details
4. **One logical change per commit** - Split related but independent changes into separate commits
5. **Write in imperative mood** - "Add feature" not "Added feature" or "Adds feature"
6. **Always include body text** - Never use subject-only commits
## Commit Message Structure
```
<type>(<scope>): <subject>
<body>
<footer>
```
### Type (Required)
- `feat`: New feature
- `fix`: Bug fix
- `refactor`: Code change that neither fixes a bug nor adds a feature
- `perf`: Performance improvement
- `style`: Code style changes (formatting, missing semicolons, etc.)
- `test`: Adding or updating tests
- `docs`: Documentation changes
- `build`: Build system or external dependencies (npm, gradle, Xcode, SPM)
- `ci`: CI/CD pipeline changes
- `chore`: Routine tasks (gitignore, config files, maintenance)
- `revert`: Revert a previous commit
### Scope (Optional but Recommended)
Indicates the area of change: `auth`, `ui`, `api`, `db`, `i18n`, `analytics`, etc.
### Subject (Required)
- **Max 50 characters**
- **Lowercase first letter** (unless it's a proper noun)
- **No period at the end**
- **Imperative mood**: "add" not "added" or "adds"
- **Be specific**: "add email validation" not "add validation"
### Body (Required)
- **Always include body text** - Minimum 1 sentence
- **Explain WHAT changed and WHY** - Provide context
- **Wrap at 72 characters**
- **Separate from subject with blank line**
- **Use bullet points for multiple changes** (use `-` or `*`)
- **Reference issue numbers** if applicable
- **Mention specific classes/functions/files when relevant**
### Footer (Optional)
- **Breaking changes**: `BREAKING CHANGE: <description>`
- **Issue references**: `Closes #123`, `Fixes #456`
- **Co-authors**: `Co-Authored-By: Name <email>`
## Banned Words & Phrases
**NEVER use these words** (they're vague, subjective, or exaggerated):
❌ Comprehensive
❌ Robust
❌ Enhanced
❌ Improved (unless you specify what metric improved)
❌ Optimized (unless you specify what metric improved)
❌ Better
❌ Awesome
❌ Great
❌ Amazing
❌ Powerful
❌ Seamless
❌ Elegant
❌ Clean
❌ Modern
❌ Advanced
## Good vs Bad Examples
### ❌ BAD (No body)
```
feat(auth): add email/password login
```
**Problems:**
- No body text
- Doesn't explain what was actually implemented
### ❌ BAD (Vague body)
```
feat: Add awesome new login feature
This commit adds a powerful new login system with robust authentication
and enhanced security features. The implementation is clean and modern.
```
**Problems:**
- Subjective adjectives (awesome, powerful, robust, enhanced, clean, modern)
- Doesn't specify what was added
- Body describes quality, not functionality
### ✅ GOOD
```
feat(auth): add email/password login with Firebase
Implement login flow using Firebase Authentication. Users can now sign in
with email and password. Includes client-side email validation and error
handling for network failures and invalid credentials.
```
**Why it's good:**
- Specific technology mentioned (Firebase)
- Clear scope (auth)
- Body describes what functionality was added
- Explains what error handling covers
---
### ❌ BAD (No body)
```
fix(auth): prevent login button double-tap
```
**Problems:**
- No body text explaining the fix
### ✅ GOOD
```
fix(auth): prevent login button double-tap
Disable login button after first tap to prevent duplicate authentication
requests when user taps multiple times quickly. Button re-enables after
authentication completes or fails.
```
**Why it's good:**
- Imperative mood
- Specific problem described
- Body explains both the issue and solution approach
---
### ❌ BAD
```
refactor(auth): extract helper functions
Make code better and more maintainable by extracting functions.
```
**Problems:**
- Subjective (better, maintainable)
- Not specific about which functions
### ✅ GOOD
```
refactor(auth): extract helper functions to static struct methods
Convert private functions randomNonceString and sha256 into static methods
of AppleSignInHelper struct for better code organization and namespacing.
```
**Why it's good:**
- Specific change described
- Mentions exact function names
- Body explains reasoning and new structure
---
### ❌ BAD
```
feat(i18n): add localization
```
**Problems:**
- No body
- Too vague
### ✅ GOOD
```
feat(i18n): add English and Turkish translations for login screen
Create String Catalog with translations for login UI elements, alerts,
and authentication errors in English and Turkish. Covers all user-facing
strings in LoginView, LoginViewController, and AuthService.
```
**Why it's good:**
- Specific languages mentioned
- Clear scope (i18n)
- Body lists what was translated and which files
---
## Multi-File Commit Guidelines
### When to Split Commits
Split changes into separate commits when:
1. **Different logical concerns**
- ✅ Commit 1: Add function
- ✅ Commit 2: Add tests for function
2. **Different scopes**
- ✅ Commit 1: `feat(ui): add button component`
- ✅ Commit 2: `feat(api): add endpoint for button action`
3. **Different types**
- ✅ Commit 1: `feat(auth): add login form`
- ✅ Commit 2: `refactor(auth): extract validation logic`
### When to Combine Commits
Combine changes in one commit when:
1. **Tightly coupled changes**
- ✅ Adding a function and its usage in the same component
2. **Atomic change**
- ✅ Refactoring function name across multiple files
3. **Breaking without each other**
- ✅ Adding interface and its implementation together
## File-Level Commit Strategy
### Example: LoginView Changes
If LoginView has 2 independent changes:
**Change 1:** Refactor stack view structure
**Change 2:** Add loading indicator
**Split into 2 commits:**
```
refactor(ui): extract content stack view as property in login view
Change inline stack view initialization to property-based approach for
better code organization and reusability. Moves stack view definition
from setupUI method to lazy property.
```
```
feat(ui): add loading state with activity indicator to login view
Add loading indicator overlay and setLoading method to disable user
interaction and dim content during authentication. Content alpha reduces
to 0.5 when loading.
```
## Localization-Specific Guidelines
### ✅ GOOD
```
feat(i18n): add English and Turkish translations
Create String Catalog (Localizable.xcstrings) with English and Turkish
translations for all login screen strings, error messages, and alerts.
```
```
build(i18n): add Turkish localization support
Add Turkish language to project localizations and enable String Catalog
generation (SWIFT_EMIT_LOC_STRINGS) in build settings for Debug and
Release configurations.
```
```
feat(i18n): localize login view UI elements
Replace hardcoded strings with NSLocalizedString in LoginView for title,
subtitle, labels, placeholders, and button titles. All user-facing text
now supports localization.
```
### ❌ BAD
```
feat: Add comprehensive multi-language support
Add awesome localization system to the app.
```
```
feat: Add translations
```
## Breaking Changes
When introducing breaking changes:
```
feat(api): change authentication response structure
Authentication endpoint now returns user object in 'data' field instead
of root level. This allows for additional metadata in the response.
BREAKING CHANGE: Update all API consumers to access response.data.user
instead of response.user.
Migration guide:
- Before: const user = response.user
- After: const user = response.data.user
```
## Commit Ordering
When preparing multiple commits, order them logically:
1. **Dependencies first**: Add libraries/configs before usage
2. **Foundation before features**: Models before views
3. **Build before source**: Build configs before code changes
4. **Utilities before consumers**: Helpers before components that use them
### Example Order:
```
1. build(auth): add Sign in with Apple entitlement
Add entitlements file with Sign in with Apple capability for enabling
Apple ID authentication.
2. feat(auth): add Apple Sign-In cryptographic helpers
Add utility functions for generating random nonce and SHA256 hashing
required for Apple Sign-In authentication flow.
3. feat(auth): add Apple Sign-In authentication to AuthService
Add signInWithApple method to AuthService protocol and implementation.
Uses OAuthProvider credential with idToken and nonce for Firebase
authentication.
4. feat(auth): add Apple Sign-In flow to login view model
Implement loginWithApple method in LoginViewModel to handle Apple
authentication with idToken, nonce, and fullName.
5. feat(auth): implement Apple Sign-In authorization flow
Add ASAuthorizationController delegate methods to handle Apple Sign-In
authorization, credential validation, and error handling.
```
## Special Cases
### Configuration Files
```
chore: ignore GoogleService-Info.plist from version control
Add GoogleService-Info.plist to .gitignore to prevent committing Firebase
configuration with API keys.
```
```
build: update iOS deployment target to 15.0
Change minimum iOS version from 14.0 to 15.0 to support async/await syntax
in authentication flows.
```
```
ci: add GitHub Actions workflow for testing
Add workflow to run unit tests on pull requests. Runs on macOS latest
with Xcode 15.
```
### Documentation
```
docs: add API authentication guide
Document Firebase Authentication setup process, including Google Sign-In
and Apple Sign-In configuration steps.
```
```
docs: update README with installation steps
Add SPM dependency installation instructions and Firebase setup guide.
```
### Refactoring
```
refactor(auth): convert helper functions to static struct methods
Wrap Apple Sign-In helper functions in AppleSignInHelper struct with
static methods for better code organization and namespacing. Converts
randomNonceString and sha256 from private functions to static methods.
```
```
refactor(ui): extract email validation to separate method
Move email validation regex logic from loginWithEmail to isValidEmail
method for reusability and testability.
```
### Performance
**Specify the improvement:**
❌ `perf: optimize login`
✅
```
perf(auth): reduce login request time from 2s to 500ms
Add request caching for Firebase configuration to avoid repeated network
calls. Configuration is now cached after first retrieval.
```
## Body Text Requirements
**Minimum requirements for body text:**
1. **At least 1-2 complete sentences**
2. **Describe WHAT was changed specifically**
3. **Explain WHY the change was needed (when not obvious)**
4. **Mention affected components/files when relevant**
5. **Include technical details that aren't obvious from subject**
### Good Body Examples:
```
Add loading indicator overlay and setLoading method to disable user
interaction and dim content during authentication.
```
```
Update signInWithApple method to accept fullName parameter and use
appleCredential for proper user profile creation in Firebase.
```
```
Replace hardcoded strings with NSLocalizedString in LoginView for title,
labels, placeholders, and buttons. All UI text now supports English and
Turkish translations.
```
### Bad Body Examples:
❌ `Add feature.` (too vague)
❌ `Updated files.` (doesn't explain what)
❌ `Bug fix.` (doesn't explain which bug)
❌ `Refactoring.` (doesn't explain what was refactored)
## Template for AI Models
When an AI model is asked to create commits:
```
1. Read git diff to understand ALL changes
2. Group changes by logical concern
3. Order commits by dependency
4. For each commit:
- Choose appropriate type and scope
- Write specific, concise subject (max 50 chars)
- Write detailed body (minimum 1-2 sentences, required)
- Use imperative mood
- Avoid banned words
- Focus on WHAT changed and WHY
5. Output format:
## Commit [N]
**Title:**
```
type(scope): subject
```
**Description:**
```
Body text explaining what changed and why. Mention specific
components, classes, or methods affected. Provide context.
```
**Files to add:**
```bash
git add path/to/file
```
```
## Final Checklist
Before suggesting a commit, verify:
- [ ] Type is correct (feat/fix/refactor/etc.)
- [ ] Scope is specific and meaningful
- [ ] Subject is imperative mood
- [ ] Subject is ≤50 characters
- [ ] **Body text is present (required)**
- [ ] **Body has at least 1-2 complete sentences**
- [ ] Body explains WHAT and WHY
- [ ] No banned words used
- [ ] No subjective adjectives
- [ ] Specific about WHAT changed
- [ ] Mentions affected components/files
- [ ] One logical change per commit
- [ ] Files grouped correctly
---
## Example Commit Message (Complete)
```
feat(auth): add email validation to login form
Implement client-side email validation using regex pattern before sending
authentication request. Validates format matches standard email pattern
(user@domain.ext) and displays error message for invalid inputs. Prevents
unnecessary Firebase API calls for malformed emails.
```
**What makes this good:**
- Clear type and scope
- Specific subject
- Body explains what validation does
- Body explains why it's needed
- Mentions the benefit (prevents API calls)
- No banned words
- Imperative mood throughout
---
**Remember:** A good commit message should allow someone to understand the change without looking at the diff. Be specific, be concise, be objective, and always include meaningful body text.
Cyberscam Survival Simulator
# Cyberscam Survival Simulator
Certification & Progression Extension
Author: Scott M
Version: 1.3.1 – Visual-Enhanced Consumer Polish
Last Modified: 2026-02-13
## Purpose of v1.3.1
Build on v1.3.0 standalone consumer enjoyment: low-stress fun, hopeful daily habit-building, replayable without pressure.
Add safe, educational visual elements (real-world scam example screenshots from reputable sources) to increase realism, pattern recognition, and engagement — especially for mixed-reality, multi-turn, and Endless Mode scenarios.
Maintain emphasis on personal growth, light warmth/humor (toggleable), family/guest modes, and endless mode after mastery.
Strictly avoid enterprise features (no risk scores, leaderboards, mandatory quotas, compliance tracking).
## Core Rules – Retained & Reinforced
### Persistence & Tracking
- All progress saved per user account, persists across sessions/devices.
- Incomplete scenarios do not count.
- Optional local-only Guest Mode (no save, quick family/friend sessions; provisional/certifications marked until account-linked).
### Scenario Counting Rules
- Scenarios must be unique within a level’s requirement set unless tagged “Replayable for Practice” (max 20% of required count per level).
- Single scenario may count toward multiple levels if it meets criteria for each.
- Internal “used for level X” flag prevents double-dipping within same level.
- At least 70% of scenarios for any level from different templates/pools (anti-cherry-picking).
### Visual Element Integration (New in v1.3.1)
- Display safe, anonymized educational screenshots (emails, texts, websites) from reputable sources (university IT/security pages, FTC, CISA, IRS scam reports, etc.).
- Images must be:
- Publicly shared for awareness/education purposes
- Redacted (blurred personal info, fake/inactive domains)
- Non-clickable (static display only)
- Framed as safe training examples
- Usage guidelines:
- 50–80% of scenarios in Levels 2–5 and Endless Mode include a visual
- Level 1: optional / lighter usage (focus on basic awareness)
- Higher levels: mandatory for mixed-reality and multi-turn scenarios
- Endless Mode: randomized visual pulls for variety
- UI presentation: high-contrast, zoomable pop-up cards or inline images; “Inspect” hotspots reveal red-flag hints (e.g., mismatched URL, urgency language).
- Accessibility: alt text, voice-over friendly descriptions; toggle to text-only mode.
- Offline fallback: small cached set of static example images.
- No dynamic fetching of live malicious content; no tracking pixels.
### Key Term Definitions (Glossary) – Unchanged
- Catastrophic failure: Shares credentials, downloads/clicks malicious payload, sends money, grants remote access.
- Blindly trust branding alone: Proceeds based only on logo/domain/sender name without secondary check.
- Verification via known channel: Uses second pre-trusted method (call known number, separate app/site login, different-channel colleague check).
- Explicitly resists escalation: Chooses de-escalate/question/exit option under pressure.
- Sunk-cost behavior: Continues after red flags due to prior investment.
- Mixed-reality scenarios: Include both legitimate and fraudulent messages (player distinguishes).
- Prompt (verification avoidance): In-game hint/pop-up (e.g., “This looks urgent—want to double-check?”) after suspicious action/inaction.
### Disqualifier Reset & Forgiveness – Unchanged
- Disqualifiers reset after earning current level.
- Level 5 over-avoidance resets after 2 successful legitimate-message handles.
- One “learning grace” per level: first disqualifier triggers gentle reflection (not block).
### Anti-Gaming & Anti-Paranoia Safeguards – Unchanged
- Minimal unique scenario requirement (70% diversity).
- Over-cautious path: ≥3 legit blocks/reports unlocks “Balanced Re-entry” mini-scenarios (low-stakes legit interactions); 2 successes halve over-avoidance counter.
- No certification if <50% of available scenario pool completed.
## Certification Levels – Visual Integration Notes Added
### 🟢 Level 1: Digital Street Smart (Awareness & Pausing)
- Complete ≥4 unique scenarios.
- ≥3 scenarios: ≥1 pause/inspection before click/reply/forward.
- Avoid catastrophic failure in ≥3/4.
- No disqualifiers (forgiving start).
- Visuals: Optional / introductory (simple email/text examples).
### 🔵 Level 2: Verification Ready (Checking Without Freezing)
- Complete ≥5 unique scenarios after Level 1.
- ≥3 scenarios: independent verification (known channel/separate lookup).
- Blindly trusts branding alone in ≤1 scenario.
- Disqualifier: 3+ ignored verification prompts (resets on unlock).
- Visuals: Required for most; focus on branding/links (e.g., fake PayPal/Amazon).
### 🟣 Level 3: Social Engineering Aware (Emotional Intelligence)
- Complete ≥5 unique emotional-trigger scenarios (urgency/fear/authority/greed/pity).
- ≥3 scenarios: delays response AND avoids oversharing.
- Explicitly resists escalation ≥1 time.
- Disqualifier: Escalates emotional interaction w/o verification ≥3 times (resets).
- Visuals: Required; show urgency/fear triggers (e.g., “account locked”, “package fee”).
### 🟠 Level 4: Long-Game Resistant (Pattern Recognition)
- Complete ≥2 unique multi-interaction scenarios (≥3 turns).
- ≥1: identifies drift OR safely exits before high-risk.
- Avoids sunk-cost continuation ≥1 time.
- Disqualifier: Continues after clear drift ≥2 times.
- Visuals: Mandatory; threaded messages showing gradual escalation.
### 🔴 Level 5: Balanced Skeptic (Judgment, Not Fear)
- Complete ≥5 unique mixed-reality scenarios.
- Correctly handles ≥2 legitimate (appropriate response) + ≥2 scams (pause/verify/exit).
- Over-avoidance counter <3.
- Disqualifier: Persistent over-avoidance ≥3 (mitigated by Balanced Re-entry).
- Visuals: Mandatory; mix of legit and fraudulent examples side-by-side or threaded.
## Certification Reveal Moments – Unchanged
(Short, affirming, 2–3 sentences; optional Chill Mode one-liner)
## Post-Mastery: Endless Mode – Enhanced with Visuals
- “Scam Surf” sessions: 3–5 randomized quick scenarios with visuals (no new certs).
- Streaks & Cosmetic Badges unchanged.
- Private “Scam Journal” unchanged.
## Humor & Warmth Layer (Optional Toggle: Chill Mode) – Unchanged
(Witty narration, gentle roasts, dad-joke level)
## Real-Life "Win" Moments – Unchanged
## Family / Shared Play Vibes – Unchanged
## Minimal Visual / Audio Polish – Expanded
- Audio: Calm lo-fi during pauses; upbeat “aha!” sting on smart choices (toggleable).
- UI: Friendly cartoon scam-villain mascots (goofy, not scary); green checkmarks.
- New: Educational screenshot display (high-contrast, zoomable, inspect hotspots).
- Accessibility: High-contrast, larger text, voice-over friendly, text-only fallback toggle.
## Avoid Enterprise Traps – Unchanged
## Progress Visibility Rules – Unchanged
## End-of-Session Summary – Unchanged
## Accessibility & Localization Notes – Unchanged
## Appendix: Sample Visual Cue Examples (Implementation Reference)
These are safe, educational examples drawn from public sources (FTC, university IT pages, awareness sites). Use as static, redacted images with "Inspect" hotspots revealing red flags. Pair with Chill Mode narration for warmth.
### Level 1 Examples
- Fake Netflix phishing email: Urgent "Account on hold – update payment" with mismatched sender domain (e.g., netf1ix-support.com). Hotspot: "Sender doesn't match netflix.com!"
- Generic security alert email: Plain text claiming "Verify login" from spoofed domain.
### Level 2 Examples
- Fake PayPal email: Mimics layout/logo but link hovers to non-PayPal domain (e.g., paypal-secure-random.com). Hotspot: "Branding looks good, but domain is off—verify separately!"
- Spoofed bank alert: "Suspicious activity – click to verify" with mismatched footer links.
### Level 3 Examples
- Urgent package smishing text: "Your package is held – pay fee now" with short link (e.g., tinyurl variant). Hotspot: "Urgency + unsolicited fee = classic pressure tactic!"
- Fake authority/greed trigger: "IRS refund" or "You've won a prize!" pushing quick action.
### Level 4 Examples
- Threaded drift: 3–4 messages starting legit (e.g., job offer), escalating to "Send gift cards" or risky links. Hotspot on later turns: "Drift detected—started normal, now high-risk!"
### Level 5 Examples
- Side-by-side legit vs. fake: Real Netflix confirmation next to phishing clone (subtle domain hyphen or urgency added). Helps practice balanced judgment.
- Mixed legit/fake combo: Normal delivery update drifting into payment request.
### Endless Mode
- Randomized pulls from above (e.g., IRS text, Amazon phish, bank alert) for quick variety.
All visuals credited lightly (e.g., "Inspired by FTC consumer advice examples") and framed as safe simulations only.
## Changelog
- v1.3.1: Added safe educational visual integration (screenshots from reputable sources), visual usage guidelines by level, UI polish for images, offline fallback, text-only toggle, plus appendix with sample visual cue examples.
- v1.3.0: Added Endless Mode, Chill Mode humor, real-life wins, Guest/family play, audio/visual polish; reinforced consumer boundaries.
- v1.2.1: Persistence, unique/overlaps, glossary, forgiveness, anti-gaming, Balanced Re-entry.
- v1.2.0: Initial certification system.
- v1.1.0 / v1.0.0: Core loop foundations.