---
name: normalize
description: 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.
user-invocable: true
argument-hint: "[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

1. Read `docs/design-system.md` for FA design conventions
2. Read `docs/memory/decisions-log.md` for design rationale (especially D031 on token access)
3. Read `docs/conventions/component-conventions.md` for structural rules
4. 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

**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()` or `var(--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 of `transform`/`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: none` without `:focus-visible` replacement
- [ ] Focus styles on `:focus` instead 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 uses `spacing(3)`)

### 5. Component Structure

**Convention**: Per `docs/conventions/component-conventions.md`.

**Scan for violations**:
- [ ] Missing `displayName` on the component
- [ ] Missing barrel export (`index.ts` with `export { default }` and `export *`)
- [ ] Missing JSDoc on props interface (every prop needs a `/** description */`)
- [ ] Missing JSDoc on the component itself
- [ ] Props defined as `type` instead of `interface` (interfaces produce better autodocs)
- [ ] Missing `sx` prop 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 `title` prefix (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., `isDisabled` vs `disabled`, `colour` vs `color`)
- [ ] CSS custom properties not prefixed with `--fa-`

## Normalize Process

1. **Scan**: Read every component file in the target tier(s)
2. **Tabulate**: Build a comparison table for each dimension showing what each component does
3. **Identify outliers**: Find components that deviate from the convention
4. **Fix**: Update outlier components to match the convention
5. **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
