Files
indee-demo/.cursor/rules/accessibility.mdc
Dorian 0bb1bcc5f9 Initial commit: IndeeHub decentralized streaming platform
Built a complete Netflix-style streaming interface for IndeeHub's decentralized media platform with real film content.

Features:
- Vue 3 + TypeScript + Vite setup with hot module reloading
- Netflix-inspired UI with hero section and horizontal scrolling content rows
- Glass morphism design system with custom Tailwind configuration
- 20+ real IndeeHub films organized into 6 categories (Bitcoin, Documentaries, Drama, etc.)
- Full-featured video player component with custom controls
- Mobile-responsive design with bottom navigation
- Nostr integration ready (nostr-tools, relay pool, NIP-71 support)
- Pinia state management for content
- MCP tools configured (Filesystem, Memory, Nostr, Puppeteer)

Components:
- Browse.vue: Main streaming interface with hero and content rows
- ContentRow.vue: Horizontal scrolling film cards with navigation arrows
- VideoPlayer.vue: Custom video player with play/pause, seek, volume, fullscreen
- MobileNav.vue: Bottom tab navigation for mobile devices

Tech Stack:
- Frontend: Vue 3 (Composition API), TypeScript
- Build: Vite 7
- Styling: Tailwind CSS with custom theme
- State: Pinia 3
- Router: Vue Router 4.6
- Protocol: Nostr (nostr-tools 2.22)

Design:
- 4px grid spacing system
- Glass morphism UI components
- Netflix-style hero section with featured content
- Smooth animations and hover effects
- Mobile-first responsive breakpoints
- Dark theme with custom color palette

Content:
- 20+ IndeeHub films with titles, descriptions, categories
- Bitcoin documentaries: God Bless Bitcoin, Dirty Coin, Searching for Satoshi
- Independent films and documentaries
- Working Unsplash CDN images for thumbnails and backdrops

Ready for deployment to Umbrel, Start9, and Archy nodes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-02 22:19:47 +00:00

282 lines
5.0 KiB
Plaintext

---
description: WCAG AA accessibility standards and patterns
alwaysApply: false
globs: **/*.{vue,html,jsx,tsx}
---
# Accessibility Standards (A11y)
## Philosophy
Accessible design is not optional. It's a fundamental requirement for building inclusive, usable applications.
**Target: WCAG AA Compliance**
## Color & Contrast
### Contrast Ratios (WCAG AA)
- **Normal text**: 4.5:1 minimum
- **Large text** (18pt+): 3:1 minimum
- **UI components**: 3:1 minimum
```html
<!-- ✅ Good - High contrast -->
<div class="bg-white text-gray-900">
Readable text with 21:1 ratio
</div>
<!-- ❌ Bad - Low contrast -->
<div class="bg-gray-300 text-gray-400">
Hard to read - only 1.5:1 ratio
</div>
```
### Don't Rely on Color Alone
```html
<!-- ✅ Good - Icon + color + text -->
<span class="text-red-500 flex items-center gap-2">
<svg class="w-4 h-4"><!-- Error icon --></svg>
Error: Invalid input
</span>
```
## Semantic HTML
### Use the Right Elements
```html
<!-- ✅ Good - Semantic -->
<header>
<nav>
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h1>Article Title</h1>
<p>Content...</p>
</article>
</main>
<!-- ❌ Bad - Divitis -->
<div class="header">
<div class="nav">...</div>
</div>
```
### Heading Hierarchy
```html
<!-- ✅ Good - Proper hierarchy -->
<h1>Page Title</h1>
<h2>Section Title</h2>
<h3>Subsection Title</h3>
```
## Keyboard Navigation
### Focus Indicators
**Always show visible focus states.**
```html
<button class="focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2">
Click Me
</button>
<input class="focus:border-primary focus:ring-2 focus:ring-primary-focus" />
```
### Skip Links
```html
<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:z-50">
Skip to main content
</a>
<main id="main-content">
<!-- Main content -->
</main>
```
### Test Keyboard Navigation
- Tab through entire page
- Shift+Tab to go backwards
- Enter/Space to activate buttons
- Escape to close modals/dropdowns
## ARIA (Use Sparingly)
**First rule of ARIA: Don't use ARIA if you can use semantic HTML instead.**
### ARIA Labels
```html
<!-- Button with only icon -->
<button aria-label="Close modal">
<svg><!-- X icon --></svg>
</button>
<!-- Decorative image -->
<img src="decoration.svg" alt="" aria-hidden="true" />
```
### ARIA Live Regions
```html
<!-- Announce status updates -->
<div
role="status"
aria-live="polite"
aria-atomic="true"
class="sr-only"
>
{{ statusMessage }}
</div>
```
## Forms Accessibility
### Label Every Input
```html
<!-- ✅ Good - Explicit label -->
<label for="email">Email Address</label>
<input id="email" type="email" name="email" />
<!-- ❌ Bad - No label -->
<input type="email" placeholder="Email" />
```
### Required Fields
```html
<label for="email">
Email <span class="text-red-500" aria-label="required">*</span>
</label>
<input
id="email"
type="email"
required
aria-required="true"
/>
```
### Error Messages
```html
<input
id="email"
:aria-invalid="hasError"
:aria-describedby="hasError ? 'email-error' : undefined"
/>
<div
v-if="hasError"
id="email-error"
role="alert"
class="text-red-500"
>
Please enter a valid email
</div>
```
## Touch Targets & Mobile
### Minimum Touch Target Size
**WCAG Guideline: 44x44px minimum**
```html
<!-- ✅ Good - Large enough -->
<button class="p-4">
<svg class="w-6 h-6"><!-- Icon --></svg>
</button>
<!-- ❌ Bad - Too small -->
<button class="p-1">
<svg class="w-3 h-3"><!-- Icon --></svg>
</button>
```
### Spacing Between Targets
```html
<!-- ✅ Good - Adequate spacing -->
<nav class="flex flex-col gap-6 md:gap-2">
<a href="/home" class="py-3 md:py-2">Home</a>
</nav>
```
## Motion & Animation
### Respect Prefers-Reduced-Motion
```css
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
```
## Screen Reader Support
### Alt Text for Images
```html
<!-- ✅ Informative image -->
<img src="chart.png" alt="Bar chart showing 25% revenue increase" />
<!-- ✅ Decorative image -->
<img src="decoration.svg" alt="" />
```
### Screen Reader Only Text
```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-width: 0;
}
```
## Accessibility Checklist
### Perceivable
- ✅ Text has sufficient contrast (4.5:1)
- ✅ Images have alt text
- ✅ Color is not the only indicator
- ✅ Content works at 200% zoom
### Operable
- ✅ All functionality keyboard accessible
- ✅ Focus indicators visible
- ✅ No keyboard traps
- ✅ Touch targets at least 44x44px
### Understandable
- ✅ Clear, simple language
- ✅ Labels for all form inputs
- ✅ Error messages are clear
- ✅ Consistent navigation
### Robust
- ✅ Semantic HTML
- ✅ Valid ARIA attributes
- ✅ Works with assistive technologies
**Remember: Accessibility is not a checklist—it's an ongoing commitment to inclusive design.**