skills/design-justice/SKILL.md
Digital equity and trauma-informed design for marginalized populations. Activate on "accessibility", "offline-first", "trauma-informed", "reentry", "recovery population", "shared device", "unstable phone", "digital equity", "design justice", "low-literacy", "intermittent access". NOT for general UX, marketing optimization, or enterprise SaaS design.
npx skillsauth add curiositech/windags-skills design-justiceInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Design for the margins, benefit the center. If it works for someone with no stable phone, unstable housing, trauma history, and low digital literacy → it works better for everyone.
Design Justice (Sasha Costanza-Chock) + Trauma-Informed Design + Digital Equity Design
Core principle: The people most impacted by design decisions should be centered in the design process, not treated as edge cases.
✅ Use for:
❌ NOT for:
User has unstable phone number?
├── YES → See: Authentication Without Stable Phones
└── NO → Standard auth OK
User may lose internet mid-task?
├── YES → See: Offline-First Design
└── NO → Standard web patterns OK
User may be on shared/public device?
├── YES → See: Shared Device Privacy
└── NO → Standard session management OK
Form is complex or emotionally difficult?
├── YES → See: Trauma-Informed Forms
└── NO → Standard form patterns OK
User has history of system trauma?
├── YES → Apply ALL trauma-informed patterns
└── UNKNOWN → Assume YES for civic/legal/benefits apps
Novice thinking: "Everyone has a phone, SMS 2FA is secure"
Reality:
Timeline:
| Need | Pattern | Implementation | |------|---------|----------------| | Primary auth | Email-first | Email is identifier, phone optional | | 2FA | Multiple pathways | Email OR backup codes OR case worker verification | | Recovery | Printable codes | One-time codes that can be written down | | Bypass | Trusted intermediary | Case managers verify via org email | | Essential access | No-signup mode | Core features work without account |
□ Email is primary identifier (phone optional)
□ Backup codes can be printed/written
□ Case worker recovery pathway exists
□ Core features work without login
□ Sessions are not device-locked
□ Phone number changes don't lock accounts
□ "Forgot password" has non-SMS option
Novice thinking: "Just show 'No connection' error"
Reality:
| Need | Pattern | Implementation | |------|---------|----------------| | Data persistence | Local-first | Save to localStorage/IndexedDB immediately | | Form state | Auto-save | Save every field change, not just on submit | | Submission | Background sync | Queue actions, sync when connection returns | | UI feedback | Optimistic updates | Update UI immediately, sync in background | | Progress | Resume anywhere | Let users pick up exactly where they left off | | Status | Visible sync state | "Saved locally" / "Syncing..." / "Up to date" | | Degradation | Graceful offline | Core features work without network |
□ PWA with service worker caching
□ All form data saves to localStorage on every change
□ Clear sync status indicator visible
□ Offline mode tested (airplane mode)
□ Background sync when connection returns
□ No data loss on connection drop (verified)
□ Multi-step flows don't timeout
□ Minimal asset downloads (text-first views available)
// Save form state on every change
function useAutoSave(key: string, data: any) {
useEffect(() => {
localStorage.setItem(key, JSON.stringify({
data,
savedAt: new Date().toISOString(),
synced: false
}));
}, [key, data]);
// Return saved data on mount
return useMemo(() => {
const saved = localStorage.getItem(key);
return saved ? JSON.parse(saved).data : null;
}, [key]);
}
Novice thinking: "Remember me improves UX"
Reality:
| Need | Pattern | Implementation | |------|---------|----------------| | Default state | Privacy mode ON | Don't auto-save sensitive info | | Logout | Prominent button | Make it obvious, not buried in menu | | Timeout | Warning + auto-logout | "5 min left. Continue?" | | Forms | No autofill default | Disable browser autofill on sensitive fields | | Mode toggle | "Public computer?" | One-click extra privacy mode | | Cookies | Session-only option | Clear on browser close |
□ "Remember me" is UNCHECKED by default
□ Logout button visible on every page
□ Session timeout with save-progress warning
□ Sensitive fields have autocomplete="off"
□ Incognito mode suggested in UI for public computers
□ No cached personal data after logout
□ "Working on a shared computer?" toggle available
Novice thinking: "Collect all info upfront for efficiency"
Reality:
| Need | Pattern | Implementation | |------|---------|----------------| | Length | Chunked progress | Break into short sections, save each | | Language | Plain language | 6th-8th grade reading level | | Complexity | One question/page | For difficult topics | | Progress | Clear indicators | "Step 2 of 5" always visible | | Validation | Forgiving input | Auto-format, accept variations | | Defaults | Smart prefill | Pre-fill what you can infer | | Help | Inline, not hidden | Help text visible, not in modals | | Flow | Skip and return | Never force-block on optional fields |
✅ Use:
❌ Avoid:
✅ Calm palette:
- Success: Soft green (#4a9d9e), not aggressive lime
- Warning: Warm amber (#d4a03a), not alarming yellow
- Error: Muted terracotta (#c97a5d), not aggressive red
- Background: Cream/warm neutrals
❌ Avoid:
- Aggressive red for errors
- High-contrast warning colors
- Flashing or pulsing elements
- Visual "alarm" states
□ No form longer than 5 fields per page
□ Progress indicator on all multi-step flows
□ Help text inline, not in tooltips/modals
□ Forgiving validation (formats automatically)
□ No required fields that aren't truly required
□ "Skip for now" on optional sections
□ Calm color palette (no aggressive reds)
□ Person-first language throughout
□ Clear "what happens next" on every screen
Novice thinking: "They know their case numbers"
Reality:
| Need | Pattern | Implementation | |------|---------|----------------| | Eligibility | Checker first | Show if qualified BEFORE collecting info | | Documents | Multiple upload methods | Email, fax, mail, in-person, photo | | Location | Auto-detection | Don't make them figure out jurisdiction | | Records | Lookup tools | Help them find their own case numbers | | Terms | Plain language | Define every legal term | | Timeline | Explicit expectations | "Most cases take 60-90 days" | | Fees | Waiver prominent | Fee waiver should be default path |
□ Eligibility checker before signup/info collection
□ Case number lookup tool or "I don't know" option
□ County auto-detected from address
□ Document upload alternatives (not just scan)
□ Legal terms have inline definitions
□ Expected timeline stated clearly
□ Fee waiver is default, not hidden option
□ "Not eligible" includes explanation WHY
The gold standard for civic tech:
Run this against any civic/legal/benefits application:
AUTHENTICATION
□ Can user sign up with just email?
□ Is there a non-SMS account recovery option?
□ Do core features work without login?
OFFLINE/INTERMITTENT
□ Does form data survive connection loss?
□ Is there visible "saved" indicator?
□ Can user resume exactly where they left off?
SHARED DEVICES
□ Is "remember me" unchecked by default?
□ Is logout button prominent?
□ Does session timeout with warning?
FORMS
□ Is reading level ≤8th grade?
□ Are there ≤5 fields per page?
□ Is help text inline (not hidden)?
□ Are required fields truly required?
TONE
□ Is language person-first?
□ Are timelines explicit?
□ Is error messaging non-blaming?
□ Are colors calm (no aggressive red)?
LEGAL/EXPUNGEMENT SPECIFIC
□ Is eligibility checked first?
□ Are fee waivers prominent?
□ Is "I don't know my case number" handled?
/references/authentication-patterns.md - Detailed auth implementation/references/offline-first-patterns.md - PWA and sync patterns/references/trauma-informed-language.md - Tone and word choice guide/references/code-for-america-learnings.md - CfA case studiesdata-ai
license: Apache-2.0 NOT for unrelated tasks outside this domain.
development
Use when designing caching strategies (cache-aside, write-through, write-behind), implementing distributed locks, building rate limiters, leaderboards, real-time streams (XADD/consumer groups), pub/sub, or tuning eviction policies. Triggers: thundering-herd on cache miss, dogpile on key expiry, Redlock vs SET-NX-PX choice, sliding-window rate limiter, hot-key on a single cluster slot, big-key blowup, MULTI/EXEC across slots, KEYS in production. NOT for Redis Cluster operations/admin (different domain), embedded KV (SQLite, leveldb), in-process LRU caches, or Memcached.
tools
Drawing the `'use client'` boundary correctly in React Server Components apps (Next.js App Router, RSC frameworks) — leaf-pushing, slot composition, serialization rules, and environment poisoning prevention. Grounded in react.dev and Next.js 16 docs.
development
Use when designing rate limiting for an API, choosing between token bucket / sliding window / leaky bucket / fixed window, implementing it in Redis, deciding edge (Cloudflare/Upstash) vs origin enforcement, sizing per-user vs per-IP vs per-endpoint quotas, returning the right 429 response with Retry-After, or fixing the boundary-burst bug in fixed-window limiters. Triggers: 429 too many requests, INCR + EXPIRE, ZADD + ZREMRANGEBYSCORE + ZCARD, X-RateLimit-Remaining header, Cloudflare WAF rate limiting rules, Upstash @upstash/ratelimit, leaky bucket shaping vs policing, distributed rate limiter consistency. NOT for DDoS mitigation specifically (different scale), CAPTCHA / bot management, full WAF design, or per-user quota billing.