From db9d1ba60363fe7ef9a2da3c36c18adb21e5c503 Mon Sep 17 00:00:00 2001 From: Richie Date: Thu, 2 Apr 2026 10:55:59 +1100 Subject: [PATCH] =?UTF-8?q?Clean=20repo=20for=20shared=20dev=20=E2=80=94?= =?UTF-8?q?=20remove=20AI=20tooling=20and=20working=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed: .claude/ agents/skills, CLAUDE.md, GEMINI.md, QUICKSTART.md, .mcp.json, bootstrap.sh, docs/memory/, docs/reference/impeccable/, docs/reference/vercel/, retroactive-review-plan, mcp-setup --- .claude/agents/component-builder.md | 82 - .claude/agents/story-writer.md | 70 - .claude/agents/token-architect.md | 57 - .claude/skills/adapt/SKILL.md | 130 - .claude/skills/audit/SKILL.md | 120 - .claude/skills/build-atom/SKILL.md | 28 - .claude/skills/build-molecule/SKILL.md | 30 - .claude/skills/build-organism/SKILL.md | 34 - .claude/skills/clarify/SKILL.md | 150 - .claude/skills/create-tokens/SKILL.md | 20 - .claude/skills/critique/SKILL.md | 124 - .claude/skills/harden/SKILL.md | 135 - .claude/skills/normalize/SKILL.md | 146 - .claude/skills/polish/SKILL.md | 146 - .claude/skills/preflight/SKILL.md | 111 - .claude/skills/quieter/SKILL.md | 131 - .claude/skills/review-component/SKILL.md | 68 - .claude/skills/status/SKILL.md | 35 - .claude/skills/sync-tokens/SKILL.md | 22 - .claude/skills/typeset/SKILL.md | 116 - .claude/skills/write-stories/SKILL.md | 29 - .claude/skills/write-tests/SKILL.md | 101 - .mcp.json | 8 - CLAUDE.md | 113 - GEMINI.md | 58 - QUICKSTART.md | 106 - bootstrap.sh | 138 - .../archive/sessions-through-2026-03-26.md | 1008 ----- docs/memory/component-registry.md | 112 - docs/memory/decisions-log.md | 295 -- docs/memory/session-log.md | 869 ---- docs/memory/token-registry.md | 288 -- docs/reference/impeccable/audit-skill.md | 147 - docs/reference/impeccable/cognitive-load.md | 106 - .../impeccable/color-and-contrast.md | 132 - docs/reference/impeccable/critique-skill.md | 201 - .../impeccable/frontend-design-skill.md | 147 - .../impeccable/heuristics-scoring.md | 234 -- .../impeccable/interaction-design.md | 195 - docs/reference/impeccable/motion-design.md | 99 - docs/reference/impeccable/personas.md | 178 - docs/reference/impeccable/polish-skill.md | 202 - .../reference/impeccable/responsive-design.md | 114 - docs/reference/impeccable/spatial-design.md | 100 - docs/reference/impeccable/typography.md | 133 - docs/reference/impeccable/ux-writing.md | 107 - docs/reference/mcp-setup.md | 127 - docs/reference/retroactive-review-plan.md | 137 - .../vercel/react-best-practices-full.md | 3502 ----------------- docs/reference/vercel/react-best-practices.md | 145 - .../reference/vercel/web-design-guidelines.md | 39 - .../vercel/web-interface-guidelines-full.md | 179 - 52 files changed, 11104 deletions(-) delete mode 100644 .claude/agents/component-builder.md delete mode 100644 .claude/agents/story-writer.md delete mode 100644 .claude/agents/token-architect.md delete mode 100644 .claude/skills/adapt/SKILL.md delete mode 100644 .claude/skills/audit/SKILL.md delete mode 100644 .claude/skills/build-atom/SKILL.md delete mode 100644 .claude/skills/build-molecule/SKILL.md delete mode 100644 .claude/skills/build-organism/SKILL.md delete mode 100644 .claude/skills/clarify/SKILL.md delete mode 100644 .claude/skills/create-tokens/SKILL.md delete mode 100644 .claude/skills/critique/SKILL.md delete mode 100644 .claude/skills/harden/SKILL.md delete mode 100644 .claude/skills/normalize/SKILL.md delete mode 100644 .claude/skills/polish/SKILL.md delete mode 100644 .claude/skills/preflight/SKILL.md delete mode 100644 .claude/skills/quieter/SKILL.md delete mode 100644 .claude/skills/review-component/SKILL.md delete mode 100644 .claude/skills/status/SKILL.md delete mode 100644 .claude/skills/sync-tokens/SKILL.md delete mode 100644 .claude/skills/typeset/SKILL.md delete mode 100644 .claude/skills/write-stories/SKILL.md delete mode 100644 .claude/skills/write-tests/SKILL.md delete mode 100644 .mcp.json delete mode 100644 CLAUDE.md delete mode 100644 GEMINI.md delete mode 100644 QUICKSTART.md delete mode 100755 bootstrap.sh delete mode 100644 docs/memory/archive/sessions-through-2026-03-26.md delete mode 100644 docs/memory/component-registry.md delete mode 100644 docs/memory/decisions-log.md delete mode 100644 docs/memory/session-log.md delete mode 100644 docs/memory/token-registry.md delete mode 100644 docs/reference/impeccable/audit-skill.md delete mode 100644 docs/reference/impeccable/cognitive-load.md delete mode 100644 docs/reference/impeccable/color-and-contrast.md delete mode 100644 docs/reference/impeccable/critique-skill.md delete mode 100644 docs/reference/impeccable/frontend-design-skill.md delete mode 100644 docs/reference/impeccable/heuristics-scoring.md delete mode 100644 docs/reference/impeccable/interaction-design.md delete mode 100644 docs/reference/impeccable/motion-design.md delete mode 100644 docs/reference/impeccable/personas.md delete mode 100644 docs/reference/impeccable/polish-skill.md delete mode 100644 docs/reference/impeccable/responsive-design.md delete mode 100644 docs/reference/impeccable/spatial-design.md delete mode 100644 docs/reference/impeccable/typography.md delete mode 100644 docs/reference/impeccable/ux-writing.md delete mode 100644 docs/reference/mcp-setup.md delete mode 100644 docs/reference/retroactive-review-plan.md delete mode 100644 docs/reference/vercel/react-best-practices-full.md delete mode 100644 docs/reference/vercel/react-best-practices.md delete mode 100644 docs/reference/vercel/web-design-guidelines.md delete mode 100644 docs/reference/vercel/web-interface-guidelines-full.md diff --git a/.claude/agents/component-builder.md b/.claude/agents/component-builder.md deleted file mode 100644 index 2da0ce3..0000000 --- a/.claude/agents/component-builder.md +++ /dev/null @@ -1,82 +0,0 @@ -# Component Builder - -You are the component-builder agent for the FA Design System. Your responsibility is building React components that consume the MUI theme and follow all project conventions. - -## Before starting - -1. Read `docs/memory/session-log.md` — understand what's been done -2. Read `docs/memory/decisions-log.md` — don't contradict previous decisions -3. Read `docs/memory/component-registry.md` — check status, avoid duplicates -4. Read `docs/memory/token-registry.md` — know which tokens are available -5. Read `docs/conventions/component-conventions.md` — follow all rules -6. Read `docs/design-system.md` — understand the spec for this component - -## Your workflow - -### Pre-flight checks - -Before writing any code: -1. **Dependency check for molecules** — if building a molecule, confirm all constituent atoms are marked `done` in `docs/memory/component-registry.md`. If any are `planned` or `in-progress`, STOP and tell the user which atoms need to be built first. -2. **Dependency check for organisms** — if building an organism, confirm all constituent molecules and atoms are `done`. -3. **Token check** — confirm `docs/memory/token-registry.md` has populated token entries. If tokens haven't been created yet (all sections empty), STOP and tell the user to run `/create-tokens` first. - -### Building a component - -1. **Check the registry** — confirm the component is planned and not already in progress. If it's `in-progress`, STOP and ask the user if they want to continue or restart it. -2. **Update the registry** — mark status as `in-progress` -3. **Create the component folder:** - ``` - src/components/{tier}/{ComponentName}/ - ├── {ComponentName}.tsx - ├── {ComponentName}.stories.tsx - └── index.ts - ``` -4. **Build the component** following all conventions: - - Extend appropriate MUI base component props - - ALL visual values from `theme` — never hardcode colours, spacing, typography, shadows - - Use `styled()` with `shouldForwardProp` for custom props - - Export both the component and props interface - - Include JSDoc on every prop - - Use `React.forwardRef` for interactive elements - - Minimum 44px touch target on mobile - - Visible focus indicators -5. **Write Storybook stories** covering ALL states from the checklist in `docs/conventions/component-conventions.md`: - - Default state with typical content - - All visual variants side by side - - All sizes side by side (if applicable) - - Disabled state - - Loading state (if applicable) - - Error state (if applicable) - - Long content / content overflow - - Empty/minimal content - - With and without optional elements - Every story meta MUST include `tags: ['autodocs']`. Do NOT mark the component done until all applicable stories exist. -6. **Create component tokens** in `tokens/component/{component}.json` if the component has stateful visual variants (e.g., `button.background.hover`, `input.border.error`) not covered by semantic tokens. If the component only uses existing semantic tokens, skip this step. -7. **Always create the `index.ts`** re-export file — components won't be importable without it: - ```typescript - export { default } from './{ComponentName}'; - export * from './{ComponentName}'; - ``` -8. **Verify in Storybook** — check the component renders correctly at http://localhost:6006. If it doesn't render, fix the issue before proceeding. - -### Component rules (non-negotiable) - -- NEVER hardcode colours, spacing, font sizes, shadows, or border radii -- Use `theme.palette.*`, `theme.spacing()`, `theme.typography.*`, `theme.shape.*` -- Every component MUST accept and forward the `sx` prop -- Use `Omit<>` to remove conflicting MUI base props -- Disabled elements: 40% opacity, `aria-disabled`, no pointer events -- Focus-visible: 2px solid interactive colour, 2px offset - -### Tiers - -- **Atoms** (`src/components/atoms/`): Button, Input, Typography, Badge, Icon, Avatar, Divider, Chip, Card, Link -- **Molecules** (`src/components/molecules/`): FormField, PriceCard, ServiceOption, SearchBar, StepIndicator -- **Organisms** (`src/components/organisms/`): ServiceSelector, PricingTable, ArrangementForm, Navigation, Footer - -## After completing work - -1. Update `docs/memory/component-registry.md` — mark component status as `review` -2. Update `docs/memory/token-registry.md` if you created any component tokens -3. Update `docs/memory/decisions-log.md` with any design decisions -4. Update `docs/memory/session-log.md` with work summary and next steps diff --git a/.claude/agents/story-writer.md b/.claude/agents/story-writer.md deleted file mode 100644 index ef68ad6..0000000 --- a/.claude/agents/story-writer.md +++ /dev/null @@ -1,70 +0,0 @@ -# Story Writer - -You are the story-writer agent for the FA Design System. Your responsibility is creating and maintaining Storybook stories that document and showcase components. - -## Before starting - -1. Read `docs/memory/session-log.md` — understand what's been done -2. Read `docs/memory/component-registry.md` — know which components exist and their status -3. Read `docs/conventions/component-conventions.md` — follow story conventions -4. Read the component's source file to understand its props and variants - -## Your workflow - -### Writing stories for a component - -1. **Read the component** — understand all props, variants, and states -2. **Create or update** `{ComponentName}.stories.tsx` in the component folder -3. **Follow the story template** from `docs/conventions/component-conventions.md` -4. **Cover all required states** (see checklist below) -5. **Verify in Storybook** at http://localhost:6006 - -### Story structure - -```typescript -import type { Meta, StoryObj } from '@storybook/react'; -import { ComponentName } from './ComponentName'; - -const meta: Meta = { - title: '{Tier}/{ComponentName}', // e.g., 'Atoms/Button' - component: ComponentName, - tags: ['autodocs'], - parameters: { - layout: 'centered', // 'centered' for atoms, 'padded' or 'fullscreen' for larger - }, - argTypes: { - // One entry per prop with control type, options, description - }, -}; - -export default meta; -type Story = StoryObj; -``` - -### Coverage checklist (every component MUST have) - -- [ ] **Default** — typical usage with standard content -- [ ] **AllVariants** — all visual variants side by side (if applicable) -- [ ] **AllSizes** — all size options side by side (if applicable) -- [ ] **Disabled** — disabled state -- [ ] **Loading** — loading state (if applicable) -- [ ] **Error** — error state (if applicable) -- [ ] **LongContent** — text overflow / long content handling -- [ ] **MinimalContent** — empty or minimal content -- [ ] **WithOptionalElements** — with/without icons, badges, etc. - -### Story naming - -- Use PascalCase for story names -- Be descriptive of the state or variant shown -- Title prefix matches atomic tier: `Atoms/`, `Molecules/`, `Organisms/` - -### Autodocs - -- Always include `tags: ['autodocs']` in meta -- Write JSDoc comments on component props — these become the docs -- Use `argTypes` to configure controls with descriptions and defaults - -## After completing work - -1. Update `docs/memory/session-log.md` noting which stories were written/updated diff --git a/.claude/agents/token-architect.md b/.claude/agents/token-architect.md deleted file mode 100644 index e1b3990..0000000 --- a/.claude/agents/token-architect.md +++ /dev/null @@ -1,57 +0,0 @@ -# Token Architect - -You are the token-architect agent for the FA Design System. Your responsibility is creating and maintaining design tokens — the single source of truth for all visual properties. - -## Before starting - -1. Read `docs/memory/session-log.md` — understand what's been done -2. Read `docs/memory/decisions-log.md` — don't contradict previous decisions -3. Read `docs/memory/token-registry.md` — know what tokens already exist -4. Read `docs/conventions/token-conventions.md` — follow all naming rules -5. Read `docs/design-system.md` — understand the brand context and spec - -## Your workflow - -### Creating tokens - -1. **Gather input** — the user provides brand colours, fonts, or reference images -2. **Use Figma MCP** if the user provides a Figma URL — call `get_design_context` or `get_screenshot` to extract design values -3. **Create primitive tokens** in `tokens/primitives/` — raw hex, px, font names using 50-950 colour scales -4. **Create semantic tokens** in `tokens/semantic/` — map primitives to design intent (text, surface, border, interactive, feedback) -5. **Validate token format** — before building, check every token has `$value`, `$type`, and `$description`. Missing `$description` is the most common mistake. -6. **Run `npm run build:tokens`** to generate CSS custom properties and JS module. If the build fails, read the error output and fix the token JSON before retrying. -7. **Update the MUI theme** in `src/theme/index.ts` to consume the generated token values. Common mappings: - - `color.brand.primary` → `palette.primary.main` - - `color.text.primary` → `palette.text.primary` - - `color.surface.default` → `palette.background.default` - - `color.feedback.*` → `palette.error.main`, `palette.warning.main`, etc. - - `fontFamily.heading` / `fontFamily.body` → `typography.fontFamily` - - Import values from `./generated/tokens.js` -8. **Verify** the build completes without errors - -### Token rules (non-negotiable) - -- Every token MUST have `$value`, `$type`, and `$description` (W3C DTCG format) -- Semantic tokens MUST reference primitives via aliases: `"$value": "{color.blue.700}"` -- Component tokens MUST reference semantic tokens -- All text colour combinations MUST meet WCAG 2.1 AA contrast (4.5:1 normal, 3:1 large) -- Use the `--fa-` CSS custom property prefix - -### File structure - -``` -tokens/primitives/colours.json — brand, neutral, feedback hue scales -tokens/primitives/typography.json — font families, sizes, weights, line heights -tokens/primitives/spacing.json — spacing scale, border radius -tokens/primitives/effects.json — shadows, opacity -tokens/semantic/colours.json — text, surface, border, interactive, feedback mappings -tokens/semantic/typography.json — typography role mappings (display, h1, body, etc.) -tokens/semantic/spacing.json — layout and component spacing -tokens/component/*.json — per-component tokens (created during component building) -``` - -## After completing work - -1. Update `docs/memory/token-registry.md` with every token you created/modified -2. Update `docs/memory/decisions-log.md` with any design decisions and rationale -3. Update `docs/memory/session-log.md` with work summary and next steps diff --git a/.claude/skills/adapt/SKILL.md b/.claude/skills/adapt/SKILL.md deleted file mode 100644 index 6df7ce3..0000000 --- a/.claude/skills/adapt/SKILL.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -name: adapt -description: Responsive adaptation review — checks touch targets, overflow, text scaling, content reflow, and mobile spacing across breakpoints. -user-invocable: true -argument-hint: "[component or area to check]" ---- - -Run a responsive design review on a component or area, then **fix issues found**. This is assessment AND fix — diagnose breakpoint problems, touch target failures, and mobile usability issues, then apply corrections. - -**Target:** $ARGUMENTS - -## Preparation - -1. Read `docs/design-system.md` for FA responsive conventions and breakpoints -2. Read the target component/area source files and stories -3. Reference `docs/reference/impeccable/responsive-design.md` for detailed responsive guidelines - -**FA context reminder**: Many Funeral Arranger users are older adults, potentially on older or budget devices, and may be using the platform on mobile during a difficult time. Touch interactions must be generous. Layouts must not break on small screens. Nothing should require precise fine-motor control or hover-only interactions. The platform must work on a 5-year-old Android phone on a slow connection just as well as on a modern desktop. - -## Diagnostic Checks - -Work through each check systematically. For each issue found, note the problem, then fix it. - -### 1. Touch Targets - -- All interactive elements (buttons, links, form controls, toggles) must have a minimum touch target of 44x44px -- Check `padding`, `min-height`, and `min-width` on clickable elements — the visual size can be smaller if the tap area is padded out -- Text links in body copy need adequate line-height or padding to create 44px+ tap areas -- Adjacent touch targets must have sufficient spacing (at least 8px gap) to prevent mis-taps -- Icon-only buttons are especially prone to being too small — verify dimensions include padding -- This is **critical** for FA's audience — elderly users and users under emotional stress have reduced fine-motor precision - -### 2. Horizontal Overflow - -- No horizontal scrolling on viewports as narrow as 320px (iPhone SE, older Android devices) -- Check for fixed widths (`width: 400px`, `min-width: 500px`) that exceed narrow viewports -- Check for content that breaks out of containers (long words, URLs, email addresses without `word-break` or `overflow-wrap`) -- Tables must adapt on mobile — use responsive patterns (card layout, horizontal scroll with visual indicator, or progressive disclosure) -- Images must have `max-width: 100%` or equivalent constraint -- Check for `flex-shrink: 0` or `flex: none` on elements that should be allowed to shrink - -### 3. Text Readability at Mobile Sizes - -- Body text minimum 14px on mobile (16px preferred) -- Use `rem` units for font sizes so text respects browser zoom/accessibility settings -- Never use `user-scalable=no` in viewport meta — this breaks accessibility -- Layouts must not break at 200% browser zoom (WCAG requirement) -- Small/caption text should remain legible — minimum 12px -- Check that heading sizes scale down appropriately on mobile (a 48px desktop heading should not stay 48px on a 320px screen) - -### 4. Content Reflow - -- Content should reflow logically between breakpoints, not just shrink -- Multi-column layouts should collapse to single column on mobile -- Side-by-side arrangements (image + text, icon + label) should stack vertically when space is constrained -- Check `flex-direction` and `grid-template-columns` for responsive adjustments -- Navigation should adapt: full horizontal on desktop, hamburger/drawer on mobile -- Cards in a grid should reduce column count at narrow widths, not just shrink cards - -### 5. Hover-Only Interactions - -- No functionality should require hover — touch users cannot hover -- Tooltips that appear only on hover need a touch alternative (tap to show, or visible by default on mobile) -- Hover-revealed actions (edit buttons, delete icons) must have an alternative on touch devices -- Use `@media (hover: hover)` for hover enhancements, with fallback for `@media (hover: none)` -- Dropdown menus triggered by hover must also work on tap -- Check for CSS `:hover` styles that hide/show content without a touch-friendly fallback - -### 6. Spacing Adjustments Per Breakpoint - -- Padding should be tighter on mobile (16px) and more generous on desktop (24-48px) -- Section spacing should compress on mobile to keep content scannable without excessive scrolling -- Card padding should adapt — desktop cards can be spacious, mobile cards should be compact but not cramped -- Check that spacing uses theme.spacing() or responsive values, not fixed values that work only at one breakpoint -- Container max-widths should be set appropriately for each breakpoint - -### 7. Image and Asset Sizing - -- Images should have responsive sizing (`max-width: 100%`, `height: auto`) -- Consider `loading="lazy"` for images below the fold (important for FA users on slow connections) -- Decorative images can be hidden on mobile if they add no informational value -- Avatar/icon sizes should be appropriate for mobile — not too large (wasting space) or too small (illegible) -- Check for background images that might not display well on small screens - -## Fix Process - -For each issue found: - -1. **Identify** the file, line, and current value -2. **Test mentally at 320px, 768px, and 1280px** — does the fix work across all three? -3. **Apply the fix** — use responsive utilities (MUI breakpoints, media queries, responsive props) -4. **Verify** the fix does not introduce new issues at other breakpoints -5. **Prefer CSS/theme solutions** over JavaScript breakpoint detection where possible - -## Report Format - -After fixing, present a summary: - -### Responsive Health Summary - -| Check | Status | Issues Found | Issues Fixed | -|-------|--------|-------------|-------------| -| Touch Targets (44px min) | pass/warn/fail | N | N | -| Horizontal Overflow (320px) | pass/warn/fail | N | N | -| Text Readability (mobile) | pass/warn/fail | N | N | -| Content Reflow | pass/warn/fail | N | N | -| Hover-Only Interactions | pass/warn/fail | N | N | -| Breakpoint Spacing | pass/warn/fail | N | N | -| Image/Asset Sizing | pass/warn/fail | N | N | - -### Breakpoint Walkthrough - -Brief assessment of the component at each key breakpoint: -- **320px** (small phone): Does it fit? Is it usable? -- **768px** (tablet): Does the layout adapt sensibly? -- **1280px** (desktop): Does it use the available space well? - -### Changes Made - -For each fix applied: -- **What changed**: Brief description -- **File**: Path and relevant line(s) -- **Before/After**: The old and new values -- **Breakpoint affected**: Which viewport size(s) this fix targets - -### Remaining Concerns - -Any issues that need design input, Storybook viewport testing, or are outside the scope of a responsive pass. - -**NEVER**: Use fixed pixel widths for containers. Add `user-scalable=no` to viewport meta. Rely on hover for essential functionality. Assume all users have modern large-screen devices. Ignore the 320px viewport — real people use iPhone SE and budget Android phones. Let touch targets fall below 44px. diff --git a/.claude/skills/audit/SKILL.md b/.claude/skills/audit/SKILL.md deleted file mode 100644 index b7780f4..0000000 --- a/.claude/skills/audit/SKILL.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -name: audit -description: Run technical quality checks across accessibility, performance, theming, responsive design, and anti-patterns. Generates a scored report with P0-P3 severity ratings. Adapted from impeccable (Apache 2.0). -user-invocable: true -argument-hint: "[component or area to audit]" ---- - -Run systematic **technical** quality checks on a component or area and generate a scored report. This is assessment-only — don't fix issues, document them. - -**Target:** $ARGUMENTS - -## Preparation - -1. Read `docs/design-system.md` for FA design conventions -2. Read the component/area source files -3. Reference `docs/reference/impeccable/` for detailed design guidelines when scoring -4. Reference `docs/reference/vercel/web-design-guidelines.md` for additional WCAG/accessibility rules (optional, for deeper a11y scoring) - -## Diagnostic Scan - -Score each dimension 0-4. - -### 1. Accessibility (A11y) - -**Check for**: -- Contrast ratios < 4.5:1 for text, < 3:1 for large text and UI components -- Missing ARIA: interactive elements without proper roles, labels, or states -- Keyboard navigation: missing focus-visible indicators, illogical tab order -- Semantic HTML: divs instead of buttons, missing landmarks, heading hierarchy -- Form issues: inputs without labels, poor error messaging -- Touch targets < 44px (critical for FA's audience — elderly, distressed) - -**Score**: 0=Fails WCAG A, 1=Major gaps, 2=Partial effort, 3=AA mostly met, 4=AA fully met - -### 2. Performance - -**Check for**: -- Expensive animations: animating layout properties instead of transform/opacity -- Missing optimisation: unoptimised assets, missing lazy loading -- Bundle concerns: unnecessary imports, unused dependencies -- Render performance: unnecessary re-renders, missing memoisation - -**Score**: 0=Severe issues, 1=Major problems, 2=Partial, 3=Mostly optimised, 4=Excellent - -### 3. Theming & Token Compliance - -**Check for**: -- Hardcoded colours not using theme palette or CSS variables -- Hardcoded spacing not using theme.spacing() or token values -- Hardcoded typography not using theme.typography variants -- Inconsistent token usage: wrong tier (primitive instead of semantic) -- Component tokens missing `$description` fields - -**Score**: 0=Hardcoded everything, 1=Minimal tokens, 2=Inconsistent, 3=Good with minor gaps, 4=Full token compliance - -### 4. Responsive Design - -**Check for**: -- Fixed widths that break on mobile -- Touch targets < 44px on interactive elements -- Horizontal scroll/overflow on narrow viewports -- Text scaling: layouts that break when text size increases -- Missing responsive padding (mobile vs desktop) - -**Score**: 0=Desktop-only, 1=Major issues, 2=Partial, 3=Good, 4=Fluid and responsive - -### 5. Design Quality - -**Check against these anti-patterns** (from impeccable frontend-design guidelines): -- Gray text on coloured backgrounds (looks washed out) -- Cards nested inside cards (visual noise) -- Identical card grids with no variation -- Bounce/elastic easing (dated, tacky) -- Every button styled as primary (no hierarchy) -- Redundant copy (headers restating the same info) -- Glassmorphism/blur used decoratively -- Missing interactive states (hover without focus, or vice versa) - -**Score**: 0=Multiple anti-patterns, 1=Several issues, 2=A couple, 3=Mostly clean, 4=Intentional, distinctive design - -## Report Format - -### Audit Health Score - -| # | Dimension | Score | Key Finding | -|---|-----------|-------|-------------| -| 1 | Accessibility | ? | | -| 2 | Performance | ? | | -| 3 | Theming & Tokens | ? | | -| 4 | Responsive Design | ? | | -| 5 | Design Quality | ? | | -| **Total** | | **??/20** | **[Rating]** | - -**Ratings**: 18-20 Excellent, 14-17 Good, 10-13 Acceptable, 6-9 Poor, 0-5 Critical - -### Executive Summary -- Score and rating -- Issue count by severity (P0/P1/P2/P3) -- Top 3-5 critical issues -- Recommended next steps - -### Detailed Findings - -Tag each issue **P0-P3**: -- **P0 Blocking**: Prevents task completion — fix immediately -- **P1 Major**: WCAG AA violation or significant UX issue — fix before release -- **P2 Minor**: Annoyance, workaround exists — fix in next pass -- **P3 Polish**: Nice-to-fix — address if time permits - -For each issue: -- **[P?] Issue name** -- **Location**: Component, file, line -- **Category**: Accessibility / Performance / Theming / Responsive / Design Quality -- **Impact**: How it affects users -- **Recommendation**: How to fix it - -### Positive Findings -Note what's working well — good practices to maintain. - -**NEVER**: Report issues without explaining impact. Provide generic recommendations. Skip positive findings. Mark everything as P0. diff --git a/.claude/skills/build-atom/SKILL.md b/.claude/skills/build-atom/SKILL.md deleted file mode 100644 index 02bd10b..0000000 --- a/.claude/skills/build-atom/SKILL.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -name: build-atom -description: Build an atom component (Button, Input, Typography, etc.) -argument-hint: "[ComponentName]" ---- - -Build an atom component for the FA Design System. - -Use the component-builder agent to handle this task. The user wants to build the following atom component: - -**Component:** $ARGUMENTS - -**Instructions for the agent:** -1. Read all memory files and conventions before starting -2. Check `docs/memory/component-registry.md` to confirm the component is planned -3. Create the component in `src/components/atoms/{ComponentName}/` -4. Include: `{ComponentName}.tsx`, `{ComponentName}.stories.tsx`, `index.ts` -5. Follow all rules in `docs/conventions/component-conventions.md` -6. ALL visual values MUST come from the MUI theme — never hardcode -7. Write comprehensive Storybook stories covering all states -8. Verify the component renders in Storybook -9. **Run internal QA** (stages 3-5 from `docs/reference/component-lifecycle.md`): - - Run `/audit` — fix all P0/P1 issues - - Run `/critique` (skip for simple utility atoms like Divider) - - Run `/harden` (skip for display-only atoms like Typography, Badge) - - Run `/polish` — final alignment, spacing, transitions -10. Present to user with summary and scores -11. Update all memory files when done diff --git a/.claude/skills/build-molecule/SKILL.md b/.claude/skills/build-molecule/SKILL.md deleted file mode 100644 index 76be77d..0000000 --- a/.claude/skills/build-molecule/SKILL.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: build-molecule -description: Build a molecule component (PriceCard, FormField, etc.) -argument-hint: "[ComponentName]" ---- - -Build a molecule component for the FA Design System. - -Use the component-builder agent to handle this task. The user wants to build the following molecule component: - -**Component:** $ARGUMENTS - -**Instructions for the agent:** -1. Read all memory files and conventions before starting -2. Check `docs/memory/component-registry.md` to confirm the component is planned and that its constituent atoms are `done` -3. Create the component in `src/components/molecules/{ComponentName}/` -4. Include: `{ComponentName}.tsx`, `{ComponentName}.stories.tsx`, `index.ts` -5. Compose from existing atom components — import from `@atoms/` -6. Follow all rules in `docs/conventions/component-conventions.md` -7. ALL visual values MUST come from the MUI theme — never hardcode -8. Write comprehensive Storybook stories with realistic content -9. Verify the component renders in Storybook -10. **Run internal QA** (stages 3-5 from `docs/reference/component-lifecycle.md`): - - Run `/audit` — fix all P0/P1 issues - - Run `/critique` — fix all P0/P1 issues - - Run `/harden` — check edge cases for interactive molecules - - Run `/polish` — final alignment, spacing, transitions - - Run `/typeset` if text-heavy (cards, form fields) -11. Present to user with summary and scores -12. Update all memory files when done diff --git a/.claude/skills/build-organism/SKILL.md b/.claude/skills/build-organism/SKILL.md deleted file mode 100644 index e950a41..0000000 --- a/.claude/skills/build-organism/SKILL.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: build-organism -description: Build an organism component (Navigation, PricingTable, etc.) -argument-hint: "[ComponentName]" ---- - -Build an organism component for the FA Design System. - -Use the component-builder agent to handle this task. The user wants to build the following organism component: - -**Component:** $ARGUMENTS - -**Instructions for the agent:** -1. Read all memory files and conventions before starting -2. Check `docs/memory/component-registry.md` — confirm the organism is planned -3. Verify all constituent molecules and atoms are marked `done` in the registry — if any are not, STOP and tell the user which dependencies need to be built first -4. Create the component in `src/components/organisms/{ComponentName}/` -5. Include: `{ComponentName}.tsx`, `{ComponentName}.stories.tsx`, `index.ts` -6. Compose from existing molecule and atom components — import from `@molecules/` and `@atoms/` -7. Follow all rules in `docs/conventions/component-conventions.md` -8. ALL visual values MUST come from the MUI theme — never hardcode -9. Write comprehensive Storybook stories with realistic page-level content -10. Verify the component renders in Storybook -11. **Run internal QA** (stages 3-5 from `docs/reference/component-lifecycle.md`): - - Run `/audit` — fix all P0/P1 issues - - Run `/critique` — fix all P0/P1 issues - - Run `/harden` — check all edge cases (organisms handle real data) - - Run `/polish` — final alignment, spacing, transitions - - Run `/typeset` if text-heavy - - Run `/adapt` — responsive check (organisms are layout components) - - Run `/quieter` if the organism handles sensitive moments (pricing, forms, errors) - - Run `/clarify` if the organism has decision points or complex information -12. Present to user with summary and scores -13. Update all memory files when done diff --git a/.claude/skills/clarify/SKILL.md b/.claude/skills/clarify/SKILL.md deleted file mode 100644 index 14e260f..0000000 --- a/.claude/skills/clarify/SKILL.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -name: clarify -description: Information hierarchy improvement — evaluates whether primary actions are visible, decision points are clear, content grouping is logical, and labels are unambiguous. -user-invocable: true -argument-hint: "[component or area to clarify]" ---- - -Evaluate and fix information hierarchy, cognitive load, and decision clarity. Unlike audit/critique which only assess, **clarify finds AND fixes issues**. This skill is critical for flows, forms, and any interface where users must make decisions. - -**Target:** $ARGUMENTS - -## Preparation - -1. Read `docs/design-system.md` for FA design conventions -2. Read `docs/memory/decisions-log.md` for design rationale -3. Read the target component/area source files and stories -4. Reference `docs/reference/impeccable/cognitive-load.md` for the 8-item checklist and violation patterns -5. Reference `docs/reference/impeccable/heuristics-scoring.md` for scoring criteria - -**FA context**: Funeral Arranger serves families in grief or distress. Cognitive capacity is reduced under grief — working memory shrinks, decision fatigue sets in faster, and tolerance for ambiguity drops to near zero. Clarity is not a nice-to-have, it is the primary design requirement. No jargon. No ambiguity. No unnecessary choices. Every screen should answer: "What am I looking at? What should I do? What happens next?" - -## Phase 1: Cognitive Load Assessment - -Run the 8-item checklist from `docs/reference/impeccable/cognitive-load.md` against the target: - -| # | Check | Pass/Fail | Notes | -|---|-------|-----------|-------| -| 1 | **Single focus**: Can the user complete their primary task without distraction? | | | -| 2 | **Chunking**: Is information in digestible groups (<=4 items per group)? | | | -| 3 | **Grouping**: Are related items visually grouped (proximity, borders, shared background)? | | | -| 4 | **Visual hierarchy**: Is it immediately clear what is most important? | | | -| 5 | **One thing at a time**: Can the user focus on one decision before the next? | | | -| 6 | **Minimal choices**: Are decisions simplified (<=4 visible options at any decision point)? | | | -| 7 | **Working memory**: Does the user need to remember info from a previous screen? | | | -| 8 | **Progressive disclosure**: Is complexity revealed only when needed? | | | - -**Scoring**: 0-1 failures = low cognitive load (good). 2-3 = moderate (address soon). 4+ = high cognitive load (critical fix needed). - -## Phase 2: Clarity Checks - -Evaluate each dimension. **Fix issues as you find them.** - -### 1. Primary Action Visibility - -The most important action on any screen should be identifiable within 2 seconds. - -- [ ] **One primary action**: There is exactly one visually dominant CTA per view -- [ ] **Visual weight**: The primary action has the strongest visual weight (size, colour, contrast) -- [ ] **Position**: The primary action is in a predictable location (bottom of form, right of button group) -- [ ] **No competition**: Secondary actions are visually subordinate (outlined or text style, not filled) -- [ ] **Label clarity**: The CTA label says what will happen ("Continue to payment" not "Next" or "Submit") - -**FA-specific**: For stepped flows (arrangement, funeral finder), the primary CTA must always be visible without scrolling. Smart defaults should pre-fill where possible to reduce friction. - -### 2. Decision Point Clarity - -At every point where the user must choose: - -- [ ] **<=4 options visible**: If more exist, group under categories or use progressive disclosure -- [ ] **Recommended option**: When appropriate, visually highlight the recommended choice -- [ ] **Clear labels**: Every option has an unambiguous label — the user should never wonder "what does this mean?" -- [ ] **Consequence preview**: The user can see what choosing each option will lead to -- [ ] **Reversibility signal**: If a choice can be changed later, say so ("You can change this later") - -**FA-specific**: Pricing decisions are high-anxiety. Show what is included, not just the price. For service options, group by category (venue, ceremony, extras) rather than showing a flat list. - -### 3. Content Grouping - -Related information should be visually grouped: - -- [ ] **Proximity**: Related items are physically close together -- [ ] **Separation**: Unrelated groups have clear visual separation (whitespace, dividers, card boundaries) -- [ ] **Labels**: Each group has a clear heading that describes its contents -- [ ] **Consistency**: Same type of grouping used for same type of content throughout - -### 4. Label Clarity - -For every label, heading, and piece of instructional text: - -- [ ] **Unambiguous**: Could not be misinterpreted by a reasonable person -- [ ] **Action-oriented**: Buttons describe what they do, not what they are -- [ ] **Jargon-free**: No funeral industry jargon unless unavoidable (and defined inline if so) -- [ ] **Consistent**: Same concept uses the same word everywhere (not "funeral" in one place and "service" in another for the same thing) -- [ ] **Concise**: Labels are as short as possible while remaining clear - -**FA-specific**: Avoid euphemistic language that creates ambiguity. "Funeral service" is clearer than "farewell ceremony." Be direct but warm. - -### 5. Information Hierarchy - -The visual presentation should match the importance of information: - -- [ ] **Reading order**: The most important information comes first (top, left) -- [ ] **Size signals importance**: Larger text = more important -- [ ] **Colour signals importance**: Brand/accent colour draws the eye to what matters -- [ ] **Redundancy eliminated**: No information is repeated without purpose -- [ ] **Noise removed**: Every element earns its place — nothing decorative without function - -### 6. Navigation Clarity - -The user should always know where they are and how to move: - -- [ ] **Current location visible**: Active states, breadcrumbs, or step indicators show position -- [ ] **Next step obvious**: The path forward is clear without thinking -- [ ] **Back path clear**: The user can always go back without losing work -- [ ] **Progress visible**: Multi-step flows show progress (step 2 of 4) - -## Phase 3: Cognitive Load Violations Scan - -Check for common cognitive load violations (from `docs/reference/impeccable/cognitive-load.md`): - -1. **Wall of Options** — 10+ choices with no hierarchy. **Fix**: Group, highlight recommended, use progressive disclosure. -2. **Memory Bridge** — Must remember info from step 1 to complete step 3. **Fix**: Keep context visible or repeat it. -3. **Hidden Navigation** — Must build a mental map. **Fix**: Show current location always. -4. **Jargon Barrier** — Technical/domain language forces translation effort. **Fix**: Plain language, define terms inline. -5. **Visual Noise Floor** — Every element has the same visual weight. **Fix**: Clear hierarchy — one primary, 2-3 secondary, rest muted. -6. **Inconsistent Pattern** — Similar actions work differently in different places. **Fix**: Standardise interaction patterns. -7. **Multi-Task Demand** — Must process multiple simultaneous inputs. **Fix**: Sequence the steps. -8. **Context Switch** — Must jump between screens to gather info for one decision. **Fix**: Co-locate information. - -## Clarification Report - -After fixing issues, present: - -### Cognitive Load Score - -**Checklist failures**: X/8 -**Rating**: Low / Moderate / High - -### What Was Clarified - -For each fix: -- **Area**: What was changed -- **Problem**: What was unclear or overloaded -- **Fix**: What was done to clarify -- **Rationale**: Why this improves the experience for FA's users - -### Clarity Wins - -Note areas that are already well-structured — reinforce good patterns. - -### Remaining Concerns - -Note any structural clarity issues that require architectural changes beyond this skill's scope. - -**NEVER**: -- Add jargon or technical language — always simplify -- Present more than 4 options at a decision point without grouping -- Remove information that users need — clarify means restructure, not delete -- Change component behaviour or API — only change presentation, labels, grouping, and hierarchy -- Use ambiguous labels ("Submit", "Click here", "Next") when specific labels are possible diff --git a/.claude/skills/create-tokens/SKILL.md b/.claude/skills/create-tokens/SKILL.md deleted file mode 100644 index ed82838..0000000 --- a/.claude/skills/create-tokens/SKILL.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: create-tokens -description: Create design tokens from brand colours, fonts, and reference material -argument-hint: "[brand colours, fonts, or Figma URL]" ---- - -Create design tokens for the FA Design System. - -Use the token-architect agent to handle this task. The user's input follows — it may include brand colours, font choices, reference images, or Figma URLs. - -**Instructions for the agent:** -1. Read all memory files and conventions before starting -2. If the user provides a Figma URL, use the Figma MCP to extract design context -3. Create primitive tokens (colour scales, typography, spacing, effects) -4. Create semantic tokens (map primitives to design intent) -5. Run `npm run build:tokens` to generate outputs -6. Update the MUI theme in `src/theme/index.ts` to use generated values -7. Update all memory files when done - -User input: $ARGUMENTS diff --git a/.claude/skills/critique/SKILL.md b/.claude/skills/critique/SKILL.md deleted file mode 100644 index 2f19e3e..0000000 --- a/.claude/skills/critique/SKILL.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -name: critique -description: UX design review — evaluates visual hierarchy, emotional journey, cognitive load, and overall quality using Nielsen's heuristics (scored 0-40). Adapted from impeccable (Apache 2.0). -user-invocable: true -argument-hint: "[component or area to critique]" ---- - -Conduct a holistic UX design critique. Think like a design director giving feedback — evaluate whether the interface actually works as a designed experience, not just technically. - -**Target:** $ARGUMENTS - -## Preparation - -1. Read `docs/design-system.md` for FA design context and brand guidelines -2. Read `docs/memory/decisions-log.md` for design rationale -3. Read the target component/area source and stories -4. Reference `docs/reference/impeccable/cognitive-load.md` for the 8-item checklist -5. Reference `docs/reference/impeccable/heuristics-scoring.md` for scoring criteria - -**FA context reminder**: Funeral Arranger serves families often in grief or distress. The design must feel warm, trustworthy, transparent, and calm. Clarity over cleverness. Accessibility is critical — users may be elderly, emotional, or unfamiliar with technology. - -## Phase 1: Design Critique - -Evaluate across these dimensions: - -### 1. Visual Hierarchy -- Does the eye flow to the most important element first? -- Is there a clear primary action visible within 2 seconds? -- Do size, colour, and position communicate importance correctly? -- Is there visual competition between elements of different weights? - -### 2. Information Architecture & Cognitive Load -- Is the structure intuitive for a first-time user? -- Is related content grouped logically? -- Are there too many choices at once? (>4 at a decision point = flag it) -- **Run the 8-item cognitive load checklist** from `docs/reference/impeccable/cognitive-load.md` -- Report failure count: 0-1 = low (good), 2-3 = moderate, 4+ = critical - -### 3. Emotional Journey -- Does the interface feel warm and trustworthy (appropriate for FA)? -- Would a grieving family member feel "this is for me"? -- Are there design interventions at anxiety-prone moments (pricing, commitment, forms)? -- Does the experience end well (confirmation, clear next step)? - -### 4. Discoverability & Affordance -- Are interactive elements obviously interactive? -- Would a user know what to do without instructions? -- Are hover/focus states providing useful feedback? - -### 5. Composition & Balance -- Does the layout feel balanced? -- Is whitespace used intentionally? -- Is there visual rhythm in spacing and repetition? - -### 6. Typography as Communication -- Does the type hierarchy signal what to read first, second, third? -- Is body text comfortable to read? (line length 45-75ch, adequate size) -- Do font choices reinforce FA's warm, professional tone? - -### 7. Colour with Purpose -- Is colour used to communicate, not just decorate? -- Does the warm gold/copper brand palette feel cohesive? -- Are accent colours drawing attention to the right things? -- Does it work for colourblind users? - -### 8. States & Edge Cases -- Empty states: Do they guide users toward action? -- Loading states: Do they reduce perceived wait time? -- Error states: Are they helpful and non-blaming? (critical for FA — no aggressive red labels) -- Success states: Do they confirm and guide next steps? - -### 9. Microcopy & Voice -- Is the writing clear and concise? -- Does it sound warm and professional (FA's tone)? -- Are labels and buttons unambiguous? -- Does error copy help users fix the problem without distress? - -## Phase 2: Present Findings - -### Design Health Score - -Score each of Nielsen's 10 heuristics 0-4 (consult `docs/reference/impeccable/heuristics-scoring.md`): - -| # | Heuristic | Score | Key Issue | -|---|-----------|-------|-----------| -| 1 | Visibility of System Status | ? | | -| 2 | Match System / Real World | ? | | -| 3 | User Control and Freedom | ? | | -| 4 | Consistency and Standards | ? | | -| 5 | Error Prevention | ? | | -| 6 | Recognition Rather Than Recall | ? | | -| 7 | Flexibility and Efficiency | ? | | -| 8 | Aesthetic and Minimalist Design | ? | | -| 9 | Error Recovery | ? | | -| 10 | Help and Documentation | ? | | -| **Total** | | **??/40** | **[Rating]** | - -**Ratings**: 36-40 Excellent, 28-35 Good, 20-27 Acceptable, 12-19 Poor, 0-11 Critical - -### Overall Impression -Brief gut reaction — what works, what doesn't, the single biggest opportunity. - -### What's Working -2-3 things done well. Be specific about why they work. - -### Priority Issues -3-5 most impactful design problems, ordered by importance. - -For each issue, tag **P0-P3**: -- **[P?] What**: Name the problem -- **Why it matters**: How it hurts users (especially in FA's sensitive context) -- **Fix**: Concrete recommendation - -### FA Audience Check -Walk through the primary user flow as: -1. **Bereaved family member** (60+, first time, emotional, possibly on mobile) -2. **Arrangement planner** (30-50, comparing options, price-sensitive, wants transparency) - -For each persona, list specific pain points found. - -### Minor Observations -Quick notes on smaller issues worth addressing. - -**Remember**: Be direct and specific. Say what's wrong AND why it matters. Prioritise ruthlessly. Don't soften criticism — honest feedback ships better design. diff --git a/.claude/skills/harden/SKILL.md b/.claude/skills/harden/SKILL.md deleted file mode 100644 index 035eede..0000000 --- a/.claude/skills/harden/SKILL.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -name: harden -description: Edge case and robustness review — checks error states, empty states, loading states, boundary values, and disabled interactions. Critical for forms and arrangement flows. -user-invocable: true -argument-hint: "[component or area to harden]" ---- - -Systematically review and fix edge cases, error states, and boundary conditions. Unlike audit/critique which only assess, **harden finds AND fixes issues**. This skill is especially critical for forms, stepped flows, and anything involving user input. - -**Target:** $ARGUMENTS - -## Preparation - -1. Read `docs/design-system.md` for FA design conventions -2. Read `docs/memory/decisions-log.md` for design rationale (especially D024 on error states) -3. Read the target component/area source files and stories -4. Reference `docs/reference/impeccable/interaction-design.md` for interactive state requirements -5. Reference `docs/reference/impeccable/cognitive-load.md` for cognitive load under stress -6. Reference `docs/conventions/component-conventions.md` for structural rules - -**FA context**: Funeral Arranger serves families in grief or distress. When something goes wrong, the interface must be gentle and guiding, never blaming or alarming. Error states use copper tones, not red (D024). Empty states should guide toward action, not leave users stranded. Loading states should reduce perceived wait time — grieving users have less patience for ambiguity. - -## Hardening Checklist - -Work through each category. **Fix issues as you find them** — do not just document. - -### 1. Error States - -For every input, form field, and async operation: - -- [ ] **Error is visible**: Error message appears near the source of the problem -- [ ] **Error is gentle**: Uses copper tones (`feedback.error`), not aggressive red. Per D024, labels stay neutral -- [ ] **Error is specific**: Identifies the exact problem ("Please enter a valid email" not "Invalid input") -- [ ] **Error is actionable**: Tells the user how to fix it -- [ ] **Error is accessible**: Connected via `aria-describedby`, announced to screen readers -- [ ] **Error does not destroy work**: Form data is preserved when validation fails -- [ ] **Error timing**: Validates on blur for individual fields, on submit for cross-field validation -- [ ] **Network errors**: Graceful message for failed API calls with retry option -- [ ] **Unexpected errors**: Catch-all error boundary that does not show a blank screen - -**FA-specific**: Error copy should never blame the user. Use passive voice for errors ("A valid email is needed" not "You entered an invalid email"). Offer help where possible. - -### 2. Empty States - -For every list, collection, search result, and data display: - -- [ ] **Empty state exists**: Not just blank space or a bare container -- [ ] **Empty state guides**: Tells the user what this area is for and how to populate it -- [ ] **Empty state has a CTA**: Primary action to add/create/search is visible -- [ ] **Empty state feels warm**: Consistent with FA's supportive tone -- [ ] **Empty state is distinct**: Clearly different from loading state — user should never confuse "no data" with "still loading" - -### 3. Loading States - -For every async operation and data fetch: - -- [ ] **Loading indicator exists**: User sees feedback that something is happening -- [ ] **Skeleton over spinner**: Use skeleton screens for content areas, spinners only for actions -- [ ] **No layout shift**: Content area maintains its dimensions during loading (prevents CLS) -- [ ] **Loading is fast-feeling**: Skeleton previews the content shape; perceived wait is minimised -- [ ] **Loading timeout**: If loading takes >5s, show a reassuring message ("This is taking longer than usual") -- [ ] **Button loading**: Buttons show inline loading state, remain disabled, and preserve their width -- [ ] **Optimistic updates**: For low-stakes actions, show success immediately and rollback on failure - -### 4. Disabled States - -For every interactive element that can be disabled: - -- [ ] **Visually distinct**: Reduced opacity (0.38-0.5) or muted treatment — clearly non-interactive -- [ ] **`aria-disabled`**: Set alongside visual treatment for screen reader users -- [ ] **No pointer events**: `pointer-events: none` or equivalent — no hover/active states -- [ ] **Tooltip on disabled**: Explains WHY the element is disabled (e.g., "Complete the required fields first") -- [ ] **Cursor**: Shows `not-allowed` cursor on hover - -### 5. Boundary Values - -For every input that accepts user data: - -- [ ] **Max length**: Text inputs have sensible `maxLength` and show remaining characters if relevant -- [ ] **Min/max values**: Number inputs have `min`/`max` attributes -- [ ] **Long content**: Component handles very long names, descriptions, and values without breaking layout -- [ ] **Short content**: Component handles single-character or minimal content gracefully -- [ ] **Special characters**: Handles ampersands, quotes, HTML entities, and emoji without rendering issues -- [ ] **Zero state**: Numeric displays handle $0.00, 0 items, 0 results -- [ ] **Large numbers**: Handles $999,999+ with proper formatting - -### 6. Overflow & Truncation - -For every text container and layout: - -- [ ] **Text overflow**: Long text truncates with ellipsis or wraps gracefully — never overflows container -- [ ] **Responsive overflow**: No horizontal scroll at any viewport width -- [ ] **List overflow**: Long lists scroll within a container, not the page -- [ ] **Image overflow**: Images are constrained to their containers with `object-fit` - -### 7. Keyboard & Focus - -For every interactive element and flow: - -- [ ] **Tab order**: Logical, matches visual order -- [ ] **Focus trap**: Modals and drawers trap focus correctly (use `inert` on background) -- [ ] **Focus return**: When a modal/popover closes, focus returns to the trigger element -- [ ] **Escape to close**: All overlays close on Escape key -- [ ] **Enter to submit**: Forms submit on Enter from the last field -- [ ] **Arrow navigation**: Tab lists, menus, and radio groups use roving tabindex with arrow keys - -### 8. Concurrent & Async - -For forms and flows with async operations: - -- [ ] **Double-submit prevention**: Submit button disables after first click -- [ ] **Rapid interaction**: Debounced search, throttled scroll handlers -- [ ] **Stale data**: Component handles data that changes between render and interaction -- [ ] **Unmount safety**: Async operations clean up on component unmount (no state updates after unmount) - -## Hardening Report - -After fixing issues, provide a summary: - -### Fixed -List each issue fixed with a one-line description. - -### Verified OK -List categories that passed inspection without changes needed. - -### Out of Scope -Note any structural issues found that require architectural changes (not hardening work). - -**NEVER**: -- Use aggressive red for error states — always copper/warm tones per D024 -- Show blank screens for empty or error states -- Leave async operations without loading feedback -- Allow double-submit on forms -- Remove focus indicators -- Make structural changes — hardening fixes edge cases within the existing architecture diff --git a/.claude/skills/normalize/SKILL.md b/.claude/skills/normalize/SKILL.md deleted file mode 100644 index 8779a85..0000000 --- a/.claude/skills/normalize/SKILL.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -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 diff --git a/.claude/skills/polish/SKILL.md b/.claude/skills/polish/SKILL.md deleted file mode 100644 index 4c037f7..0000000 --- a/.claude/skills/polish/SKILL.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -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. diff --git a/.claude/skills/preflight/SKILL.md b/.claude/skills/preflight/SKILL.md deleted file mode 100644 index 95d2c5c..0000000 --- a/.claude/skills/preflight/SKILL.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -name: preflight -description: Pre-commit quality check — verifies TypeScript, ESLint, Prettier, Storybook, token sync, and no hardcoded values -argument-hint: "[--fix to auto-fix issues]" ---- - -Run quality checks before committing. Reports pass/fail for each check and blocks commit if critical issues are found. - -**Mode:** $ARGUMENTS (pass `--fix` to attempt auto-fixes, otherwise report-only) - -**Run these checks in order:** - -### 1. TypeScript compilation -```bash -npx tsc --noEmit 2>&1 | grep -v "tokens.js" -``` -- **Pass:** No errors (the tokens.js declaration warning is a known pre-existing issue — ignore it) -- **Fail:** Any other TypeScript errors → report them -- **Critical:** Yes — do not commit if this fails - -### 2. Storybook build -```bash -npx storybook build --quiet 2>&1 -``` -- **Pass:** Build succeeds -- **Fail:** Build errors → report them -- **Critical:** Yes — do not commit if this fails - -### 3. Token sync check -Compare timestamps: do the generated outputs (`src/theme/generated/tokens.js`, `src/theme/generated/tokens.css`) have an older modification time than any `tokens/**/*.json` file? -```bash -# Find newest token JSON file -newest_token=$(find tokens/ -name "*.json" -newer src/theme/generated/tokens.js 2>/dev/null | head -5) -``` -- **Pass:** No token JSON files are newer than the generated outputs -- **Fail:** Token JSON was modified but outputs weren't regenerated -- **Fix:** Run `npm run build:tokens` -- **Critical:** Yes — stale generated tokens cause silent bugs - -### 4. Hardcoded values scan -Scan component files for hardcoded colours, spacing, and font values that should use tokens: -```bash -# Check for hex colours in component files (excluding stories and tokens) -grep -rn "#[0-9a-fA-F]\{3,8\}" src/components/ --include="*.tsx" --include="*.ts" | grep -v ".stories." | grep -v "// ok-hardcode" -``` -- **Pass:** No hex colours found in component source files (stories are exempt) -- **Fail:** Hardcoded values found → report file and line -- **Note:** Lines with `// ok-hardcode` comment are exempted (for rare intentional cases) -- **Critical:** No — warn but don't block commit - -### 5. Component exports check -Verify each component folder has a barrel export (`index.ts`) and the component has `displayName`: -```bash -# Check for missing index.ts -for dir in src/components/atoms/*/; do - [ -f "$dir/index.ts" ] || echo "Missing index.ts: $dir" -done -# Check for missing displayName (exclude stories) -find src/components/atoms/ -name "*.tsx" ! -name "*.stories.tsx" | xargs grep -L "displayName" 2>/dev/null -``` -- **Pass:** All component folders have index.ts and components set displayName -- **Fail:** Missing exports or displayName -- **Critical:** No — warn but don't block commit - -### 6. ESLint -```bash -npm run lint 2>&1 -``` -- **Pass:** No errors -- **Fail:** ESLint errors → report them -- **Fix:** Run `npm run lint:fix` -- **Critical:** Yes — do not commit if this fails - -### 7. Prettier -```bash -npm run format:check 2>&1 -``` -- **Pass:** All files formatted correctly -- **Fail:** Formatting issues found → report them -- **Fix:** Run `npm run format` -- **Critical:** No — warn but don't block commit (Husky pre-commit hook auto-fixes these) - -### Report format -``` -PREFLIGHT RESULTS -═══════════════════════════════ -✓ TypeScript .............. PASS -✓ Storybook build ........ PASS -✓ Token sync ............. PASS -⚠ Hardcoded values ....... WARN (2 issues) -✓ Component exports ...... PASS -✓ ESLint ................. PASS -✓ Prettier ............... PASS -─────────────────────────────── -Result: PASS (safe to commit) -``` - -Use `PASS`, `FAIL`, or `WARN`. If any critical check fails, the result is `FAIL (do not commit)`. If only warnings, result is `PASS (safe to commit)` with warnings listed. - -If `--fix` was passed, attempt to fix issues automatically (e.g., run `npm run build:tokens` for stale tokens) and re-check. - -### 8. Visual QA spot-check (manual review, non-blocking) - -If a component was recently modified, do a quick visual review of the source code for these common issues (adapted from impeccable /polish): - -- **Transition consistency**: All interactive state changes should use `150ms ease-in-out` (FA convention). Flag mismatches. -- **Focus-visible**: Every interactive element should have a `:focus-visible` style. Flag any that rely only on hover. -- **Touch targets**: Interactive elements should have `minHeight >= 44px` for the largest size (or the mobile-intended size). -- **Spacing consistency**: Padding/gap values should use `theme.spacing()` or token CSS variables, not raw px. - -These are advisory — report as `INFO` lines after the main results. Do not block commit for these. diff --git a/.claude/skills/quieter/SKILL.md b/.claude/skills/quieter/SKILL.md deleted file mode 100644 index d165584..0000000 --- a/.claude/skills/quieter/SKILL.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -name: quieter -description: Calmer design pass — reduces visual noise, aggressive colours, competing weights, and transactional copy. Highly FA-specific for grief-sensitive context. -user-invocable: true -argument-hint: "[component or area to quiet]" ---- - -Run a grief-sensitive design pass on a component or area, then **fix issues found**. This is assessment AND fix — diagnose anything that feels too loud, too urgent, or too transactional for a funeral planning context, then apply corrections. - -**Target:** $ARGUMENTS - -## Preparation - -1. Read `docs/design-system.md` for FA brand guidelines and tone -2. Read `docs/memory/decisions-log.md` for colour and tone decisions (especially D024 for error treatment) -3. Read the target component/area source files and stories -4. Reference `docs/reference/impeccable/color-and-contrast.md` for colour usage principles -5. Reference `docs/reference/impeccable/personas.md` for user archetypes (especially Jordan — confused first-timer, and Casey — distracted mobile user) - -**FA context reminder**: "Understated empathy — warm but not gushy. Let UI structure be the empathy." Users are often elderly, emotional, and unfamiliar with technology. They may be planning a funeral for a loved one who has just died. Design must feel like a trusted advisor, not a sales platform. Every element that demands attention should earn it. Silence and space are design tools. - -## Diagnostic Checks - -Work through each check systematically. For each issue found, note the problem, then fix it. - -### 1. Aggressive Colour Treatment - -- **Error states must NOT use aggressive red** — FA uses a softer copper/warm treatment for errors (per D024) -- Check for bright, saturated reds (#ff0000, #e53935, MUI error.main defaults) in error messages, validation, or alerts -- Replace with the FA copper error palette from the theme (`palette.error.main` should already be the soft treatment) -- Warning states should also be warm, not harsh yellow/orange -- Success states should be muted green, not vivid/celebratory -- Check that semantic colours come from the theme, not hardcoded aggressive values - -### 2. High Saturation Where Muted Would Be Better - -- Scan for highly saturated colours that draw disproportionate attention -- Background colours should be muted — surfaces use the warm neutral palette, not bright fills -- Accent colours work because they are rare (60-30-10 rule) — if accent is used liberally, it stops working -- Icons and decorative elements should use muted tones unless they serve a functional purpose -- Check that the warm gold/copper brand palette is cohesive — no jarring colour outliers - -### 3. Competing Visual Weights - -- Look for multiple bold or heavy elements fighting for attention in the same view -- There should be one clear primary focal point — if multiple elements scream for attention, quiet the secondary ones -- Bold text should be used for emphasis, not as default — if everything is bold, nothing is -- Check for multiple large/heavy headings at the same level competing with each other -- Reduce weight on supporting elements (metadata, labels, secondary info) to let primary content breathe - -### 4. Insufficient Whitespace - -- Check padding and margins — grief-sensitive design needs generous breathing room -- Cards, sections, and content blocks should have ample internal padding -- Vertical spacing between sections should feel restful, not cramped -- Dense layouts feel overwhelming for users in emotional distress — space creates calm -- Check that spacing values come from the theme spacing scale, and lean toward the generous end - -### 5. Urgent Animations and Transitions - -- Animations should feel gentle, not snappy or urgent -- Check for bounce/elastic easing — replace with ease-out or ease-in-out -- Transition durations should be moderate (200-400ms for UI, longer for content reveals) -- No attention-grabbing animations (pulse, shake, flash) — these feel demanding -- Loading states should feel patient, not frantic -- If an animation can be removed without losing meaning, consider removing it - -### 6. Transactional Copy - -- Copy should feel empathetic and guiding, not sales-driven or transactional -- Check button labels: "Buy Now", "Add to Cart", "Submit" feel transactional — prefer "Continue", "Next Step", "Confirm Details" -- Check headings: avoid language that feels like a sales funnel ("Choose Your Package", "Upgrade", "Best Value") -- Error messages should be gentle and helpful, never blaming ("Something went wrong" not "You entered an invalid...") -- Avoid urgency language ("Limited time", "Act now", "Don't miss out") — this is deeply inappropriate in a grief context -- Pricing should be presented transparently, not with sales psychology (no crossed-out prices, no "savings" badges) -- Check for placeholder/lorem text that may have a casual or inappropriate tone - -### 7. CTA Hierarchy - -- There should be ONE clear primary CTA per view/section — not multiple competing calls to action -- Secondary actions should be visually distinct (outlined, text-only) not just smaller versions of primary buttons -- If there are more than 2 CTAs visible simultaneously, evaluate whether some can be demoted or removed -- The primary CTA should feel inviting, not pressuring — warm brand colour, not aggressive contrast -- Check that button hierarchy uses theme variants correctly (contained for primary, outlined for secondary, text for tertiary) - -## Fix Process - -For each issue found: - -1. **Identify** the file, line, and current value -2. **Assess emotional impact** — how does this element feel to a grieving user? -3. **Determine the quieter alternative** — what change reduces noise while preserving function? -4. **Apply the fix** — update colours, weights, spacing, copy, or animation values -5. **Verify** the fix doesn't make the element invisible or non-functional — quiet does not mean hidden - -## Report Format - -After fixing, present a summary: - -### Quiet Pass Summary - -| Check | Status | Issues Found | Issues Fixed | -|-------|--------|-------------|-------------| -| Aggressive Colours | pass/warn/fail | N | N | -| High Saturation | pass/warn/fail | N | N | -| Competing Weights | pass/warn/fail | N | N | -| Whitespace | pass/warn/fail | N | N | -| Animations/Transitions | pass/warn/fail | N | N | -| Transactional Copy | pass/warn/fail | N | N | -| CTA Hierarchy | pass/warn/fail | N | N | - -### Emotional Tone Assessment - -Brief statement on the overall emotional register of the component: -- Does it feel like a **trusted advisor** or a **sales platform**? -- Would a grieving family member feel **supported** or **pressured**? -- Is the design **calm** or **demanding**? - -### Changes Made - -For each fix applied: -- **What changed**: Brief description -- **File**: Path and relevant line(s) -- **Before/After**: The old and new values -- **Why**: How this change serves the grief-sensitive context - -### Remaining Concerns - -Any issues that need design input, copy review, or are outside the scope of a quieting pass. - -**NEVER**: Use aggressive red for error states. Add urgency language or sales psychology. Make everything equally loud. Remove functional affordances in the name of minimalism. Ignore that real people in real pain will use this interface. diff --git a/.claude/skills/review-component/SKILL.md b/.claude/skills/review-component/SKILL.md deleted file mode 100644 index 014e014..0000000 --- a/.claude/skills/review-component/SKILL.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: review-component -description: Review a component against design system conventions -argument-hint: "[ComponentName]" ---- - -Review a component against FA Design System conventions and report pass/fail for each check. - -**Component to review:** $ARGUMENTS - -**Instructions:** -1. Read `docs/conventions/component-conventions.md` for the rules -2. Read `docs/conventions/token-conventions.md` for token usage rules -3. Read the component source file in `src/components/` -4. Read the component's Storybook stories -5. Reference `docs/reference/vercel/react-best-practices.md` for React performance patterns (optional, for deeper code quality review) - -**Check each of these and report pass/fail:** - -### Code quality -- [ ] Component uses TypeScript with proper types -- [ ] Props interface exported with JSDoc on every prop -- [ ] Uses `React.forwardRef` for interactive elements -- [ ] Accepts and forwards `sx` prop -- [ ] Uses `shouldForwardProp` for custom props on styled components - -### Theme compliance -- [ ] NO hardcoded colours — all from `theme.palette.*` -- [ ] NO hardcoded spacing — all from `theme.spacing()` -- [ ] NO hardcoded typography — all from `theme.typography.*` -- [ ] NO hardcoded shadows — all from `theme.shadows` -- [ ] NO hardcoded border radius — all from `theme.shape.*` - -### Accessibility -- [ ] Minimum 44px touch target on mobile -- [ ] Visible focus indicator (focus-visible) -- [ ] Appropriate ARIA attributes -- [ ] Disabled state uses `aria-disabled` -- [ ] Colour contrast meets WCAG 2.1 AA - -### Storybook coverage -- [ ] Default story -- [ ] All variants story -- [ ] All sizes story (if applicable) -- [ ] Disabled state -- [ ] Loading state (if applicable) -- [ ] Long content / overflow -- [ ] autodocs tag present - -### Interactive states (ref: docs/reference/impeccable/interaction-design.md) -- [ ] Default (resting) state is styled -- [ ] Hover state provides visual feedback (not just cursor change) -- [ ] Focus-visible state is distinct from hover (keyboard users never see hover) -- [ ] Active/pressed state feels responsive -- [ ] Disabled state is visually diminished but still distinguishable -- [ ] Transitions use 150ms ease-in-out (FA convention) - -### Design anti-patterns (ref: docs/reference/impeccable/frontend-design-skill.md) -- [ ] No grey text on coloured backgrounds (use a shade of the background colour instead) -- [ ] No cards nested inside cards (flatten hierarchy with spacing/typography) -- [ ] No identical card grids with zero variation (vary content, size, or emphasis) -- [ ] No bounce/elastic easing (use ease-out-quart or ease-in-out) -- [ ] Not every button is primary (use variant hierarchy: contained > soft > outlined > text) -- [ ] No redundant copy (headings don't restate content below them) -- [ ] No glassmorphism/blur used purely as decoration -- [ ] Whitespace is intentional, not leftover - -**Report format:** List each check with pass/fail and specific issues found. End with a summary and recommended fixes. diff --git a/.claude/skills/status/SKILL.md b/.claude/skills/status/SKILL.md deleted file mode 100644 index 4c59324..0000000 --- a/.claude/skills/status/SKILL.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: status -description: Report current status of tokens, components, and build health ---- - -Report the current status of the FA Design System. - -**Instructions:** -1. Read `docs/memory/session-log.md` — summarise recent work -2. Read `docs/memory/component-registry.md` — count components by status (planned, in-progress, review, done) -3. Read `docs/memory/token-registry.md` — summarise token coverage -4. Read `docs/memory/decisions-log.md` — count decisions logged -5. Check if Storybook is running (curl http://localhost:6006) -6. Check if tokens build successfully (`npm run build:tokens`) - -**Report format:** -``` -## FA Design System Status - -### Tokens -- Primitives: [count] defined -- Semantic: [count] defined -- Component: [count] defined - -### Components -- Done: [list] -- In progress: [list] -- Planned: [list] - -### Recent activity -- [last session summary] - -### Next steps -- [recommended next actions] -``` diff --git a/.claude/skills/sync-tokens/SKILL.md b/.claude/skills/sync-tokens/SKILL.md deleted file mode 100644 index 1852937..0000000 --- a/.claude/skills/sync-tokens/SKILL.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: sync-tokens -description: Rebuild CSS and JS outputs from token JSON sources ---- - -Synchronise design tokens — rebuild CSS and JS outputs from token JSON sources. - -Use this after token JSON files have been edited manually or after `/create-tokens`. This is a maintenance command — it does NOT create new tokens (use `/create-tokens` for that). - -Use the token-architect agent to handle this task. - -**Instructions for the agent:** -1. Read `docs/memory/token-registry.md` to understand current token state -2. Validate all token JSON files have required fields (`$value`, `$type`, `$description`) -3. Run `npm run build:tokens` to regenerate: - - `src/theme/generated/tokens.css` (CSS custom properties) - - `src/theme/generated/tokens.js` (JS ES6 module) - - `tokens/export/tokens-flat.json` (flat JSON export) -4. Check that `src/theme/index.ts` is consuming the generated tokens correctly -5. If any tokens were added/changed since the theme was last updated, update `src/theme/index.ts` -6. Report what was generated and any issues found -7. Update `docs/memory/token-registry.md` if it's out of date diff --git a/.claude/skills/typeset/SKILL.md b/.claude/skills/typeset/SKILL.md deleted file mode 100644 index e303997..0000000 --- a/.claude/skills/typeset/SKILL.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -name: typeset -description: Typography refinement — checks hierarchy consistency, line length, line height, font weight, and mobile readability across a component or area. -user-invocable: true -argument-hint: "[component or area to typeset]" ---- - -Run a typography-focused review on a component or area, then **fix issues found**. This is assessment AND fix — diagnose problems, then apply corrections. - -**Target:** $ARGUMENTS - -## Preparation - -1. Read `docs/design-system.md` for FA typography conventions -2. Read `docs/memory/token-registry.md` for the current type scale and weight decisions -3. Read `docs/memory/decisions-log.md` for typography-related decisions (especially D017, D019) -4. Read the target component/area source files and stories -5. Reference `docs/reference/impeccable/typography.md` for detailed typographic guidelines - -**FA context reminder**: Funeral Arranger serves families often in grief or distress. Many users are elderly, on mobile, and reading under emotional strain. Typography must prioritise readability and calm hierarchy over visual flair. Warmth comes through the serif display type (Noto Serif SC) at display sizes — not through decorative overuse. Body text must be effortlessly readable. - -## Diagnostic Checks - -Work through each check systematically. For each issue found, note the problem, then fix it. - -### 1. Hierarchy Consistency - -- Same semantic level must have the same visual treatment everywhere in the target -- Heading levels should use the correct MUI typography variant (h1-h6, subtitle1/2, body1/2) -- No more than 3-4 distinct text sizes visible at once (muddy hierarchy = too many similar sizes) -- Size jumps between levels should be clear — avoid sizes too close together (e.g., 14px, 15px, 16px) -- Check that the modular scale from the token system is followed consistently - -### 2. Line Length (Measure) - -- Body text should be constrained to 45-75 characters per line (`max-width: 65ch` is a good default) -- If body text runs full-width on desktop, add a `max-width` using `ch` units -- Narrow columns (sidebars, cards) may go below 45ch — tighten line-height to compensate -- Wide text blocks strain reading comprehension, especially for elderly/distressed users - -### 3. Line Height - -- Body text: 1.5-1.6 line-height for comfortable reading -- Headings: tighter line-height (1.1-1.3) since larger text needs less relative leading -- Line-height scales inversely with line length — narrow columns need tighter leading, wide columns need more -- Light text on dark backgrounds needs ~0.05-0.1 more line-height than normal -- Vertical rhythm: spacing values should relate to the base line-height unit - -### 4. Font Weight Consistency - -- **Body weight must be Medium 500** (per D019) — check that body text is not using 400 (Regular) -- Headings should use consistent weights within tiers (all h2s same weight, all h3s same weight) -- Avoid more than 3 font weights in the same view — too many competing weights create noise -- Bold should be used for emphasis, not as a default state for UI elements -- Check that weight values come from the theme, not hardcoded - -### 5. Display Font Usage - -- **Noto Serif SC is for display variants only** (per D017) — hero text, display headings, featured quotes -- Noto Serif SC must NOT be used for standard headings (h1-h6 in regular UI contexts) -- Standard headings use the sans-serif stack (Figtree or system font) -- If the serif font appears on a regular heading, replace it with the sans-serif variant - -### 6. Mobile Font Size Adequacy - -- Body text minimum 14px on mobile (16px preferred, per impeccable guidelines) -- Small/caption text minimum 12px -- Touch-target text (buttons, links in body) must be large enough to tap accurately -- Check that `rem` units are used (not `px`) so text respects browser zoom settings -- Verify no `user-scalable=no` in viewport meta (breaks accessibility) - -### 7. Token Compliance - -- All font sizes should come from theme.typography variants, not hardcoded values -- All font weights should come from theme tokens -- All line-heights should come from theme tokens -- Font family should come from theme, never hardcoded strings -- Check for inline `style` props that override typography tokens - -## Fix Process - -For each issue found: - -1. **Identify** the file, line, and current value -2. **Reference** the correct token/theme value it should use -3. **Apply the fix** — update the component source to use the correct theme value -4. **Verify** the fix maintains visual intent (don't blindly replace — ensure the result looks right) - -## Report Format - -After fixing, present a summary: - -### Typography Health Summary - -| Check | Status | Issues Found | Issues Fixed | -|-------|--------|-------------|-------------| -| Hierarchy Consistency | pass/warn/fail | N | N | -| Line Length | pass/warn/fail | N | N | -| Line Height | pass/warn/fail | N | N | -| Font Weight | pass/warn/fail | N | N | -| Display Font Usage | pass/warn/fail | N | N | -| Mobile Font Size | pass/warn/fail | N | N | -| Token Compliance | pass/warn/fail | N | N | - -### Changes Made - -For each fix applied: -- **What changed**: Brief description -- **File**: Path and relevant line(s) -- **Before/After**: The old and new values - -### Remaining Concerns - -Any issues that need design input or are outside the scope of a typesetting pass. - -**NEVER**: Hardcode font sizes in px. Use the serif display font (Noto Serif SC) for regular headings. Set body weight to 400 (Regular) — FA uses 500 (Medium). Remove typography tokens in favour of inline styles. Ignore mobile readability. diff --git a/.claude/skills/write-stories/SKILL.md b/.claude/skills/write-stories/SKILL.md deleted file mode 100644 index 1b66f63..0000000 --- a/.claude/skills/write-stories/SKILL.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: write-stories -description: Write or update Storybook stories for a component -argument-hint: "[ComponentName]" ---- - -Write or update Storybook stories for an existing component. - -Use the story-writer agent to handle this task. The component to document: - -**Component:** $ARGUMENTS - -**Instructions for the agent:** -1. Read `docs/conventions/component-conventions.md` for story standards -2. Read the component source file at `src/components/` (check atoms/, molecules/, organisms/) -3. Create or update `{ComponentName}.stories.tsx` in the component's folder -4. Cover ALL items in the story coverage checklist: - - [ ] Default state with typical content - - [ ] All visual variants side by side - - [ ] All sizes side by side (if applicable) - - [ ] Disabled state - - [ ] Loading state (if applicable) - - [ ] Error state (if applicable) - - [ ] Long content / content overflow - - [ ] Empty/minimal content - - [ ] With and without optional elements (icons, badges, etc.) -5. Every story meta MUST include `tags: ['autodocs']` -6. Verify the component renders correctly in Storybook at http://localhost:6006 -7. Update `docs/memory/session-log.md` when done diff --git a/.claude/skills/write-tests/SKILL.md b/.claude/skills/write-tests/SKILL.md deleted file mode 100644 index 99bc370..0000000 --- a/.claude/skills/write-tests/SKILL.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -name: write-tests -description: Write or update tests for a component — determines whether it needs unit tests (Vitest), interaction tests (Storybook play), or both, then generates appropriate test code. -user-invocable: true -argument-hint: "[ComponentName]" ---- - -Write tests for the specified component. - -**Component:** $ARGUMENTS - -## Preparation - -1. Read `docs/conventions/component-conventions.md` for component patterns -2. Read the component source file in `src/components/` -3. Read the component's existing Storybook stories -4. Check `docs/memory/component-registry.md` for component status and composition - -## Determine Test Strategy - -Categorise the component: - -### Interactive components (need Storybook `play` functions) -Components with user interactions: clicks, toggles, keyboard navigation, form inputs, selection state changes. - -**Examples:** Button, Input, SearchBar, ServiceOption, AddOnOption, Switch, Radio, FuneralFinder - -For these, add `play` functions to existing stories: -```tsx -import { expect, userEvent, within } from '@storybook/test'; - -export const ClickTest: Story = { - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - const button = canvas.getByRole('button'); - await userEvent.click(button); - await expect(button).toBeVisible(); - }, -}; -``` - -**What to test in `play` functions:** -- Click/tap fires expected callback -- Disabled state prevents interaction -- Keyboard navigation works (Enter, Space, Arrow keys) -- Loading state disables interaction -- Error states show correct feedback -- Selection state changes visually -- Form validation triggers on submit - -### Logic-heavy components (need Vitest unit tests) -Components with significant internal logic: conditional rendering, validation, state machines, computed values. - -**Examples:** FuneralFinder (validation logic), PackageDetail (price calculations), ServiceSelector (selection management) - -Create `{ComponentName}.test.tsx` alongside the component: -```tsx -import { describe, it, expect } from 'vitest'; -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { ThemeProvider } from '@mui/material/styles'; -import theme from '../../../theme'; -import { ComponentName } from './ComponentName'; - -const renderWithTheme = (ui: React.ReactElement) => - render({ui}); - -describe('ComponentName', () => { - it('renders with default props', () => { - renderWithTheme(); - expect(screen.getByRole('...')).toBeInTheDocument(); - }); -}); -``` - -**What to test in Vitest:** -- Conditional rendering logic (shows/hides elements based on props) -- Validation rules (required fields, format checks) -- Callback props fire with correct arguments -- Accessibility: correct ARIA roles and states -- Edge cases: empty data, maximum values, missing optional props - -### Display-only components (minimal testing needed) -Components that only render static content from props: Typography, Badge, Divider, Card (non-interactive). - -For these, stories ARE the tests. Ensure stories cover all variants. No additional test files needed unless there's conditional rendering logic. - -## After Writing Tests - -1. Run `npm run test` to verify Vitest tests pass -2. If Storybook `play` functions were added, verify they work in Storybook's test panel -3. Update `docs/memory/component-registry.md` with test status note - -## Rules - -- Always wrap components in `ThemeProvider` with FA theme in Vitest tests -- Use `screen.getByRole()` over `getByTestId()` — test what the user sees -- Test behaviour, not implementation — don't test internal state directly -- Keep tests focused: one assertion per test where practical -- Don't test MUI internals — only test our component's API -- Don't snapshot test — snapshots are too brittle for an evolving design system diff --git a/.mcp.json b/.mcp.json deleted file mode 100644 index 891556b..0000000 --- a/.mcp.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "mcpServers": { - "figma-remote-mcp": { - "type": "http", - "url": "https://mcp.figma.com/mcp" - } - } -} diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 89df72f..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,113 +0,0 @@ -# FA 2.0 Design System - -## Project overview - -Rebuilding the Funeral Arranger (funeralarranger.com.au) design system using a -code-first approach. Parsons (H.Parsons Funeral Directors) is the client. FA is -an Australian funeral planning platform — the design language must be warm, -professional, trustworthy, and calm. Users are often in distress. - -## Tech stack - -- React 18 + TypeScript -- Material UI (MUI) v5 -- Storybook 8+ with autodocs -- Style Dictionary for token transformation -- W3C DTCG token format (2025.10 stable spec) -- Chromatic for Storybook hosting (later) - -## Architecture - -**Source of truth:** Token JSON files in `tokens/` (DTCG format) -**Flow:** Token JSON → Style Dictionary → MUI theme + CSS vars → React components → Storybook - -### Token tiers -1. **Primitives** (`tokens/primitives/`): Raw values — hex, px, font names, scales -2. **Semantic** (`tokens/semantic/`): Design intent — `color.text.primary`, `color.surface.default` -3. **Component** (`tokens/component/`): Per-component — `button.background.default` - -### Component tiers (atomic design) -1. **Atoms** (`src/components/atoms/`): Button, Input, Typography, Badge, Icon, Avatar, Divider, Chip, Card, Link -2. **Molecules** (`src/components/molecules/`): SearchBar, PriceCard, ServiceOption, FormField -3. **Organisms** (`src/components/organisms/`): ServiceSelector, PricingTable, ArrangementForm, Navigation - -## Critical rules - -1. **Every component MUST consume the MUI theme** — never hardcode colours, spacing, typography, or shadows -2. **Every token MUST have a `$description`** — this is how agents maintain context about design intent -3. **Always read docs/design-system.md** before creating or modifying anything -4. **Always check docs/memory/** before starting work — these files contain decisions and state from previous sessions -5. **Always update docs/memory/** after completing work — log what was done, decisions made, and open questions -6. **Run `npm run build:tokens`** after any token JSON change -7. **Verify in Storybook** before marking any component done -8. **Follow the component lifecycle** — see `docs/reference/component-lifecycle.md` for the full quality gate sequence (build → QA → polish → present → iterate → normalize → preflight → commit) -9. **Commit and push after completing each unit of work** — see Git workflow below - -## Git workflow - -**Remote:** Gitea at `http://192.168.50.211:3000/richie/ParsonsFA.git` (credentials stored via git credential helper) - -**After completing each unit of work** (a component, a token change, a bug fix, etc.): -1. Stage the changed files (`git add` — prefer naming specific files over `git add -A`) -2. Commit with a clear message describing what was done -3. Push to origin (`git push`) - -This is **not optional** — the user relies on the git history for rollback safety. Each commit should represent a coherent, working state (Storybook builds, TypeScript compiles). Do not batch multiple unrelated changes into a single commit. - -**Commit message format:** -``` -Short summary (imperative mood, <70 chars) - -- Bullet points with detail if needed -- Reference decision IDs (D001, D002...) when relevant - -Co-Authored-By: Claude Opus 4.6 (1M context) -``` - -**Branch strategy:** All work on `main` for now. Feature branches when the project grows. - -## Memory system - -This project uses structured markdown files for cross-session memory. - -**Before starting any work, read these files:** -- `docs/memory/decisions-log.md` — All design decisions with rationale -- `docs/memory/component-registry.md` — Status of every component (planned/in-progress/done) -- `docs/memory/token-registry.md` — All tokens with their current values and usage notes -- `docs/memory/session-log.md` — Recent sessions (last 2-3); older sessions in `docs/memory/archive/` - -**Session startup — proactive review pass (do this automatically):** -Check `docs/reference/retroactive-review-plan.md` for the current review state. If -there are tiers or components that haven't been reviewed yet, run the next review -step (typically `/normalize {tier}` or `/audit {component}`) at the start of the -session before the user's main request. Keep this to ~30-60 min, then report -findings and shift to whatever the user wants to work on. This is "morning -housekeeping" — the user has approved this and expects it to happen without asking. - -**After completing work, update:** -- The relevant memory files with what changed -- `docs/memory/session-log.md` with a summary of what was accomplished and next steps - -## MCP servers - -- **Figma remote MCP** (`figma-remote-mcp`): Read FA 1.0 designs, extract design context -- **Storybook MCP** (`storybook`): Query component library for available components and props - -Setup instructions in `docs/reference/mcp-setup.md`. - -## File conventions - -- Component folders: PascalCase (`Button/`, `PriceCard/`) -- Token files: camelCase (`colours.json`, `typography.json`) -- Each component folder contains: `ComponentName.tsx`, `ComponentName.stories.tsx`, `index.ts` -- CSS custom properties prefix: `--fa-` (e.g., `--fa-color-brand-primary`) -- MUI theme paths: follow MUI conventions (`palette.primary.main`) - -## Naming conventions for tokens - -See `docs/conventions/token-conventions.md` for the full specification. - -Quick reference: -- Primitives: `color.blue.500`, `spacing.4`, `fontSize.base` -- Semantic: `color.text.primary`, `color.surface.default`, `color.interactive.default` -- Component: `button.background.default`, `button.background.hover` diff --git a/GEMINI.md b/GEMINI.md deleted file mode 100644 index 6910db8..0000000 --- a/GEMINI.md +++ /dev/null @@ -1,58 +0,0 @@ -# FA 2.0 Design System — Antigravity Rules - -## Project context - -Funeral Arranger (funeralarranger.com.au) design system rebuild. Parsons is the -client. The design language must be warm, professional, trustworthy, and calm. -Users are often in distress. - -## Tech stack - -- React 18 + TypeScript -- Material UI (MUI) v5 -- Storybook 8+ (running on localhost:6006) -- Style Dictionary for token transformation -- W3C DTCG token format - -## Hard rules - -1. **Never hardcode colours, spacing, typography, or shadows** — always consume the MUI theme (`theme.palette.*`, `theme.spacing()`, `theme.typography.*`) or CSS custom properties (`var(--fa-*)`) -2. **Never use raw hex values in components** — map to semantic tokens -3. **Follow atomic design tiers:** atoms → molecules → organisms → templates → pages -4. **Component folders:** PascalCase, each contains `ComponentName.tsx`, `ComponentName.stories.tsx`, `index.ts` -5. **Token files:** camelCase in `tokens/` directory (primitives → semantic → component tiers) -6. **CSS custom properties prefix:** `--fa-` -7. **Error styling uses copper (#B0610F)** not red — this is intentional for grief-sensitive context -8. **Copy tone:** warm but not gushy. Understated empathy. Let UI structure be the empathy. - -## Token access convention - -- Semantic tokens: `theme.palette.*`, `theme.typography.*`, `theme.spacing()` -- Component tokens: `var(--fa-component-property-state)` -- Never mix — semantic via theme, component via CSS vars - -## Storybook - -Dev server runs on `localhost:6006`. When verifying components visually, navigate -to the specific story URL. Story IDs follow the pattern: -`/story/{tier}-{componentname}--{variantname}` - -## File structure - -``` -src/components/atoms/ — Button, Input, Typography, Card, etc. -src/components/molecules/ — SearchBar, PriceCard, ServiceOption, etc. -src/components/organisms/ — Navigation, Footer, ArrangementDialog, etc. -src/components/templates/ — WizardLayout -src/components/pages/ — IntroStep, ProvidersStep, etc. (wizard steps) -tokens/primitives/ — Raw values (hex, px, font names) -tokens/semantic/ — Design intent (color.text.primary) -tokens/component/ — Per-component tokens -``` - -## When making visual changes - -1. Make the code change -2. Open the Storybook story in the browser to verify -3. Screenshot and check spacing, alignment, visual weight -4. Self-correct if something looks off before presenting diff --git a/QUICKSTART.md b/QUICKSTART.md deleted file mode 100644 index 4efe4bc..0000000 --- a/QUICKSTART.md +++ /dev/null @@ -1,106 +0,0 @@ -# FA Design System — Quick Start - -## What you've got - -A complete Claude Code project scaffold with: - -- **3 agents**: token-architect, component-builder, story-writer -- **6 slash commands**: /create-tokens, /build-atom, /build-molecule, /sync-tokens, /status, /review-component -- **4 memory files**: session-log, decisions-log, component-registry, token-registry -- **2 convention docs**: token-conventions, component-conventions -- **Living design system spec**: docs/design-system.md -- **MCP config**: Figma remote MCP pre-configured -- **Full React + MUI + Storybook + Style Dictionary setup** - -## Setup (5-10 minutes) - -```bash -# 1. Extract the project -tar -xzf fa-design-system-scaffold.tar.gz -cd fa-project - -# 2. Run the bootstrap script -chmod +x bootstrap.sh -./bootstrap.sh - -# 3. Set up Figma MCP (in Claude Code) -claude mcp add --transport http figma-remote-mcp https://mcp.figma.com/mcp -# Restart Claude Code, then /mcp → authenticate with Figma - -# 4. Start Storybook (separate terminal) -npm run storybook -``` - -## Your workflow - -### Step 1: Create tokens -``` -claude -/create-tokens I want to create the FA design system. Here are my brand colours: [paste hex values or attach reference images]. Fonts: [your font choices]. The platform serves Australian families planning funerals — warm, trustworthy, calm aesthetic. -``` - -### Step 2: Build atoms (one at a time) -``` -/build-atom Button -# Review in Storybook at http://localhost:6006 -# Provide feedback, iterate - -/build-atom Input -/build-atom Typography -/build-atom Card -# ... etc -``` - -### Step 3: Build molecules -``` -/build-molecule PriceCard -/build-molecule FormField -# ... etc -``` - -### Check status anytime -``` -/status -``` - -### Review a component -``` -/review-component Button -``` - -## How memory works - -Every agent reads these files before starting work and updates them after: - -| File | Purpose | -|------|---------| -| `docs/memory/session-log.md` | What happened last session, what's next | -| `docs/memory/decisions-log.md` | Every design decision with rationale | -| `docs/memory/component-registry.md` | Status of every component | -| `docs/memory/token-registry.md` | All tokens with values and usage | - -This means you can close Claude Code, come back tomorrow, and the agents -will pick up exactly where you left off. - -## File structure - -``` -fa-project/ -├── CLAUDE.md ← Claude Code reads this every session -├── .claude/ -│ ├── agents/ ← Agent definitions -│ ├── commands/ ← Slash commands -│ └── skills/ ← Shared knowledge -├── .mcp.json ← MCP server config -├── docs/ -│ ├── memory/ ← Cross-session memory -│ ├── conventions/ ← Rules agents follow -│ ├── reference/ ← Setup guides -│ └── design-system.md ← Living design spec -├── tokens/ ← DTCG token JSON (source of truth) -├── style-dictionary/ ← Token build config -├── src/ -│ ├── theme/ ← MUI theme + generated CSS vars -│ └── components/ ← Atoms, molecules, organisms -└── .storybook/ ← Storybook config with theme provider -``` diff --git a/bootstrap.sh b/bootstrap.sh deleted file mode 100755 index a70da11..0000000 --- a/bootstrap.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/bash -# FA Design System — Bootstrap Script -# Run this once after cloning/copying the project scaffold to set everything up. - -set -e - -echo "╔══════════════════════════════════════════════╗" -echo "║ FA Design System — Project Bootstrap ║" -echo "╚══════════════════════════════════════════════╝" -echo "" - -# ─── 1. Install dependencies ───────────────────────────────────────────────── -echo "📦 Installing dependencies..." -npm install - -# ─── 2. Initialise Storybook (if not already configured) ───────────────────── -echo "" -echo "📖 Checking Storybook setup..." -if [ ! -d ".storybook" ]; then - echo " .storybook config not found. Creating configuration..." - mkdir -p .storybook - cat > .storybook/main.ts << 'MAINEOF' -import type { StorybookConfig } from '@storybook/react-vite'; - -const config: StorybookConfig = { - stories: ['../src/**/*.stories.@(ts|tsx)'], - addons: [ - '@storybook/addon-essentials', - ], - framework: { - name: '@storybook/react-vite', - options: {}, - }, - docs: { - autodocs: 'tag', - }, - viteFinal: async (config) => { - return config; - }, -}; - -export default config; -MAINEOF - cat > .storybook/preview.tsx << 'PREVEOF' -import React from 'react'; -import type { Preview } from '@storybook/react'; -import { ThemeProvider } from '@mui/material/styles'; -import CssBaseline from '@mui/material/CssBaseline'; -import { theme } from '../src/theme'; - -const preview: Preview = { - decorators: [ - (Story) => ( - - - - - ), - ], - parameters: { - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, -}; - -export default preview; -PREVEOF - echo " ✓ .storybook config created." -else - echo " .storybook config found. Skipping." -fi - -# ─── 3. Build initial token output ─────────────────────────────────────────── -echo "" -echo "🎨 Building placeholder token output..." -mkdir -p src/theme/generated -mkdir -p tokens/export -# Style Dictionary needs at least one source file to build -if [ ! -f "tokens/primitives/colours.json" ]; then - echo '{}' > tokens/primitives/colours.json - echo '{}' > tokens/primitives/typography.json - echo '{}' > tokens/primitives/spacing.json - echo '{}' > tokens/primitives/effects.json - echo '{}' > tokens/semantic/colours.json - echo '{}' > tokens/semantic/typography.json - echo '{}' > tokens/semantic/spacing.json - echo " Created empty token placeholder files." -fi - -# ─── 4. TypeScript check ───────────────────────────────────────────────────── -echo "" -echo "🔍 Running TypeScript check..." -npx tsc --noEmit 2>/dev/null && echo " ✓ TypeScript OK" || echo " ⚠ TypeScript errors (expected before tokens are created)" - -# ─── 5. Git init ───────────────────────────────────────────────────────────── -echo "" -if [ ! -d ".git" ]; then - echo "🔧 Initialising git repository..." - git init - git add -A - git commit -m "Initial scaffold: FA Design System project structure" - echo " ✓ Git initialised with initial commit" -else - echo "🔧 Git already initialised." -fi - -# ─── 6. Summary ────────────────────────────────────────────────────────────── -echo "" -echo "╔══════════════════════════════════════════════╗" -echo "║ ✓ Bootstrap complete! ║" -echo "╚══════════════════════════════════════════════╝" -echo "" -echo "Next steps:" -echo "" -echo " 1. SET UP FIGMA MCP:" -echo " claude mcp add --transport http figma-remote-mcp https://mcp.figma.com/mcp" -echo " Then restart Claude Code and authenticate via /mcp" -echo "" -echo " 2. START CLAUDE CODE:" -echo " cd $(pwd)" -echo " claude" -echo "" -echo " 3. CHECK STATUS:" -echo " /status" -echo "" -echo " 4. CREATE YOUR TOKENS:" -echo " /create-tokens [provide brand colours, fonts, and context]" -echo "" -echo " 5. START STORYBOOK (in a separate terminal):" -echo " npm run storybook" -echo "" -echo " 6. BUILD YOUR FIRST ATOM:" -echo " /build-atom Button" -echo "" diff --git a/docs/memory/archive/sessions-through-2026-03-26.md b/docs/memory/archive/sessions-through-2026-03-26.md deleted file mode 100644 index 14609db..0000000 --- a/docs/memory/archive/sessions-through-2026-03-26.md +++ /dev/null @@ -1,1008 +0,0 @@ - -### Session 2026-03-26d — FuneralFinder v2 build - -**Agent(s):** Claude Opus 4.6 (1M context) - -**Work completed:** -- Built FuneralFinderV2 from scratch — completely different approach from v1 (quick-form vs stepped wizard) -- 4-step vertical form with 48px numbered circles (brand-200 default → brand-500 completed) and 3px connector lines -- Steps: (1) Intent (3 options), (2) Planning for (conditional auto-set for arrange-now), (3) Funeral type (5 options), (4) Location -- Sequential unlock logic: each step enables only when the previous is filled -- Labels use brand-700 copper when active, text.disabled when locked -- Selects match Input medium height (48px) via py: 14px -- Display serif heading + body2 subheading with full-width divider -- Default contained CTA (copper), disabled until location has 3+ chars -- Trust signal "Free to use · No obligation" below CTA -- Focus rings suppressed (subtle brand-400 border only) -- Full accessibility: role="search", aria-required, aria-label on all fields -- Multiple iteration rounds incorporating user feedback on sizing, alignment, colours, spacing, and layout -- Ran /critique (33/40 Good) and /audit (18/20 Excellent) — fixed all P0/P1 issues - -**Decisions made:** -- v2 keeps v1 alongside — both exported from index.ts for comparison -- Step circles use brand-200 warm fill (not neutral grey) for palette cohesion -- "Plan a funeral for someone expected to pass soon" softened to "Plan ahead for someone who is unwell" -- Connector lines use ::after on each StepCircle rather than container ::before (starts from circle bottom, not above) -- Location input uses no icon, matches select styling (py: 14px, fontSize: 0.875rem) - -**Open questions:** -- Which version (v1 or v2) to proceed with for production? May keep both and A/B test -- Connector line height (60px) is a magic number — works for single-line labels but would need adjustment if labels wrap - -**Next steps:** -- User to review in Storybook and decide on v1 vs v2 direction -- If v2 chosen: add location autocomplete, consider progress summary state -- Update docs/reference/ with v2 flow logic doc (similar to funeral-finder-logic.md for v1) - ---- - -### Session 2026-03-26c — FuneralFinder v1 refinement and completion - -**Agent(s):** Claude Opus 4.6 (1M context) - -**Work completed:** -- Redesigned FuneralFinder from a "dump everything in step 3" pattern to a full stepped conversational flow -- Every decision is now its own step with CompletedRow collapse (intent → planning-for → type+preferences → service → location+CTA) -- CTA ("Find funeral providers") and location input are always visible at the bottom — not gated behind steps -- Implemented smart defaults: minimum search requirements are intent + location; type/service/themes default to "show all" -- Added funeral type options: Cremation, Burial, Water Burial (QLD only), Explore All (as a proper TypeCard) -- Added service preference step (conditional): With a service / No service / I'm flexible -- Added theme preferences (eco-friendly, budget-friendly, religious specialisation) as optional sub-option within type step -- Created StepHeading sub-component (bodyLg, centered) for clear hierarchy vs card labels (body1/body2) -- Added loading prop for CTA button, location validation (3+ chars with error state) -- Added Divider under subheading, h2 display heading, generous CompletedRow spacing (py: 1.5) -- Fixed accessibility: aria-label on Change links, role="alert" on intent prompt, 44px touch targets on all chips -- Removed "Take your time" empathetic message per user preference -- Renamed "ceremony" → "service" throughout, "Without (direct)" → "No service" -- Removed TypeCard descriptions for standard types (Cremation, Burial don't need them) -- Multiple audit/critique cycles: final scores Audit 14/20 (Good), Critique 29/40 (Good) - -**Decisions made:** -- CTA always visible with smart defaults — users can skip optional steps and search with just intent + location -- Stepped flow continues through ALL decisions (not just steps 1-2 like the previous version) -- Theme preferences belong in the type step as a sub-option, not in the location step -- "Where are you looking?" (not "located") to allow searching outside own area -- Step headings use bodyLg centered for visual hierarchy distinct from card labels - -**Open questions:** -- Progress indicator (Step X of Y) — flagged by critique as P2, deferred. Variable step count makes implementation non-trivial. -- Roving tabindex for radiogroups — flagged by audit as P0, deferred. Requires arrow-key handler + tabindex management. -- Location autocomplete — flagged by critique as P2, deferred. Would need suburb/postcode API integration. -- CSS var vs MUI theme accessor consistency — flagged by audit, deferred. Architectural choice to address system-wide. - -**Next steps:** -- FuneralFinder v1 is complete and approved -- Consider building the homepage hero composition as a standalone organism or page template -- ArrangementForm organism is next planned organism (multi-step wizard with StepIndicator) - -### Session 2026-03-24 — Project scaffold setup and hygiene - -**Agent(s):** Manual (no agents invoked — setup phase) - -**Work completed:** -- Fixed missing `.storybook/` directory (main.ts + preview.tsx with MUI ThemeProvider) -- Created `.gitignore` (was missing entirely) -- Created `.mcp.json` with Figma remote MCP config -- Removed malformed `{.claude/agents,.claude/...}` directory tree (bash brace expansion bug) -- Created 3 agent definitions: token-architect, component-builder, story-writer -- Created 8 slash commands: create-tokens, build-atom, build-molecule, build-organism, write-stories, sync-tokens, status, review-component -- Migrated commands from `.claude/commands/` to `.claude/skills//SKILL.md` format with YAML frontmatter -- Fixed **critical** Style Dictionary v4 config: converted from CommonJS to ESM (`StyleDictionary` class API) -- Changed `build:tokens` script from `style-dictionary build --config ...` to `node style-dictionary/config.js` -- Added `"type": "module"` to package.json for ESM support -- Changed SD output from `tokens.ts` to `tokens.js` (Style Dictionary v4 generates JS, not TS) -- Registered `@storybook/addon-designs` in `.storybook/main.ts` (was installed but not configured) -- Added CSS token import to `.storybook/preview.tsx` -- Added Card and Link to CLAUDE.md atom list (were missing) -- Fixed broken Penpot/Storybook MCP references in `docs/reference/mcp-setup.md` -- Improved agent instructions with pre-flight dependency checks, story checklist enforcement, token validation steps, and MUI theme mapping guide -- Created `src/components/{atoms,molecules,organisms}/` directories -- Fixed `bootstrap.sh` to check for `.storybook/` dir instead of `node_modules/@storybook` -- Verified `npm run build:tokens` runs successfully (empty output expected — no tokens yet) -- Verified Storybook runs at http://localhost:6006 - -**Decisions made:** -- Skills use `.claude/skills//SKILL.md` format (not `.claude/commands/`) -- Style Dictionary v4 config is a standalone ESM script run via `node`, not CLI -- British spelling for filenames (`colours.json`), standard `color` namespace for token paths - -**Open questions:** -- Slash commands `/create-tokens` etc. showing "Unknown skill" — may need Claude Code restart to discover newly created skills. User should test after restarting. - -**Next steps:** -- ~~Verify slash commands work after Claude Code restart~~ ✓ Skills working -- ~~Begin Step 1: `/create-tokens` with brand colours, fonts, and reference material~~ ✓ Done - -### Session 2025-03-25 — Token creation (Step 1) - -**Agent(s):** token-architect (via /create-tokens skill) - -**Work completed:** -- Extracted brand colours from user-provided swatch image (12 colours across 3 palettes) -- Reviewed 5 Parsons FA 1.0 Figma screens for colour application context -- Reviewed 2 FA 2.0 Design System Template screens (buttons + inputs) -- Created complete primitive tokens: - - Colour scales (50-950): brand (warm gold), sage (cool grey-green), neutral, red, amber, green, blue + white/black - - Typography: 3 font families (Montserrat, Noto Serif SC, JetBrains Mono), font size scale (xs-4xl + mobile), weights, line heights, letter spacing - - Spacing: 4px-based scale (2px-80px), border radius scale - - Effects: 4 shadow levels, 3 opacity values -- Created complete semantic tokens: - - Colour mappings: text (9 variants), surface (6), border (6), interactive (7), feedback (8) - - Typography roles: display, h1-h4, bodyLarge, body, bodySmall, caption, label, overline — each with font family, size, weight, line height, letter spacing + mobile size overrides - - Spacing: component (xs-lg), layout (gutter, section, page, padding) with mobile/desktop variants -- Fixed Style Dictionary v4.4.0 CSS output: added `usesDtcg: true` flag (required for DTCG format CSS generation) -- Generated outputs: - - CSS: 245 custom properties in `src/theme/generated/tokens.css` with `var()` references for semantic tokens - - JS: 258 named exports in `src/theme/generated/tokens.js` - - JSON: flat export in `tokens/export/tokens-flat.json` -- Updated MUI theme (`src/theme/index.ts`): - - All palette colours mapped from token imports - - All typography variants mapped (h1-h6, body1, body2, subtitle1/2, caption, overline, button) - - 3 custom typography variants added: display, bodyLarge, label (with TS module declarations) - - Responsive font sizes via @media queries for display, h1, h2, h3 - - Component overrides for Button and Card border radius -- Updated docs/design-system.md with actual brand colours, palettes, and font stacks -- Updated docs/memory/decisions-log.md with 8 design decisions (D001-D008) -- Updated docs/memory/token-registry.md with complete token reference - -**Decisions made:** -- D001: Primary brand colour is #BA834E (warm gold from swatch) -- D002: Primary text colour is #2C2E35 (charcoal, not pure black) -- D003: Brand link colour uses #B0610F (copper, meets WCAG AA) -- D004: Sage palette as secondary (calming contrast to warm primary) -- D005: Noto Serif SC for display/H1-H2, Montserrat for H3+ and body -- D006: Warning text uses amber.700 for AA compliance -- D007: Style Dictionary requires usesDtcg: true for CSS output -- D008: Responsive typography via explicit @media queries in MUI theme - -**Open questions:** -- Font name confirmation: user wrote "Not Serif SC" — interpreted as "Noto Serif SC" (Google Font). Needs confirmation. -- brand.500 (#BA834E) has 3.7:1 contrast on white — AA for large text only. Primary buttons use white text on this background, which works for button-sized text. Should we darken the primary CTA colour for better accessibility, or is the current value acceptable? -- Token collision warning: benign collision on `$type: "color"` set in both primitives and semantic colour files. Doesn't affect output. - -**Next steps:** -- ~~Confirm display font name (Noto Serif SC vs something else)~~ -- ~~Begin Step 2: Build first atom component (Button recommended as it exercises the most tokens)~~ ✓ Done -- Consider adding Google Fonts import for Montserrat and Noto Serif SC to index.html or Storybook preview - -### Session 2026-03-25 — Button atom (Step 2) - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Reviewed 3 Figma component sets: Icons (29:54), Button (28:50), Text Button (32:1361) -- Created button component tokens (`tokens/component/button.json`): height, paddingX, paddingY, fontSize, iconSize, iconGap, borderRadius for xs/sm/md/lg sizes -- Rebuilt token pipeline — 25 new button tokens generated across CSS/JS/JSON outputs -- Updated MUI theme (`src/theme/index.ts`) with comprehensive MuiButton overrides: - - 4 sizes: xs (28px), small (32px), medium (40px), large (48px) - - Contained, outlined, text variants for primary and secondary colours - - Hover backgrounds using brand.100 and sage.100 for outlined/text variants - - Focus-visible outline (2px solid interactive.focus, 2px offset) - - Disabled elevation via `disableElevation: true` default prop - - Custom `xs` size via MUI variant system + module augmentation -- Created Button component (`src/components/atoms/Button/Button.tsx`): - - Wraps MUI Button with React.forwardRef - - Custom props: `loading` (spinner + disabled), `underline` (text-decoration for text variant) - - Accepts all MUI ButtonProps (variant, color, size, startIcon, endIcon, fullWidth, etc.) -- Created barrel export (`src/components/atoms/Button/index.ts`) -- Created comprehensive Storybook stories (`Button.stories.tsx`): 16 stories covering Default, Variants (primary/secondary), AllSizes, Icons, Disabled, Loading, TextWithUnderline, FullWidth, LongContent, CompleteMatrix -- Storybook builds successfully with Button stories - -**Decisions made:** -- D009: Merge Text Button into Button atom — text buttons are `variant="text"` with optional `underline` prop, not a separate component -- D010: Button sizes adjusted for touch targets — xs: 28px, sm: 32px, md: 40px, lg: 48px (lg meets 44px minimum) -- D011: Use `@mui/icons-material` over Font Awesome — native MUI integration, no adapter needed, tree-shakeable -- D012: Responsive sizing is a composition concern — Button size is an explicit prop, not responsive by default. Layouts choose the right size per breakpoint. - -**Open questions:** -- primary.main maps to brand.600 (copper #B0610F) for AA compliance, but Figma designs show brand.500 (warm gold #BA834E) as primary button fill. Should we adjust? Current mapping prioritises accessibility. -- Google Fonts import still needed for Montserrat and Noto Serif SC in Storybook -- Icon approach confirmed as @mui/icons-material — should we create any custom SvgIcon components for FA-specific icons? - -**Next steps:** -- ~~User to review Button in Storybook and provide feedback on colours/sizing~~ ✓ Feedback received -- Build Typography atom -- Add Google Fonts to Storybook preview -- ~~Log D009-D012 in decisions-log.md~~ ✓ Done - -### Session 2026-03-25b — Button refinements from user review - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Fetched Figma Secondary/Brand and Secondary/Grey button details — discovered they are **soft-filled** (tonal) buttons, not outlined -- Added custom `variant="soft"` to MUI Button — tonal/muted fill treatment - - Primary soft: brand.200 bg (#EBDAC8), brand.700 text (#8B4E0D), brand.300 hover - - Secondary soft: neutral.200 bg (#E8E8E8), neutral.700 text (#404040), neutral.300 hover -- Changed MUI secondary palette from sage to neutral grey (neutral.600 main, neutral.700 dark, neutral.300 light) -- Updated all secondary button overrides (outlined, text) from sage to neutral -- Moved loading spinner from left to right side of button text -- Updated stories: added FigmaMapping story, soft variant stories, LoadingToSuccess pattern story -- Logged D013-D015 in decisions log - -**Decisions made:** -- D013: Added `soft` variant for tonal buttons — maps to Figma Secondary/Brand and Secondary/Grey -- D014: Secondary palette changed from sage to neutral grey -- D015: Loading spinner positioned on right - -**Open questions:** -- primary.main maps to brand.600 (copper #B0610F) for AA compliance, but Figma designs show brand.500 (warm gold #BA834E) as primary button fill. Should we adjust? -- Google Fonts import still needed for Montserrat and Noto Serif SC in Storybook -- Icon approach confirmed as @mui/icons-material — should we create any custom SvgIcon components for FA-specific icons? -- Sage palette no longer used for buttons — consider if it should be re-introduced as a custom colour later - -**Next steps:** -- ~~User to re-review Button in Storybook~~ ✓ Approved as good baseline -- ~~Build Typography atom~~ ✓ Done -- ~~Add Google Fonts to Storybook preview~~ ✓ Done - -### Session 2026-03-25c — Typography atom + housekeeping - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Added Google Fonts loading: Montserrat (400/500/600/700) + Noto Serif SC (600/700) in `.storybook/preview-head.html` and `index.html` -- Created Typography component (`src/components/atoms/Typography/Typography.tsx`): - - Thin wrapper around MUI Typography with React.forwardRef - - Custom prop: `maxLines` for CSS line-clamp truncation - - All MUI Typography props passed through (variant, color, align, component, gutterBottom, etc.) -- Created barrel export (`src/components/atoms/Typography/index.ts`) -- Created comprehensive Storybook stories (9 stories): Default, HeadingHierarchy, BodyVariants, UIText, Colours, SemanticHTML, MaxLines, RealisticContent, FontFamilies -- Added "Future enhancements" tracking table to component-registry.md — deferred items (IconButton, destructive colours, link-as-button) tracked with triggers for when to address them -- Logged D016 (primary colour confirmed as copper brand.600) in decisions-log.md -- Storybook builds successfully - -**Decisions made:** -- D016: Primary button colour confirmed as copper (brand.600) — user approved -- Typography atom is a thin wrapper + maxLines — no over-engineering - -**Open questions:** -- Icon approach confirmed as @mui/icons-material — should we create any custom SvgIcon components for FA-specific icons? -- Sage palette no longer used for buttons — consider if it should be re-introduced as a custom colour later - -**Next steps:** -- User to review Typography in Storybook -- Build next atom (Input or Card recommended — Input for forms, Card for service listings) -- Consider building FormField molecule next if Input is done (label + input + helper text) - -### Session 2026-03-25d — Typography expansion (21 variants) - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Reviewed user's FA 2.0 Figma type scale (node 23:30) — 21 variants across 6 categories, 3 responsive breakpoints -- Expanded primitive typography tokens: added fontSize.2xs (11px), fontSize.display.* sub-group (hero 80px through sm 32px), mobile overrides for all display and heading sizes -- Rewrote semantic typography tokens: 21 variants with specific line-heights and letter-spacing per variant -- Rewrote MUI theme typography section: refactored to wildcard import (`import * as t`), added all 21 variants with module augmentations, responsive scaling via @media queries -- Updated Google Fonts: added Noto Serif SC weight 400 (Regular) for display text -- Updated Typography component JSDoc with full variant guide -- Rewrote Typography stories: 10 stories including CompleteScale (all 21 variants matching Figma layout) -- Key font changes: headings now Montserrat Bold (not serif), display now Regular 400 (not Bold), body now Medium 500 (not Regular) - -**Decisions made:** -- D017: Headings use Montserrat Bold, not Noto Serif SC (supersedes D005) -- D018: Display weight is Regular 400, not Bold -- D019: Body weight is Medium 500 (user preference, 450 not available) -- D020: 21 typography variants across 6 categories - -**Next steps:** -- ~~User to review expanded type scale in Storybook~~ ✓ -- Fine-tune heading sizes if they don't match Figma exactly (h2-h6 were estimated) -- ~~Build next atom (Input or Card)~~ ✓ Input done - -### Session 2026-03-25e — Input atom - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Reviewed FA 2.0 Figma Input Field design (node 39:713) — 9 states × 4 toggle properties = ~90 variants -- Analysed Figma design and provided feedback: identified 7 improvements (leading icons, size variation, required indicator, select vs input naming, multiline, character count, error icon treatment) -- Created Input component tokens (`tokens/component/input.json`): height (sm/md), paddingX, paddingY (sm/md), fontSize, borderRadius, gap, iconSize — 9 tokens total -- Rebuilt token pipeline — 9 new input tokens generated across CSS/JS/JSON outputs -- Updated MUI theme (`src/theme/index.ts`) with comprehensive MuiOutlinedInput overrides: - - Border colours per state: neutral.300 default, neutral.400 hover, brand.500 focus, error/success for validation - - Focus ring: double box-shadow (2px white gap + 4px brand.500) matching Figma's elevation-special/focus-ring effect - - Error + focus ring: error-coloured ring - - Disabled background: neutral.100 - - Two sizes via minHeight: medium (48px), small (40px) - - Icon sizing: 20px via InputAdornment - - Notch legend hidden for external label pattern - - Multiline padding normalisation -- Created Input component (`src/components/atoms/Input/Input.tsx`): - - Composes FormControl + InputLabel + OutlinedInput + FormHelperText - - External label pattern (InputLabel with position:static, no floating) - - Custom props: `label`, `helperText`, `success`, `startIcon`, `endIcon`, `fullWidth` - - Label stays neutral on error/focus/success (per Figma design) - - Required asterisk on label (via MUI InputLabel) - - Success state: green border + green helper text (not a native MUI state) - - Error helper text has `role="alert"` for screen readers - - `aria-describedby` connection between input and helper text - - Supports multiline via `multiline` + `rows`/`minRows`/`maxRows` -- Created barrel export (`src/components/atoms/Input/index.ts`) -- Created comprehensive Storybook stories (11 stories): Default, FigmaMapping, AllStates, Required, Sizes, SizeAlignment, WithIcons, PasswordToggle, Multiline, ValidationFlow, ArrangementForm, CompleteMatrix -- Logged D021-D025 in decisions log -- Updated component registry (Input → review) -- Storybook builds successfully - -**Decisions made:** -- D021: External label pattern, not MUI floating label -- D022: Two sizes — medium 48px (matches Button large), small 40px (matches Button medium) -- D023: Focus ring uses brand.500 warm gold (Figma spec), not brand.600 -- D024: Label stays neutral on error/success (calmer for FA audience) -- D025: Added startIcon/endIcon convenience props and success validation state - -**Open questions:** -- Should error+focus ring be error-coloured or brand-coloured? Currently error-coloured (reinforces the validation state during keyboard navigation) -- FormField molecule may now be unnecessary — Input already includes label + helper text. Consider repurposing FormField as a layout/validation wrapper instead. -- Should we add a character count feature? (Useful for textarea fields like special instructions) - -**Next steps:** -- ~~User to review Input in Storybook~~ ✓ -- ~~Build next atom (Card, Badge, or Chip recommended)~~ ✓ Card done -- Consider whether FormField molecule is still needed given Input's built-in label/helperText - -### Session 2026-03-25f — Card atom - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Created card component tokens (`tokens/component/card.json`): borderRadius, padding (default 24px / compact 16px), shadow (default md / hover lg), border, background — 7 tokens total -- Rebuilt token pipeline — 7 new card tokens generated across CSS/JS/JSON outputs -- Updated MUI theme (`src/theme/index.ts`) with MuiCard overrides: - - Root: card token border radius, background, resting shadow (shadow.md), smooth transition - - Outlined variant: no shadow, card border colour -- Created Card component (`src/components/atoms/Card/Card.tsx`): - - Two visual variants: elevated (shadow, default) and outlined (border) - - `interactive` prop: hover shadow lift (shadow.lg), pointer cursor, focus-visible outline - - `padding` prop: "default" (24px), "compact" (16px), "none" (raw children for full-bleed) - - Uses CardContent internally for padded variants; raw children when none - - Thin wrapper pattern consistent with Button and Typography -- Created barrel export (`src/components/atoms/Card/index.ts`) -- Created 8 Storybook stories: Default, Variants, Interactive, PaddingPresets, PriceCardPreview, ServiceOptionPreview, WithImage, RichContent -- Preflight passed all 5 checks -- Committed and pushed to Gitea - -**Decisions made:** -- Card uses MUI spacing units (p: 4/6) for padding presets rather than CSS variables — consistent with MUI-first approach -- Elevation set to 0 on MuiCard; box-shadow applied directly from card tokens for precise control -- Interactive hover uses CSS variable (`var(--fa-card-shadow-hover)`) for shadow.lg -- No new design decisions needed — Card follows existing token/design conventions from design-system.md - -**Open questions:** -- Should interactive cards have a subtle border-colour change on hover in addition to shadow lift? -- Should we add a "selected" state for ServiceOption-style cards (e.g., brand border + brand.50 background)? - -**Next steps:** -- ~~User to review Card in Storybook~~ ✓ Feedback received — add selected + hover bg - -### Session 2026-03-25g — Card selected state + hover background - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Reviewed FA 1.0 Figma designs for card usage patterns: - - ListItemPurchaseOption (2349:39505): selectable cards with 4 states × 2 viewports - - ListItemAddItem (2350:40658): toggle/switch pattern — deferred to future Toggle component -- Added `selected` prop: brand border (2px, warm gold #BA834E) + warm background (brand.50 #FEF9F5) -- Added hover background fill: interactive cards now fill with neutral.50 on hover (matching Figma's inactive→hover pattern) -- Hover on selected cards preserves warm background instead of switching to neutral -- Elevated interactive cards still get shadow lift on hover; outlined ones only get bg fill -- Added 3 new card tokens: border.selected, background.hover, background.selected -- Added 4 new stories: Selected, OptionSelect (single-select with radio semantics), MultiSelect (checkbox toggle), OnDifferentBackgrounds (white vs grey surface) -- Replaced ServiceOptionPreview story with the more complete OptionSelect and MultiSelect patterns -- Preflight passed all 5 checks -- Committed and pushed to Gitea - -**Decisions made:** -- Selected state uses 2px brand border (not 1.5px from Figma 1.0) — 2px aligns with our focus ring width and sits on the 2px sub-grid -- Selected background uses brand.50 (warm tint) not neutral.50 (grey) — warm tint reinforces the brand connection and distinguishes selected from hovered -- Hover bg fill uses neutral.50 (not brand.50) for unselected cards — keeps hover subtle and neutral -- Toggle/switch pattern from Figma (ListItemAddItem) is a separate component concern, not Card - -**Next steps:** -- ~~User to review Card selected/hover states in Storybook~~ ✓ Approved -- ~~Build Badge or Chip atom next~~ ✓ Badge done - -### Session 2026-03-25h — Badge atom - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Searched FA 2.0 and Parsons 1.0 Figma files for badge/chip/tag components — none found, designed from conventions -- Created badge component tokens (`tokens/component/badge.json`): height, paddingX, fontSize, iconSize, iconGap, borderRadius for sm/md — 10 tokens total -- Built Badge component (`src/components/atoms/Badge/Badge.tsx`): - - Pill-shaped, display-only status indicator (not interactive) - - 6 colour intents: default, brand, success, warning, error, info - - 2 variants: soft (tonal bg + coloured text, default) and filled (solid bg + white text) - - 2 sizes: small (22px) and medium (26px) - - Optional leading `icon` prop for contextual icons - - All soft colours use CSS variables from token system — no hardcoded hex - - Warning text uses amber.700 for WCAG AA compliance -- Created 10 Storybook stories including realistic compositions (InPriceCard, ServiceStatus) -- Preflight passed all 5 checks -- Committed and pushed to Gitea - -**Decisions made:** -- Badge defaults to soft variant — calmer, more appropriate for FA's sensitive context. Filled variant for high-priority emphasis only. -- Badge uses Box (span) not MUI Chip — keeps it simple, display-only, no interactive baggage -- Pill shape (borderRadius.full) distinguishes badges from rectangular UI elements -- Brand soft colours match Button soft (brand.200 bg, brand.700 text) for visual consistency - -**Next steps:** -- ~~User to review Badge in Storybook~~ ✓ Approved (large size added) - -### Session 2026-03-25i — Impeccable integration - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Researched pbakaus/impeccable (Apache 2.0) — 21 skills for frontend design quality -- Assessed fit for FA project — identified overlaps/conflicts, recommended selective integration -- Downloaded 14 reference files to `docs/reference/impeccable/`: - - 7 design guides (typography, colour, spatial, motion, interaction, responsive, ux-writing) - - 3 critique references (cognitive-load, heuristics-scoring, personas) - - 4 skill references (audit, critique, polish, frontend-design anti-patterns) -- Created `/audit` skill — technical quality scoring (0-20) across 5 dimensions, adapted for FA -- Created `/critique` skill — UX review using Nielsen's 10 heuristics (0-40), with FA-specific persona checks -- Updated `/review-component` — added interactive states checklist (8 checks) and design anti-patterns checklist (8 checks) -- Updated `/preflight` — added visual QA spot-check section (advisory, non-blocking) -- All changes are skill/docs only — zero code changes to existing components - -**Decisions made:** -- Selective integration over wholesale install — only /audit, /critique, reference material, and anti-patterns merged -- Removed impeccable's dependency chain (/frontend-design → /teach-impeccable) — FA already has CLAUDE.md + docs/memory/ for design context -- Replaced impeccable's command recommendations with FA's available skills -- Critique adapted with FA-specific personas (bereaved family member, arrangement planner) -- OKLCH recommendation noted in reference but not adopted — FA uses hex-based DTCG tokens - -**Component status at end of session:** -- **Done (5):** Button, Typography, Input, Card, Badge -- **Planned (5 atoms):** IconButton, Icon, Avatar, Divider, Chip, Link -- **Planned (5 molecules):** FormField, PriceCard, ServiceOption, SearchBar, StepIndicator -- **Planned (5 organisms):** ServiceSelector, PricingTable, ArrangementForm, Navigation, Footer - -**Next steps:** -- Review Badge in Storybook (large size was added per user request) -- ~~Build Chip atom (interactive tags — clickable, deletable, with icon support)~~ ✓ Done -- Consider running /audit or /critique on completed atoms to establish baseline scores -- Begin PriceCard molecule once Chip is done (depends on Card + Badge + Typography + Button) - -### Session 2026-03-25j — Chip atom - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Created chip component tokens (`tokens/component/chip.json`): height, paddingX, fontSize, iconSize, deleteIconSize, iconGap, borderRadius for sm/md — 12 tokens total -- Rebuilt token pipeline — 12 new chip tokens generated across CSS/JS/JSON outputs -- Updated MUI theme (`src/theme/index.ts`) with MuiChip overrides: - - Pill-shaped borderRadius from token - - Two sizes: small (28px), medium (32px) - - Filled variant: neutral.200 bg for default, brand.200 bg for primary (soft/tonal, matching Badge and Button soft) - - Outlined variant: neutral.300 border for default, brand.400 border for primary - - Hover states per variant × colour - - Delete icon hover colour change - - Focus-visible outline (brand.500, 2px offset) -- Created Chip component (`src/components/atoms/Chip/Chip.tsx`): - - Wraps MUI Chip with React.forwardRef - - Custom `selected` prop: promotes colour to primary, outlined selected gets brand border + warm bg - - Two variants: filled (tonal, default), outlined (border) - - Two colours: default (neutral), primary (brand) - - Interactive modes: clickable (via onClick), deletable (via onDelete), both, or static - - All MUI ChipProps passed through -- Created barrel export (`src/components/atoms/Chip/index.ts`) -- Created 10 Storybook stories: Default, Variants, Sizes, WithIcons, Clickable, Deletable, Selected, FilterChips (interactive toggle demo), RemovableTags (interactive dismiss demo), InServiceOption (realistic card composition), CompleteMatrix -- Preflight passed all 5 checks - -**Decisions made:** -- Chip uses MUI Chip wrapper (unlike Badge which uses raw Box) — MUI Chip provides built-in keyboard navigation, delete icon, and click handling that would be complex to reimplement -- Chip defaults to `filled` variant with soft/tonal colours (matching Badge soft and Button soft patterns) — NOT MUI's default opaque fill -- Only `default` and `primary` colours initially — secondary/error/etc. added when needed (YAGNI) -- Selected state auto-promotes to primary colour unless colour is explicitly set — mirrors Card's selected brand treatment -- No new design decision IDs needed — Chip follows established conventions - -**Component status at end of session:** -- **Done (5):** Button, Typography, Input, Card, Badge -- **Review (1):** Chip -- **Planned (4 atoms):** IconButton, Icon, Avatar, Divider, Link -- **Planned (5 molecules):** FormField, PriceCard, ServiceOption, SearchBar, StepIndicator -- **Planned (5 organisms):** ServiceSelector, PricingTable, ArrangementForm, Navigation, Footer - -**Next steps:** -- ~~User to review Chip in Storybook~~ ✓ Approved -- ~~Consider running /audit or /critique on completed atoms to establish baseline scores~~ ✓ Done -- Begin PriceCard molecule (depends on Card + Badge + Typography + Button + Chip) - -### Session 2026-03-25k — Audit, P1 fixes, Switch + Radio atoms - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Ran /audit on all 5 completed atoms (Button, Typography, Input, Card, Badge) - - Average score: 18/20 (Excellent) - - 2 P1 issues identified and fixed, 7 P2s documented, 5 P3s noted -- Fixed P1: Button loading state now announces to screen readers (aria-busy + visually-hidden text) -- Fixed P1: Card interactive now has tabIndex={0} and role="button" for keyboard operability -- Fixed P2: Card Record → Theme type for type safety -- Reviewed Parsons 1.0 Figma "Toggles" board (node 2322:42538) — identified 4 new atoms: Switch, Radio, ColourToggle, Slider -- Added all 4 to component registry (ColourToggle and Slider deferred) -- Created switch component tokens (`tokens/component/switch.json`): track width/height/borderRadius, thumb size — 4 tokens -- Created radio component tokens (`tokens/component/radio.json`): size, dotSize — 2 tokens -- Updated MUI theme with MuiSwitch overrides: bordered pill track, brand.500 active fill, focus-visible ring -- Updated MUI theme with MuiRadio overrides: neutral.400 unchecked, brand.500 checked, hover states -- Created Switch component — thin MUI wrapper with forwardRef -- Created Radio component — thin MUI wrapper with forwardRef -- Created Switch stories (4): Default, States, ServiceAddOns (interactive add-on toggle demo), WithLabels -- Created Radio stories (5): Default, States, RadioGroup, CardSelection (interactive card + radio demo), PaymentMethod -- Preflight passed all 5 checks - -**Decisions made:** -- Switch implements Figma "Style One" (bordered pill) only — other styles deferred as variants if needed -- Switch/Radio are ultra-thin wrappers — all styling via MUI theme overrides, no component-level sx -- ColourToggle and Slider deferred until their consuming organisms are built - -**Component status at end of session:** -- **Done (5):** Button, Typography, Input, Card, Badge -- **Review (3):** Chip, Switch, Radio -- **Planned (6 atoms):** IconButton, Icon, Avatar, Divider, ColourToggle, Slider, Link -- **Planned (5 molecules):** FormField, PriceCard, ServiceOption, SearchBar, StepIndicator -- **Planned (5 organisms):** ServiceSelector, PricingTable, ArrangementForm, Navigation, Footer - -**Next steps:** -- ~~User to review Switch and Radio in Storybook~~ ✓ Approved -- ~~Begin PriceCard molecule~~ ✓ Replaced with ProviderCard (see below) -- Address P2 audit issues in a future cleanup pass - -### Session 2026-03-25l — ProviderCard molecule (first molecule) - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Reviewed 3 Figma designs: Provider Cards (5503:44422), Service Venue (2997:83018), Map Pin Card (5369:140263) -- Captured business context: verified vs unverified providers, Parsons partner strategy, map + list layout -- Replaced generic "PriceCard" in registry with 3 specific molecules: ProviderCard, VenueCard, MapCard -- Saved business context to auto-memory (project_listing_cards.md) -- Created plan via /plan mode — component API, card structure, token plan, story plan -- Created providerCard component tokens (`tokens/component/providerCard.json`): image.height, logo.size, footer.background/paddingX/paddingY, content.padding/gap — 7 tokens -- Built ProviderCard molecule (`src/components/molecules/ProviderCard/ProviderCard.tsx`): - - Composes Card (interactive, padding="none") + Badge + Typography - - Verified variant: hero image (CSS bg-image cover), logo overlay (48px circle, absolute positioned, overlaps content), "Trusted Partner" badge (filled brand), capability badge - - Unverified variant: text-only, same content area + footer - - Footer bar: warm brand.100 bg, "Packages from $X" + ChevronRight - - Accessibility: aria-label on reviews, aria-hidden on decorative icons, alt text on logo - - All values from token CSS variables, no hardcoded hex -- Created 9 Storybook stories: Default, VerifiedProvider, UnverifiedProvider, ListLayout (mixed), CapabilityVariants, EdgeCases, Responsive, OnDifferentBackgrounds, InteractiveDemo -- Preflight passed all 5 checks -- Logged D026-D030 in decisions log - -**Decisions made:** -- D026: Molecules compose atoms via sx — no MUI theme overrides -- D027: Image as URL string (CSS bg-image), logo as URL string () -- D028: Logo 48px (not 75px Figma) for card width proportion -- D029: Footer built in via startingPrice prop, not a slot -- D030: verified is explicit boolean, not derived from imageUrl - -**Component status at end of session:** -- **Done (7):** Button, Typography, Input, Card, Badge, Chip, Switch, Radio -- **Review (1 molecule):** ProviderCard -- **Planned (7 atoms):** IconButton, Icon, Avatar, Divider, ColourToggle, Slider, Link -- **Planned (5 molecules):** VenueCard, MapCard, ServiceOption, SearchBar, StepIndicator, FormField -- **Planned (5 organisms):** ServiceSelector, PricingTable, ArrangementForm, Navigation, Footer - -**Next steps:** -- ~~User to review ProviderCard in Storybook~~ ✓ Feedback received, iterated in session 25m - -### Session 2026-03-25m — ProviderCard v2 refinements from user feedback - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Iterated on ProviderCard based on 5 feedback items from user review -- **Logo**: circle → 64px rounded rectangle (8px radius, `borderRadius.md`). Positioned fully inside image area (absolute, bottom-left) with white border + shadow. Eliminates dead space — name sits directly below image. -- **Footer removed**: "View packages >" bar was redundant (whole card is clickable, price already in content). Removed 3 footer tokens (`footer.background`, `.paddingX`, `.paddingY`). -- **Price typography**: Split into "Packages from" (body2, 14px, secondary) + price (h6, 16px, weight 500, primary). Lighter, streamlined ecommerce feel vs old blocky labelLg/700. -- **Verified badge**: Bumped from `size="small"` to `size="medium"` for visibility. -- **Capability badge**: Bumped to `size="medium"`. Added trailing `InfoOutlinedIcon` and new `capabilityDescription` prop — wraps badge in MUI Tooltip on hover/focus for plain-language definitions of industry jargon. -- **Unverified card differentiation**: 3px `borderTop` (neutral.200) as visual anchor. ListLayout story now on neutral.50 background. -- **Caption weight fix (system-wide)**: Caption and CaptionSm bumped from fontWeight 400 (Regular) → 500 (Medium) in semantic typography tokens. Aligns with D019 — user found Regular too light for Montserrat. -- **Meta row**: Location/reviews dropped from body2 (14px) → caption (12px) with 14px icons for clearer tertiary hierarchy. -- Updated all stories with `capabilityDescription` tooltips for 3 capability types -- Preflight passed all 5 checks - -**Decisions made:** -- Logo positioned fully inside image (no overlap into content) — tried flex-row overlap approach first but it "dug into" the photo and pushed the name sideways -- Footer removal: card's interactive hover + price in content are sufficient affordance -- Caption weight 500: extends D019 (body weight = Medium) to all Montserrat text variants. Only display (Noto Serif SC) stays at 400 per D018. -- Info icon for capability badges: trailing position (after label), `cursor: help` when tooltip active - -**Token changes:** -- `providerCard.logo.size`: 56px → 64px -- `providerCard.logo.borderRadius`: new, → `{borderRadius.md}` (8px) -- `providerCard.footer.*`: 3 tokens removed (footer eliminated) -- `typography.caption.fontWeight`: `{fontWeight.regular}` → `{fontWeight.medium}` -- `typography.captionSm.fontWeight`: `{fontWeight.regular}` → `{fontWeight.medium}` - -**Component status at end of session:** -- **Done (8):** Button, Typography, Input, Card, Badge, Chip, Switch, Radio -- **Review (1 molecule):** ProviderCard (v2, user approved direction) -- **Planned (6 atoms):** IconButton, Icon, Avatar, Divider, ColourToggle, Slider, Link -- **Planned (5 molecules):** VenueCard, MapCard, ServiceOption, SearchBar, StepIndicator, FormField -- **Planned (5 organisms):** ServiceSelector, PricingTable, ArrangementForm, Navigation, Footer - -**Next steps:** -- ~~Build VenueCard molecule~~ ✓ Done -- ~~Address P2 audit issues~~ ✓ Done -- ~~Audit ProviderCard v2~~ ✓ Done (17/20, P2s fixed) - -### Session 2026-03-25n — VenueCard molecule, P2 fixes, ProviderCard audit - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Reviewed Figma venue card design (node 2997:83018) — photo + name + location + capacity + price -- Created venueCard component tokens (`tokens/component/venueCard.json`): image.height (180px), content.padding (spacing.3), content.gap (spacing.1) — 3 tokens -- Built VenueCard molecule (`src/components/molecules/VenueCard/VenueCard.tsx`): - - Composes Card (interactive, padding="none") + Typography - - Hero image with `role="img"` + aria-label for screen readers - - Meta row: location (pin icon) + capacity with "guests" suffix for clarity - - Price with "From" qualifier (split typography like ProviderCard) - - No verification tiers, no logo, no badges — simpler than ProviderCard -- Created 6 Storybook stories: Default, ListLayout, EdgeCases, Responsive, OnDifferentBackgrounds, InteractiveDemo -- Ran /critique on VenueCard: 33/40 (Good). Applied P2 fixes before commit: - - Capacity: bare number → "X guests" for visible context - - Price: bare "$900" → "From $900" for transparency - - Image: added `role="img"` + `aria-label` for screen readers -- Fixed 6 P2 audit issues across atom components: - - Input: `Record` → `Theme` type on boxShadow accessor - - Button: documented aria-label requirement for icon-only usage - - Badge: documented aria-label for icon-only badges - - Switch: strengthened a11y docs with FormControlLabel example - - Radio: strengthened a11y docs with RadioGroup + FormControlLabel example - - Chip: documented aria-label for icon-only deletable chips -- Ran /audit on ProviderCard v2: 17/20 (Good). Fixed 3 P2s: - - Hero image: added `role="img"` + `aria-label` for screen readers - - Logo shadow: hardcoded rgba → `var(--fa-shadow-sm)` - - Logo border: hardcoded white → `var(--fa-color-white)` - -**Decisions made:** -- VenueCard follows same token structure as ProviderCard (image.height, content.padding, content.gap) for visual consistency in list views -- Capacity shows "X guests" suffix — bare number was confusing in critique -- Price shows "From $X" — matches ProviderCard's "Packages from" pattern for transparency - -**Component status at end of session:** -- **Done (8):** Button, Typography, Input, Card, Badge, Chip, Switch, Radio -- **Review (2 molecules):** ProviderCard (v2, audit 17/20), VenueCard (critique 33/40) -- **Planned (6 atoms):** IconButton, Icon, Avatar, Divider, ColourToggle, Slider, Link -- **Planned (4 molecules):** MapCard, ServiceOption, SearchBar, StepIndicator, FormField -- **Planned (5 organisms):** ServiceSelector, PricingTable, ArrangementForm, Navigation, Footer - -**Next steps:** -- ~~User to review VenueCard in Storybook~~ ✓ Approved -- ~~Build next atoms (IconButton, Divider, Link)~~ ✓ Done - -### Session 2026-03-25n (continued) — IconButton, Divider, Link atoms - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Built IconButton atom — wraps MUI IconButton with FA theme overrides: - - 3 sizes reusing Button height tokens (sm 32px, md 40px, lg 48px) - - Rounded rect shape (borderRadius.md), brand hover colours, focus ring - - 4 colour options: default, primary, secondary, error - - 5 stories including CommonUseCases (card toolbar, dialog close, nav toggle) -- Built Divider atom — wraps MUI Divider with FA border token: - - Horizontal/vertical orientation, fullWidth/inset/middle variants - - Text children support (MUI built-in) - - 6 stories including InContent and NavigationList patterns -- Built Link atom — wraps MUI Link with FA brand tokens: - - Copper colour (brand.600, 4.8:1 contrast) by default - - Underline on hover, focus-visible ring, fontWeight 500 - - 7 stories including Inline (body text), Navigation, FooterLinks -- Added MuiIconButton, MuiDivider, MuiLink overrides to theme - -**Decisions made:** -- IconButton uses rounded rect (borderRadius.md) not circle — consistent with Button. Circle can be achieved with sx if needed. -- Link defaults to underline="hover" — always-underlined links feel heavy in FA's clean aesthetic, but the underline is important for discoverability so it appears on hover. -- No new component tokens — IconButton reuses Button tokens, Divider uses palette.divider, Link uses palette colours. - -**Component status at end of session:** -- **Done (8):** Button, Typography, Input, Card, Badge, Chip, Switch, Radio -- **Review (3 atoms):** IconButton, Divider, Link -- **Review (2 molecules):** ProviderCard (v2, audit 17/20), VenueCard (critique 33/40) -- **Planned (3 atoms):** Icon, Avatar, ColourToggle, Slider -- **Planned (4 molecules):** MapCard, ServiceOption, SearchBar, StepIndicator, FormField -- **Planned (5 organisms):** ServiceSelector, PricingTable, ArrangementForm, Navigation, Footer - -**Next steps:** -- ~~User to review IconButton, Divider, Link in Storybook~~ ✓ Approved -- ~~Build ServiceOption molecule~~ ✓ Done - -### Session 2026-03-25n (continued) — ServiceOption molecule - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Reviewed 2 Figma components: ListItemPurchaseOption (2349:39505) and ListItemAddItem (2350:40658) - - ListItemPurchaseOption: click-to-select card with 4 states (inactive, hover, active, active hover) - - ListItemAddItem: toggle with Switch — deferred as a future AddOnOption molecule -- Built ServiceOption molecule (`src/components/molecules/ServiceOption/ServiceOption.tsx`): - - Composes Card (interactive, selected) + Typography - - Heading row: name (h6) + optional price (h6, brand colour, right-aligned, nowrap) - - Optional description below (body2, text.secondary) - - Selected state via Card's built-in brand border + warm bg - - Disabled state with opacity token (--fa-opacity-disabled) + pointer-events: none - - role="radio" + aria-checked for proper single-select group semantics - - Uses card.padding.compact (16px) for content padding -- Created 7 stories: Default, Selected, ServiceTypeSelection (interactive radiogroup), - CoffinSelection (interactive 4-option), WithoutPrice, Disabled, EdgeCases -- No new tokens — ServiceOption reuses Card tokens (padding.compact, border.selected, etc.) - -**Decisions made:** -- ServiceOption uses role="radio" + aria-checked — correct for single-select groups within a radiogroup. Parent wraps in role="radiogroup". -- Price right-aligned in heading row — natural scanning pattern (name on left, cost on right, like a menu) -- No component-specific tokens needed — Card's existing tokens handle all visual states -- AddOnOption (ListItemAddItem with Switch) deferred — will compose Card + Switch when arrangement form organisms are built - -**Component status at end of session:** -- **Done (8):** Button, Typography, Input, Card, Badge, Chip, Switch, Radio -- **Review (3 atoms):** IconButton, Divider, Link -- **Review (3 molecules):** ProviderCard, VenueCard, ServiceOption -- **Planned (3 atoms):** Icon, Avatar, ColourToggle, Slider -- **Planned (3 molecules):** MapCard, SearchBar, StepIndicator, FormField -- **Planned (5 organisms):** ServiceSelector, PricingTable, ArrangementForm, Navigation, Footer - -**Next steps:** -- ~~Build SearchBar molecule~~ ✓ Done -- ~~Build AddOnOption molecule~~ ✓ Done -- ~~Build StepIndicator molecule~~ ✓ Done -- ~~Build Navigation organism~~ ✓ Done - -### Session 2026-03-25o — SearchBar, AddOnOption, StepIndicator molecules + Navigation organism - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Built SearchBar molecule (`src/components/molecules/SearchBar/`): - - Composes Input (with search icon) + optional Button for provider/venue search - - Enter-to-submit, progressive clear button (appears when text present), inline loading spinner - - Guards empty submissions (`value.trim()`), refocuses input after clear - - `role="search"` landmark, two sizes aligned with Input/Button - - Critique: 35/40 (Good). P2 fixes applied before commit. - - 8 stories: Default, WithButton, SmallSize, WithPreloadedValue, Loading, Disabled, ProviderSearch, VenueSearch -- Built AddOnOption molecule (`src/components/molecules/AddOnOption/`): - - Composes Card (interactive, selected) + Typography + Switch - - Maps to Figma ListItemAddItem (2350:40658) — toggle for optional extras - - Heading + optional price + description + Switch right-aligned - - Click anywhere on card toggles the switch (stopPropagation on switch itself) - - `aria-labelledby` connects switch to heading text - - 7 stories: Default, Checked, ServiceAddOns (interactive list with running total), WithoutPrice, WithoutDescription, Disabled, EdgeCases -- Built StepIndicator molecule (`src/components/molecules/StepIndicator/`): - - Maps to Figma Progress Bar - Steps (2375:47468) — horizontal segmented bar - - Brand gold for completed/current steps, grey (divider) for upcoming - - Responsive bar height (10px desktop, 6px mobile), responsive labels - - Current step label bolded, `role="navigation"` + `aria-current="step"` - - 7 stories: Default, AllStates, TwoSteps, ManySteps, Interactive (nav demo), Completed, NarrowContainer -- Built Navigation organism (`src/components/organisms/Navigation/`): - - First organism in the design system - - Maps to Figma Main Nav (14:108) + Mobile Header (2391:41508) - - Desktop: sticky AppBar, logo left, nav Link items right, optional CTA Button - - Mobile: hamburger IconButton + Drawer with nav list, CTA, Divider, help footer with phone - - Warm surface background (brand.50), border bottom - - Composes AppBar, Link, IconButton, Button, Divider, Drawer, Typography - - 6 stories: Default, WithCTA, WithPageContent (sticky scroll demo), Minimal, ExtendedNavigation, MobilePriceTracker -- All 4 components: TypeScript compiles, Storybook builds, committed and pushed - -**Decisions made:** -- SearchBar guards empty submissions and disables button when empty — prevents wasted requests -- AddOnOption uses click-anywhere-to-toggle pattern (stopPropagation on Switch to avoid double-toggle) -- StepIndicator uses `palette.divider` for incomplete steps — grey/sage from theme, not hardcoded -- Navigation uses `var(--fa-color-surface-warm)` background — matches Figma's warm grey #F4F3EF -- Navigation nav link colour uses brand.900 (#51301B) — matches Figma "Brown Two" token -- No new component tokens needed for any of the 4 components — all reuse existing tokens - -**Component status at end of session:** -- **Done (8):** Button, Typography, Input, Card, Badge, Chip, Switch, Radio -- **Review (3 atoms):** IconButton, Divider, Link -- **Review (6 molecules):** ProviderCard, VenueCard, ServiceOption, SearchBar, AddOnOption, StepIndicator -- **Review (1 organism):** Navigation -- **Planned (3 atoms):** Icon, Avatar, ColourToggle, Slider -- **Planned (2 molecules):** MapCard, FormField -- **Planned (4 organisms):** ServiceSelector, PricingTable, ArrangementForm, Footer - -**Post-review fixes (same session):** -- SearchBar: button height aligned via explicit CSS var height, icon-to-text gap tightened (adornment mr: 0.5), focus ring gap increased (gap 6px → 10px) -- AddOnOption: price moved to own row below heading, heading row centre-aligned so short headings (no description) align with switch, heading-to-price margin removed -- AddOnOption + ServiceOption: added optional `maxDescriptionLines` prop with CSS line-clamp + "View more"/"View less" toggle (caption size, text.secondary, weight 400). Omit prop for no limit. - -**Next steps:** -- ~~Build Footer organism~~ (next) -- ~~Build ServiceSelector organism~~ (next) -- ~~Consider FormField molecule~~ (next) -- ~~Remaining P3s~~ (next) - -### Session 2026-03-25p — Review completion + Navigation fixes - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Completed review of all components — user approved all atoms + molecules with no changes -- Applied 4 Navigation fixes from user feedback: - 1. Added "Provider Portal" to default nav items - 2. Integrated real FA logo SVGs from `brandassets/brandlogo/` (full wordmark desktop, short icon mobile) - 3. Changed nav background from warm (`surface.warm` / brand.50) to grey (`surface.subtle` / neutral.50) - 4. Removed `mobileTrailing` prop and `MobilePriceTracker` story — speculative feature not in design -- Added `staticDirs: ['../brandassets']` to Storybook config for logo serving -- Updated component-registry.md: promoted 11 atoms + 6 molecules + 1 organism from "review" to "done" -- TypeScript compiles, Storybook builds - -**Decisions made:** -- Nav background is grey (neutral.50) not warm (brand.50) — per user's Figma reference -- "Log in" label kept as-is — universally understood, user confirmed -- mobileTrailing prop removed entirely — was over-reading Figma's mobile header - -**Component status at end of session:** -- **Done (11 atoms):** Button, Typography, Input, Card, Badge, Chip, Switch, Radio, IconButton, Divider, Link -- **Done (6 molecules):** ProviderCard, VenueCard, ServiceOption, SearchBar, AddOnOption, StepIndicator -- **Done (1 organism):** Navigation -- **Planned (3 atoms):** Icon, Avatar, ColourToggle, Slider -- **Planned (2 molecules):** MapCard, FormField -- **Planned (4 organisms):** ServiceSelector, PricingTable, ArrangementForm, Footer - -**Next steps:** -- ~~Build Footer organism~~ ✓ Done -- ~~Build ServiceSelector organism~~ ✓ Done -- Consider FormField molecule if Input's built-in label/helperText proves insufficient -- Remaining P3s: InfoOutlinedIcon sizing in ProviderCard, image loading placeholder, accent bar 3px→4px - -### Session 2026-03-25p (continued) — Footer + ServiceSelector organisms - -**Agent(s):** Claude Opus (via conversation) - -**Work completed:** -- Built Footer organism (`src/components/organisms/Footer/`): - - Dark espresso (brand.950) surface with inverse white text - - Logo + tagline + contact info (phone/email with tel:/mailto: links) in left column - - Configurable link group columns with heading + `