Initial skills documentation — 25 categories, all SKILL.md + references + scripts

This commit is contained in:
root
2026-07-15 17:42:20 -04:00
commit 1b4fcd4427
976 changed files with 188344 additions and 0 deletions
@@ -0,0 +1,119 @@
# Web Standards & Accessibility — Ops Portal Checklist
Applied during the July 2026 audit to all 10 ops portal HTML files. Covers HTML5 validity, WCAG 2.1 AA, and ARIA compliance.
## Structural Requirements
### Document-Level
- `<!DOCTYPE html>` (first line)
- `<html lang="en">`
- `<meta charset="UTF-8">` (first element in `<head>`)
- `<meta name="viewport" content="width=device-width, initial-scale=1.0">`
### Semantic Elements
| Element | When to Use |
|---------|-------------|
| `<main id="main-content" role="main">` | One per page, wraps primary content |
| `<header>` | Page header (h1 + actions) |
| `<footer>` | Page footer (last-updated timestamp) |
| `<nav>` / `<nav role="navigation" aria-label="Main navigation">` | Navigation block |
| `<section class="card" aria-labelledby="sectionId">` | Every card/section, paired with `<h2 id="sectionId">` |
| `<h1>``<h2>``<h3>` | Strict hierarchy, no skipping |
### Section Card Pattern (before → after)
**Before (invalid):**
```html
<div class="card">
<div class="card-header">Section Title</div>
...
</div>
```
**After (valid):**
```html
<section class="card" aria-labelledby="myHeading">
<h2 class="card-header" id="myHeading">Section Title</h2>
...
</section>
```
## Accessibility Requirements
### Interactive Elements
- **SVG icons** — all decorative/informational SVGs need:
- `role="img"`
- `aria-label="Refresh"` (or equivalent descriptive text)
- **Error banners** — must have `role="alert"` and `aria-live="polite"`
- **Tables** — every `<th>` must have `scope="col"` (or `scope="row"`)
- **Buttons** — `<button>` elements need accessible text (icon-only buttons need `aria-label`)
- **Navigation toggle** — hamburger button needs `aria-label="Toggle navigation"` and `aria-expanded`
### Color & Contrast
- The dark theme palette passes WCAG AA:
- `--bg-body: #0f172a` / `--text-primary: #f1f5f9` → ratio 15.1:1
- `--accent: #f59e0b` (amber) on `--bg-card: #1e293b` → ratio 7.2:1
- Status colors (green `#22c55e`, red `#ef4444`) used only as supplements, not sole indicators
- Status dots (`.status-dot`) are always paired with text labels
### Focus & Keyboard
- `.refresh-btn:hover` has `border-color: var(--accent)` — also applies `:focus-visible` (browser default)
- `.filter-btn.active` — selection state is conveyed through text (class change + visible count)
- Sortable table headers use `cursor: pointer` and hover highlight — no `:focus` outline removed
### Landmarks
- `<div id="nav">` → nav injected via `fetch('/nav.html')`, already has `role="navigation" aria-label="Main navigation"`
- `<main id="main-content" role="main">` — primary content landmark
- `<header>` — implicit banner landmark
- `<footer>` — implicit contentinfo landmark
## Nav Injection Pattern (Critical)
Inline `<script>` in `nav.html` **does not execute** when the file is loaded via `innerHTML`. Always:
1. **Place nav JS in `/js/utils.js`** as `window.initNav()`
2. **Call `initNav()` after every nav injection:**
```html
fetch('/nav.html')
.then(r => r.text())
.then(html => {
document.getElementById('nav').innerHTML = html;
if (typeof window.initNav === 'function') window.initNav();
})
```
`initNav()` handles:
- Active link highlighting (via `data-path` attribute)
- Hamburger toggle (`aria-expanded` management)
- Click-outside-to-close
## Verification Commands
```bash
# Structural balance check
for section balance:
grep -Pc '<section\b' file.html
grep -c '</section>' file.html
for main balance:
grep -c '<main' file.html
grep -c '</main>' file.html
for h2 balance:
grep -Pc '<h2\b' file.html
grep -c '</h2>' file.html
```
## Common Fixes
| Issue | Fix |
|-------|-----|
| `<div class="card">``<section>` | Change opening to `<section class="card" aria-labelledby="id">`, closing to `</section>` |
| `.card-header``<h2>` | Change `<div class="card-header">` to `<h2 class="card-header" id="id">`, closing to `</h2>` |
| `</div>` should be `</section>` | Convert all section-closing `</div>` to `</section>` |
| SVG missing `role="img"` | Add `role="img"` and `aria-label="..."` |
| Error banner missing ARIA | Add `role="alert" aria-live="polite"` |
| `<th>` missing `scope` | Add `scope="col"` to every `<th>` |
| No `<main>` wrapper | Wrap primary content in `<main id="main-content" role="main">` |
| Inline nav script | Move to `/js/utils.js` as `window.initNav()`, call after injection |