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>
6.7 KiB
name, description, user-invocable, argument-hint
| name | description | user-invocable | argument-hint |
|---|---|---|---|
| normalize | Cross-component consistency scan — checks token access patterns, transitions, focus styles, spacing methods, and displayName across all components in a tier or the entire system. | true | [tier (atoms/molecules/organisms) or 'all'] |
Scan all components in a tier (or the entire system) for consistency violations and fix them. Unlike audit/critique which evaluate individual components, normalize ensures the system behaves as one cohesive whole. This skill finds AND fixes issues.
Target tier: $ARGUMENTS
Preparation
- Read
docs/design-system.mdfor FA design conventions - Read
docs/memory/decisions-log.mdfor design rationale (especially D031 on token access) - Read
docs/conventions/component-conventions.mdfor structural rules - List all component files in the target tier(s):
- Atoms:
src/components/atoms/*/ - Molecules:
src/components/molecules/*/ - Organisms:
src/components/organisms/*/ - If target is "all", scan every tier
- Atoms:
FA context: Consistency is trust. When components behave differently for no reason — different transition speeds, different focus styles, different spacing methods — users sense it even if they cannot articulate it. For families in distress, inconsistency creates subconscious unease. Normalize ruthlessly.
Consistency Dimensions
For each dimension, scan ALL components in the target scope, compare patterns, identify outliers, and fix them to match the established convention.
1. Token Access Patterns (D031)
Convention: Two access methods, by token tier:
- Semantic tokens (colour, spacing, typography, shape):
theme.palette.*,theme.spacing(),theme.typography.*,theme.shape.*inside theme callbacks.var(--fa-color-*),var(--fa-spacing-*)in static contexts. - Component tokens (badge sizes, card shadows, input dimensions):
var(--fa-badge-*),var(--fa-card-*)CSS variables only — these are NOT in the MUI theme.
Scan for violations:
- Hardcoded hex/rgb colour values (should use theme or CSS var)
- Hardcoded px spacing values (should use
theme.spacing()orvar(--fa-spacing-*)) - Hardcoded font sizes or weights (should use
theme.typography.*) - Semantic tokens accessed via CSS var when inside a theme callback (prefer theme accessor)
- Component tokens accessed via theme (they are CSS vars only)
- Primitive tokens used directly instead of semantic tokens
2. Transition Timing
Convention: 150ms ease-in-out for all state transitions.
Scan for violations:
- Transitions using durations other than 150ms (or
theme.transitions.duration.short) - Transitions using easing other than ease-in-out
- Transitions using bounce, elastic, or spring easing (remove — feels dated)
- Missing transitions on interactive state changes (hover, focus, active)
- Transitions on layout properties (
width,height,top,left) instead oftransform/opacity
3. Focus-Visible Style
Convention: :focus-visible with 2px outline, offset 2px, high contrast (3:1 minimum against adjacent colours).
Scan for violations:
outline: nonewithout:focus-visiblereplacement- Focus styles on
:focusinstead of:focus-visible(shows ring on click) - Inconsistent outline width, colour, or offset across components
- Missing focus styles entirely on interactive elements
- Focus ring colour that does not meet 3:1 contrast
4. Spacing Method
Convention: theme.spacing() in styled components and sx props. var(--fa-spacing-*) in static contexts.
Scan for violations:
- Raw pixel values for padding/margin/gap (e.g.,
padding: '16px') - Mixed methods in the same component (some
theme.spacing(), some raw values) - Inconsistent spacing scale usage across similar components (e.g., one card uses
spacing(2)for padding, another usesspacing(3))
5. Component Structure
Convention: Per docs/conventions/component-conventions.md.
Scan for violations:
- Missing
displayNameon the component - Missing barrel export (
index.tswithexport { default }andexport *) - Missing JSDoc on props interface (every prop needs a
/** description */) - Missing JSDoc on the component itself
- Props defined as
typeinstead ofinterface(interfaces produce better autodocs) - Missing
sxprop forwarding (every component must accept consumer overrides) - Interactive elements not using
React.forwardRef
6. Story Coverage
Convention: Per story coverage checklist in docs/conventions/component-conventions.md.
Scan for violations:
- Missing
tags: ['autodocs']in story meta - Missing Default story
- Missing AllVariants story (if component has variants)
- Missing Disabled story (if component can be disabled)
- Missing Loading story (if component has loading state)
- Incorrect
titleprefix (should match tier:Atoms/,Molecules/,Organisms/)
7. Naming Consistency
Scan for violations:
- Component folder not in PascalCase
- File names not matching component name
- Inconsistent prop naming across similar components (e.g.,
isDisabledvsdisabled,colourvscolor) - CSS custom properties not prefixed with
--fa-
Normalize Process
- Scan: Read every component file in the target tier(s)
- Tabulate: Build a comparison table for each dimension showing what each component does
- Identify outliers: Find components that deviate from the convention
- Fix: Update outlier components to match the convention
- Verify: Ensure TypeScript compiles and Storybook renders after fixes
Normalization Report
Present findings in this format:
Scan Summary
| Dimension | Components scanned | Violations found | Fixed |
|---|---|---|---|
| Token access | ? | ? | ? |
| Transitions | ? | ? | ? |
| Focus styles | ? | ? | ? |
| Spacing | ? | ? | ? |
| Structure | ? | ? | ? |
| Stories | ? | ? | ? |
| Naming | ? | ? | ? |
Violations Fixed
For each fix, note:
- Component: Which component was changed
- Dimension: Which consistency rule was violated
- Before: What it was doing
- After: What it does now
System-Level Observations
Note any patterns that suggest a convention should be updated (e.g., if most components deviate from the convention, perhaps the convention is wrong).
NEVER:
- Change a component's behaviour or API — normalize only changes implementation details
- Fix one component and leave similar components unfixed — normalize the whole tier
- Change conventions without flagging it — if you think a convention should change, note it as an observation, do not unilaterally change the rule