Add workflow infrastructure — ESLint, Prettier, Husky, Vitest, 7 new skills

Phase 1: Session log archived (1096→91 lines), D031 token access convention
Phase 2: ESLint v9 + Prettier + jsx-a11y, initial config and lint fixes
Phase 3: 7 new skills (polish, harden, normalize, clarify, typeset, quieter, adapt)
         + Vercel reference docs, updated audit/review-component refs
Phase 4: Husky + lint-staged pre-commit hooks, preflight updated to 8 checks
Phase 5: Vitest + Testing Library + /write-tests skill

- Badge.tsx colour maps unified to CSS variables (D031)
- 5 empty interface→type alias fixes (Switch, Radio, Divider, IconButton, Link)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-27 16:41:57 +11:00
parent c5bfeaee2f
commit aa7cdeecf0
33 changed files with 7685 additions and 1088 deletions

View File

@@ -0,0 +1,146 @@
---
name: polish
description: Final production readiness pass — visual alignment, spacing consistency, interaction states, copy, edge cases. Use before marking a component done.
user-invocable: true
argument-hint: "[component or area to polish]"
---
Perform a meticulous final pass on a component or area, fixing every detail that separates good work from great work. Unlike audit/critique which only assess, **polish finds AND fixes issues**.
**Target:** $ARGUMENTS
## Preparation
1. Read `docs/design-system.md` for FA design conventions
2. Read `docs/memory/decisions-log.md` for design rationale and prior decisions
3. Read the target component/area source files and stories
4. Reference `docs/reference/impeccable/polish-skill.md` for the full checklist
5. Reference `docs/conventions/component-conventions.md` for structural rules
**FA context**: Funeral Arranger serves families in grief or distress. The design must feel warm, trustworthy, and calm. Touch targets >= 44px. Transitions 150ms ease-in-out. No aggressive colours for errors (copper, not red — see D024). Accessibility is critical — users may be elderly, emotional, or on mobile.
**CRITICAL**: Polish is the last step, not the first. Do not polish work that is not functionally complete. If the component has open TODOs or missing features, flag them and skip those areas.
## Pre-Polish Assessment
Before fixing anything, assess the current state:
1. **Review completeness** — Is the component functionally complete? Are there known issues to preserve (mark with TODOs)?
2. **Identify polish areas** — Scan for visual inconsistencies, spacing issues, interaction state gaps, copy problems, edge cases, and transition roughness.
3. **Set scope** — List the specific fixes to make. Do not attempt structural changes — polish is micro-detail work.
## Polish Systematically
Work through each dimension. **Fix issues as you find them** — do not just document.
### 1. Visual Alignment & Spacing
- **Grid alignment**: All elements line up to the spacing scale (no arbitrary gaps)
- **Consistent spacing**: Every gap uses `theme.spacing()` or `var(--fa-spacing-*)` — no magic numbers
- **Optical alignment**: Adjust for visual weight where needed (icons often need offset for optical centering)
- **Responsive consistency**: Spacing works at all breakpoints (mobile, tablet, desktop)
**How to check**: Inspect computed styles. Look for values that are not multiples of 4px or 8px. Squint at the layout — anything that feels off probably is.
### 2. Typography Refinement
- **Hierarchy consistency**: Same element types use the same typography variant throughout
- **Line length**: Body text stays within 45-75 characters
- **Line height**: Appropriate for font size and reading context
- **Token compliance**: All font sizes, weights, and families come from `theme.typography.*`
### 3. Colour & Contrast
- **Contrast ratios**: All text meets WCAG AA (4.5:1 for normal text, 3:1 for large text and UI)
- **Token usage**: No hardcoded hex values — all via theme palette or CSS variables
- **Tinted neutrals**: No pure gray or pure black — add subtle colour tint per FA palette
- **Gray on colour**: Never put gray text on coloured backgrounds — use a shade of that colour
### 4. Interaction States
Every interactive element must have ALL of these states:
| State | Treatment | FA note |
|-------|-----------|---------|
| Default | Base styling | Warm, inviting |
| Hover | Subtle lift, colour shift | 150ms ease-in-out |
| Focus | Visible ring via `:focus-visible` | 2px, offset 2px, high contrast |
| Active | Pressed/darker | Immediate feedback |
| Disabled | Reduced opacity, `aria-disabled` | Clearly non-interactive |
| Loading | Spinner or skeleton | Reduce perceived wait |
| Error | Copper border/text, not red | Gentle, per D024 |
| Success | Confirmation feedback | Reassuring, not flashy |
**The common miss**: Designing hover without focus. Keyboard users never see hover states.
### 5. Micro-interactions & Transitions
- **Timing**: All transitions 150ms ease-in-out (FA convention)
- **Properties**: Only animate `transform`, `opacity`, `background-color`, `border-color`, `box-shadow` — never animate `width`, `height`, or `top`/`left`
- **Reduced motion**: Must respect `prefers-reduced-motion`
- **Easing**: Ease-in-out or ease-out. Never bounce or elastic — they feel dated.
### 6. Copy & Content
- **Consistent terminology**: Same things called the same names throughout
- **Capitalisation**: Sentence case for body, consistent for labels
- **Tone**: Warm, professional, clear — no jargon, no condescension
- **Labels**: Unambiguous — a user should never wonder "what does this mean?"
- **Punctuation**: Consistent (periods on sentences, not on labels)
### 7. Edge Cases
- **Long content**: Handles very long names, descriptions, prices
- **Empty states**: Helpful guidance, not blank space
- **Missing data**: Graceful degradation with sensible defaults
- **Loading states**: Clear async feedback, skeleton over spinner where possible
- **Error states**: Helpful, non-blaming messages with recovery paths (copper, not red)
### 8. Code Cleanliness
- Remove `console.log` statements
- Remove commented-out code
- Remove unused imports
- Verify `displayName` is set on the component
- Verify barrel export in `index.ts`
- Ensure all props have JSDoc descriptions
- No TypeScript `any` types
## Polish Checklist
Verify each item after completing fixes:
- [ ] Visual alignment correct at all breakpoints
- [ ] Spacing uses design tokens consistently (no magic numbers)
- [ ] Typography hierarchy consistent
- [ ] All interactive states implemented (hover, focus, active, disabled, loading, error)
- [ ] All transitions 150ms ease-in-out
- [ ] Focus indicators visible via `:focus-visible`
- [ ] Copy is consistent, warm, and unambiguous
- [ ] Touch targets >= 44px on all interactive elements
- [ ] Contrast ratios meet WCAG AA
- [ ] Keyboard navigation works correctly
- [ ] No console errors or warnings
- [ ] No layout shift on load
- [ ] Respects `prefers-reduced-motion`
- [ ] Code is clean (no TODOs, console.logs, commented code, unused imports)
- [ ] Component has `displayName` and barrel export
- [ ] All props have JSDoc descriptions
## Final Verification
After all fixes:
1. **Check Storybook** — Verify all stories render correctly
2. **Check TypeScript** — Ensure no type errors introduced
3. **Compare states** — Walk through every interactive state visually
4. **Test keyboard** — Tab through the component, verify focus order and indicators
**NEVER**:
- Polish before the component is functionally complete
- Introduce bugs while polishing (test thoroughly after each fix)
- Ignore systematic issues (if spacing is off everywhere, fix the system not individual instances)
- Perfect one area while leaving others rough (maintain consistent quality level)
- Make structural or architectural changes — that is not polish work
Report a summary of what was fixed when done.